進化が止まらない、さらに賢くなったコードレビュー自動化サービス Amazon CodeGuru の中身とは ?
Author : 金杉 有見子
builders.flash 読者の皆様、あけましておめでとうございます。日々いかがお過ごしでしょうか ? 私は毎日乾燥に悩まされながら AWS re:Invent 2020 で発表されたアップデートのキャッチアップに励んでいます。
さて、7 月に機械学習でコードレビューを自動化 ! Amazon CodeGuru 3 分間クッキングの記事をお届けしてから早くも半年が経とうとしています。あれから CodeGuru には様々なアップデートが加わっていて、より使いやすいよう進化しています。本日は、その中でも 3 つのアップデート、CodeGuru Reviewer リポジトリ解析、 CodeGuru Reviewer セキュリティ解析、CodeGuru Reviewer Python対応 (Preview) に注目してご紹介していきます。
ご注意
本記事で紹介する AWS サービスを起動する際には、料金がかかります。builders.flash メールメンバー特典の、クラウドレシピ向けクレジットコードプレゼントの入手をお勧めします。
この記事のデモを無料でお試しいただけます »
毎月提供されるデベロッパー向けアップデート情報とともに、クレジットコードを受け取ることができます。
Amazon CodeGuru Reviewer とは ?
CodeGuruを初めて聞いた方もいらっしゃると思うので、簡単におさらいしたいと思います。
Amazon CodeGuru は、自動化されたコードレビューとアプリケーションパフォーマンスの推奨事項を提供する機械学習をベースとしたサービスです。プロダクトとしては、CodeGuru Reviewer と Codeguru Profiler の 2 つに分かれており、本日のテーマはコードレビューのサービス CodeGuru Reviewer の方になります。では、ここからアップデートについて見ていきましょう !
CodeGuru Reviewer リポジトリ解析
これまでの CodeGuru Reviewer では、Pull Request ベースのコードレビューに対応していました。セットアップは非常に簡単です。まずは対象のリポジトリを関連付けて、あとは Pull Request を都度作成するだけで、CodeGuru Reviewer が推奨事項をコメントとして残してくれます。デベロッパーは CodeGuru Reviewer がコメントした推奨事項を確認し、必要に応じて修正を行います。
この Pull Request ベースの方式では、コードレビューのプロセスに CodeGuru Reviewer がシームレスに組み込まれるので、通常の運用であれば十分事足ります。しかし、既存のコードを使って CodeGuru Reviewer をクイックに評価してみたいユースケースでは一工夫が必要でした。
また、CodeGuru Reviewer では日々新しい検知領域の実装が追加されています。定期的にリポジトリ全体をスキャンし、コードクオリティを評価したいケースもあるかと思います。これらのニーズに対応するのが、CodeGuru Reviewer のリポジトリ解析です。リポジトリ解析により、関連付けたリポジトリの特定ブランチに対し、コードレビューを行うことができるようになりました。
CodeGuru Reviewer リポジトリ解析は2ステップで始めることができます。まず、AWS コンソールにログインし、Amazon CodeGuru サービスのページに移動します。Getting started のプルダウンから CodeGuru Reviewer を選択します。
クリックすると拡大します
Source Provider はご自身が使用しているプロバイダーを選択します。GitHub の場合、Connect to GitHub をクリックして CodeGuru Reviewer のアクセスを許可します。最後に対象のリポジトリをプルダウンから選んだら、Associate をクリックします。これで準備は完了です。
リポジトリの関連付けができたら、早速リポジトリ解析をしてみましょう。CodeGuru コンソールの左メニューから、Code reviews を選択します。Code reviews の画面では過去実施したコードレビューの一覧を確認することができます。今回はリポジトリ解析を行うので、画面中央にある Repository analysis を選択します。最後に、画面右にある Create repository analysis をクリックします。
次の画面では、実際に解析を行いたいリポジトリとブランチを選択します。コンソール画面も非常にシンプルで、先ほど関連づけたリポジトリをプルダウンから選択し、対象のブランチ名を入力するだけです。コードレビュー名も任意で指定することができます。最後に、Create repository analysis をクリックすると、コードレビューが自動的に開始されます。
結果は先ほどお見せした Code reviews の画面から、もしくは ListCodeReviews API から確認することができます (結果は 90 日しか保存されないのでご注意ください)。
試しに先ほど作成した Code review 名をクリックしてみると、レビューのスキャン対象となったコード行数、リポジトリ、ブランチ名などのメタ情報が確認できます。生成された推奨事項の数や、それぞれの詳細についても確認することが可能でして、さらにここから直接推奨事項に対してフィードバックを提供することもできます。
CodeGuru Reviewer セキュリティ解析
CodeGuru Reviewer では以下のカテゴリの推奨事項を提供してくれます。
- AWS ベストプラクティス
- 並列処理
- リソースリーク
- 機密データの漏洩
- 一般的なコーディングベストプラクティス
- リファクタリング
- インプットバリデーション
- コード品質
AWS re:Invent 2020 では、上記 8 つのカテゴリに加え、セキュリティ解析を追加しました。セキュリティ解析機能は、現状 Java のソースコードに対応しており、機械学習のパワーを駆使してコード内のセキュリティ脆弱性を識別してくれます。他の推奨事項と同じように、問題が検出されると、課題点と修正方法をセットに推奨事項が生成されます。現状、対応しているセキュリティ分野には以下のようなものがあります。
AWS API セキュリティベストプラクティス
AWS API を使用する際のセキュリティベストプラクティスに従っているかを確認 (例: 認証情報を API Call にハードコードしていないか)
Java 暗号化ライブラリベストプラクティス
一般的な Java 暗号ライブラリを使用する際のセキュリティベストプラクティスに従っているかを確認 (例: 古い暗号アルゴリズムを使用していないか)
セキュアウェブアプリケーション
非構造化データの取り扱いがセキュアかどうかを検出 (例: ユーザーインプットを正しく処理し、CSS、SQL インジェクションなどに対策できているかどうか)
AWS セキュリティベストプラクティス
AWS のセキュリティ組織が提供するセキュリティベストプラクティスに従っているかを確認
2 つの例を見ていきたいと思います。
AWS API セキュリティベストプラクティス
AWS API セキュリティベストプラクティスでは、AWS SDK や API を使用しているコードがベストプラクティスに従っているかを検知してくれます。一例として、認証情報を直接コード内で記述しているケースが挙げられます。例えば以下のコード例を見てみましょう。
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.BasicAWSCredentials;
static String myKeyId ="AKIAX742FUDUQXXXXXXX";
static String mySecretKey = "MySecretKey";
public static void main(String[] args) {
AWSCredentials creds = getCreds(myKeyId, mySecretKey);
}
static AWSCredentials getCreds(String id, String key) {
return new BasicAWSCredentials(id, key);
}
このコードでは、myKeyId と mySecretKey がアプリケーションコード内にハードコードされています。これらの情報は攻撃者に晒されて悪用されてしまう可能性もありますし、誤って公開されてしまうリスクがあります。これに対し、CodeGuru Reviewer は環境変数もしくは AWS profile を使用する方法を提案しています。また、漏洩のリスクを考慮して、キーをローテートし、CloudWatch を通して悪用されていないかを確認するよう推奨しています。
Java 暗号化ライブラリベストプラクティス
続いて、Java 暗号化ライブラリベストプラクティスについてみてみましょう。
機密データを扱う際、私たちは暗号化アルゴリズムを選択してデータを暗号化・複合します。そこで、解読が難しい強固なアルゴリズムを選択することが重要です。例えば以下のコードサンプルがあるとします。
import javax.crypto.Cipher;
static final String CIPHER = "DES";
public void run() {
cipher = Cipher.getInstance(CIPHER);
}
このコードでは、DES アルゴリズムを使用した Cipher オブジェクトが作成されています。これに対し、CodeGuru Reviewer はより強固な暗号化方式を使用するよう推奨しています。Learn more をクリックすると、この推奨事項を生成した背景や根拠に関するドキュメントを参照することができます。
セキュリティ解析を始めるには
先ほど、CodeGuru Reviewer では Pull Request ベースの解析とリポジトリ解析の両方を提供していると紹介しました。セキュリティ解析を含むコードレビューを行うにはリポジトリ解析を選択します。また、直接 CodeCommit や GitHub のリポジトリを指定することはできず、CodeGuru Reviewer が作成する S3 バケットをリポジトリとして指定する必要があります。ソースコード (.java ファイル) とビルドアーティファクト (.jar ファイルや .class ファイル) を zip で固め、S3 バケットにアップロードし、セキュリティ解析と通常のコードレビュー両方の推奨事項を得ることができます。
では、セキュリティ解析を試してみたいと思います。まず、先ほどと同じように、Code Reviews の画面から Repository analysis を選択し、Create repository analysis をクリックします。
今回はセキュリティの推奨事項も得たいので、Code and security recommendations (Java) をクリックします。Repository nameを入力し、Associate をクリックすると、名前が codeguru-reviewer- から始まる S3 バケットが自動的に作成され、選択された状態になります。この時入力した Repository name も CodeGuru のリポジトリとして登録され、後ほど AWS コンソールの CodeGuru > Reviewer > Repositories 配下で確認することができます。
数秒後に S3 バケットの作成とリポジトリ登録が終わるので、画面上でソースコードとビルドアーティファクトのアップロードができるようになります。ちなみにコンソール画面からアップロードする場合、zip ファイルは最大 100 MB までという制限があるので、100 MB 以上である場合は直接 S3 バケットにアップロードしておく必要があります。最後に、Create repository analysis をクリックし、解析を始めます。
解析の結果は、Code reviews から確認することができます。手元で試してみたものを開いてみると、先ほどと同じようにレビューのメタ情報を確認することができます。また、Security Recommendations という欄では、実際にセキュリティ解析による推奨事項を何件検出できたかが記載されています。セキュリティの推奨事項は通常のレビュー結果と一緒に Recommendations セクションに出力され、フィルタを通じて絞って表示することもできます。
CodeGuru Reviewer Python 対応 (Preview)
CodeGuru Reviewer が対応している言語はこれまで Java のみでした。多くのお客様から要望をいただいた結果、AWS re:Invent 2020 で待望の Python 対応が Preview 発表されました。Preview 段階なので、一般公開に向けて仕様が強化されたり、変更される可能性がありますが、執筆時点で Python Reviewer は以下のカテゴリの検出に対応しています。
- AWS SDK API ベストプラクティス
- データストラクチャとコントロールフロー (Exception Handling など)
- リソースリーク
- シェルインジェクションを防ぐためのセキュアコーディング
これまで Java コードに対するコードレビュー同様、Pull Request ベースあるいはリポジトリ解析でレビューすることができます。なお、セキュリティレビューにはまだ対応していませんのでご留意ください。
1 つ例を見てみましょう。例えば以下のようなコードがあったとします。
def sync_ddb_table(source_ddb, destination_ddb):
response = source_ddb.scan(TableName=“table1”)
for item in response['Items']:
...
destination_ddb.put_item(TableName=“table2”, Item=item)
…
このコードでは、DynamoDB テーブルに対し Scan をしています。DynamoDB の Scan API のレスポンスには 1 MB の上限があります。よって、上記のような実装だとテーブルの一部のデータしか取得できていない可能性があります。これに対し、CodeGuru Reviewer は以下のように、ページング処理を実装するような推奨事項を生成してくれます。ぜひ、お手元の Python コードでも試してみてください!
クリックすると拡大します
まとめ
本日は CodeGuru Reviewer の新機能、リポジトリ解析、セキュリティ解析と Python 対応について紹介しました。
これらの新機能により、Pull Request ベースのコードレビューに加え、リポジトリのブランチを対象としたコードレビュー、及びセキュリティ解析を含めたコード全体のレビューができるようになりました。簡単に使い分けを以下の図に示しますので、ユースケースに応じて参考にしてみてください。
また、料金体系も若干異なるので、料金ページをご確認ください。
CodeGuru Reviewer では 90 日間の無償期間を提供しています。ぜひ一度お試しください ! Happy Code Reviewing !
筆者プロフィール
金杉 有見子 (かなすぎ ゆみこ)
アマゾン ウェブ サービス ジャパン合同会社
ソリューションアーキテクト
インターネットメディアのお客様のクラウド活用をサポートするアーキテクト。旅とゲームが好き。
AWS を無料でお試しいただけます