DIVX テックブログ

catch-img

アジャイル開発時代のアプリケーションをセキュアにする方法


目次[非表示]

  1. 1.脆弱性はバグの一種です
  2. 2.脆弱性のあるアプリケーション
  3. 3.Sneakerの挙動確認
  4. 4.Snykにログインする
  5. 5.Snyk CLIを使用可能にする
  6. 6.Snyk CLIで脆弱性をスキャンする
    1. 6.1.アプリケーションコードの脆弱性
    2. 6.2.OSSライブラリの脆弱性
    3. 6.3.Dockerイメージの脆弱性
  7. 7.CIを導入してみる
    1. 7.1.作業用ブランチを作成する
    2. 7.2.Visual Studio CodeにSnykのプラグインを入れる
      1. 7.2.1.Sneakerディレクトリをプロジェクトとして開く
      2. 7.2.2.拡張機能としてSnykを有効化する
    3. 7.3.OSSとアプリケーションコードの脆弱性を確認する
    4. 7.4.Github Actionsでワークフローを実行する
      1. 7.4.1.Secretをリポジトリへ登録する
      2. 7.4.2.リポジトリへプッシュしてワークフローを実行する
    5. 7.5.アプリケーションコードの脆弱性を修正する
    6. 7.6.OSSの脆弱性を修正する
      1. 7.6.1.OSSの継続監視
    7. 7.7.Dockerイメージの脆弱性は?
  8. 8.コンテナレジストリの脆弱性を継続的に検知する
  9. 9.まとめ

はじめに

こんにちは。DIVXでCTOを務めている田島です。

先日「エンジニア向けセキュリティ勉強会 〜アジャイル開発時代のアプリケーションをセキュアにする方法〜」と題した勉強会をSnykのToshiさんと行わせていただきました。結果として70名以上の方に参加頂けたようで嬉しかったです。皆さんありがとうございました。

今回の記事はその勉強会で行った内容をまとめたものです。勉強会に参加いただいた方もそうでない方も、よろしければご覧いただけると嬉しいです。

脆弱性はバグの一種です

バグはソフトウェアのリリースにブレーキをかけます。バグはテストを行う事で発見し修正する事ができますが、近年のアジャイルな開発現場ではそれらはCI/CDというリリースサイクルの中に組み込まれて自動化されている事が多いです。

バグの中でも情報漏えいを起こしたり、データを意図せず書き換えてしまうようなものを脆弱性と言います。脆弱性もバグの一種なのでCI/CDの中に組み込むのが理想ですが、今回はそんな理想を叶える為の方法をシェアいたします。

脆弱性のあるアプリケーション

今回はSneakerというコンテナで動くアプリケーション開発のCIに、脆弱性スキャンのフローを組み込んでみます。

Sneakerはサンプルのアプリケーションですが、Githubへのプッシュをイベントとして自動テストおよびコンテナイメージのビルド、コンテナレジストリへのプッシュまで行うので、皆さんが開発しているアプリケーションに組み込むとしたらどうなるのか?のイメージはつくと思っております。

Sneakerの挙動確認

SneakerはDockerコンテナが動く環境であれば簡単に動作します。ローカルPC内のお好きなディレクトリ内で、下記のリポジトリをクローンして下さい。CI実行のブランチがciブランチなので、ciブランチをデフォルトのブランチとして指定しています。

git clone -b ci https://github.com/yuya-tajima/sneaker.git


リポジトリをクローンした後は、READMEに書いてある手順でアプリが起動します。下記にコマンドだけ改めて記載します。

cp .env.sample .env
docker-compose run app composer install
docker-compose build
docker-compose up


http://localhost:8080/にアクセスすると、下記のような簡素のUIのページが表示されます。


Sneakerの挙動確認


結論から先に申し上げると、Sneakerには少なくとも下記の脆弱性があります。これらは後述のSnyk CLIを使えば簡単に確認する事ができます。

  • アプリケーションコード
    • クロスサイトスクリプティング(XSS)
    • SQLインジェクション
    • ファイルインクルード
    • OSコマンドインジェクション
  • OSSライブラリ
    • guzzlehttp/guzzle
      • CVE-2022-29248
      • CVE-2022-31043
      • CVE-2016-5385
  • Dockerコンテナ(一部抜粋)
    • apache2
    • curl
    • dpkg
    • expat
    • glibc
    • openssl

最終的にこれらの脆弱性をCIツールと連携する事で検出してみます。

なお、上記の中でアプリケーションコードの脆弱性だけは、ユーザーのコーディング依存で発生しているものですので下記の通り再現が容易です。興味のある方は試してみて下さい。

クロスサイトスクリプティング(XSS)

クロスサイトスクリプティング(XSS)

クロスサイトスクリプティング(XSS)


SQLインジェクション

SQLインジェクション

SQLインジェクション


OSコマンドインジェクション

OSコマンドインジェクション

OSコマンドインジェクション


ファイルインクルード

ファイルインクルード

ファイルインクルード

Snykにログインする

Snykを利用するにはSnykにログインする必要があります。ログインはGithubアカウントやGoogleアカウントがあれば簡単にログインできます。途中Githubとの連携を求められるので、Githubでログインしておいた方がスムーズかもしれません。


Snykにログインする


ログインすると、下記のようにダッシュボードへと遷移します。


Snykにログインする

Snyk CLIを使用可能にする

ダッシュボードにて、「Using Snyk in the command line」というパネルがあるので、snyk authで認証まで実施します。


Snyk CLIを使用可能にする


認証が成功したら、下記コマンドでAPIキーを取得しておきましょう。APIキーはSnykをDocker Hub等の外部サービスと連携させる時に必要となるので、そのタイミングで改めて取得していただいても構いません。なお、取得した値は誰にも公開されないように取り扱う必要があります。

snyk config get api

Snyk CLIで脆弱性をスキャンする

まずはじめに最も手軽に脆弱性をスキャンする方法として、Snyk CLIを使ってみます。

アプリケーションコードの脆弱性

リポジトリのディレクトリ直下で下記コマンドを実行します。

snyk code test

下記の通り4つの脆弱性が発見されました。


アプリケーションコードの脆弱性

OSSライブラリの脆弱性

リポジトリのディレクトリ直下で下記コマンドを実行します。

snyk test html --severity-threshold=high

各プログラミング言語に備わっているパッケージ管理システムのマニフェストファイルを対象にスキャンするので、それがあるディレクトリを指定しています。今回の場合はhtmlディレクトリ内に、composer.jsonおよびcomposer.lockが配置されているので、htmlを引数として指定しています。また、 --severity-threshold=highも指定して、重大度が高以上のものだけに絞っています。


OSSライブラリの脆弱性

Dockerイメージの脆弱性

Dockerイメージは使用しているマシン内でグローバルに管理されていますが、一応リポジトリのディレクトリ直下で下記コマンドを実行します。

snyk container test sneaker:latest --severity-threshold=high


ビルド済みのDockerイメージを対象にスキャンするので、今回ビルドしたsneaker:latestを指定しています。OSSと同様に --severity-threshold=highも指定して、重大度が高以上のものだけに絞っています。それでも、かなり膨大な数の脆弱性が発見できるはずです。


Dockerイメージの脆弱性

CIを導入してみる

Snyk CLIによって脆弱性が発見できるので、それを修正していけば脆弱性を解消する事ができますが、今回のテーマは「アジャイル開発時代のアプリケーションをセキュアにする方法」です。よって、CIツールの中でそれらを解消していこうと思います。

今回はCI/CDツールとしてGithub Actionsを使用します。CDまでは行いませんが、CIのイメージができれば、それをCDへ拡張できる事は自明でしょう。

作業用ブランチを作成する

もしカレントブランチがciではなかった場合はスウィッチします。

git switch ci

そこからpracticeブランチを作成しましょう。以後の修正はpracticeブランチ上で行っていきます。

git switch -c practice

Visual Studio CodeにSnykのプラグインを入れる

私個人は普段Vimを使用しているので、あまりVisual Studio Codeを使う機会はないのですが、SnykとVisual Studio Codeの組み合わせがとても便利なので今回はこちらを活用します。

Sneakerディレクトリをプロジェクトとして開く

ブランチが、先程変更したpracticeである事も確認しておきましょう。


Sneakerディレクトリをプロジェクトとして開く

拡張機能としてSnykを有効化する

拡張機能でsnykと検索するといくつか出てくるので、Previewではない方をインストールしましょう。


拡張機能としてSnykを有効化する


左メニューにSnykのアイコンが現れるのでクリックします。その後、赤枠をクリックしてブラウザ経由での認証を済ませます。


拡張機能としてSnykを有効化する


認証が成功すると下記のような画面になるので、「OPEN SOURCE SECURITY」の「Settings」をクリックします。


拡張機能としてSnykを有効化する


「Additional Parameters」の入力エリアにhtmlと入力します。これは、Snyk CLIで「OSSライブラリの脆弱性」のスキャンを実行した時に引数として渡したhtmlと同じ意味です。

このように一度Snyk CLIでシンプルな操作を体験しておくと、他の複雑なツールを扱う時も設定項目の意味が理解しやすいです。よって、Snyk CLIで操作をイメージしてから他のツールを使う事を個人的にはオススメしてます。


拡張機能としてSnykを有効化する


htmlを入力後、スキャンを実行するとOSSの脆弱性を検知できるようになります。


拡張機能としてSnykを有効化する

OSSとアプリケーションコードの脆弱性を確認する

Snykのメニューを開くと、OSSとアプリケーションコードの脆弱性がサイドバーに表示されています。これはさきほどSnyk CLIでスキャンした結果と一致しているので、Snyk CLIのアウトプットと見比べてみて下さい。


OSSとアプリケーションコードの脆弱性を確認する


ここで、「CODE SECURITY」のどれか一つをクリックすると、該当のソースコードとその詳細情報が右のパネルに表示されるので、Snyk CLIで確認した時よりも見やすいです。


OSSとアプリケーションコードの脆弱性を確認する

Github Actionsでワークフローを実行する

今の脆弱性がある状態で、Github Actionsのワークフローを実行してみます。現状のリポジトリのワークフローファイルの設定では、git pushによってワークフローが実行されるようになっています。皆さんがこのワークフロー実行を試す場合は、originをgithub.com:yuya-tajima/sneaker.gitから皆さんのアカウントのリポジトリに変更をお願いいたします。

Secretをリポジトリへ登録する

SNYK_TOKENとしてsnyk config get apiで取得しておいたAPIキーを設定します。DOCKERHUB_TOKENDOCKERHUB_USERNAMEはDocker Hubにビルドしたコンテナイメージをプッシュする時に必要な情報です。


Secretをリポジトリへ登録する


リポジトリへプッシュしてワークフローを実行する

下記のコマンドを実行し、ローカルで新規作成したブランチをリモートへプッシュします。

git push origin practice

Githubの「Actions」タブをクリックすると、ワークフローが実行されている事が確認できます。


リポジトリへプッシュしてワークフローを実行する


詳細を確認すると、Vulnerability Scanningというジョブが失敗しているのが確認できます。


リポジトリへプッシュしてワークフローを実行する


更に詳細を確認をすると、失敗している箇所で4つのアプリケーションコードの脆弱性が検知されている事が確認できます。


リポジトリへプッシュしてワークフローを実行する


これはVisual Studio Codeの下記赤枠と一致しています。よって、ここを修正すればワークフローの失敗箇所が成功しそうです。


リポジトリへプッシュしてワークフローを実行する

アプリケーションコードの脆弱性を修正する

検出された4つの脆弱性を修正します。自力で修正頂いても良いですが、fixedディレクトリ内のindex.phpをコピーして頂ければ修正が完了します。

更新すると「CODE SECURITY」の脆弱性が消えました。


アプリケーションコードの脆弱性を修正する


修正内容をコミット&プッシュして再度ワークフローを実行してみると、アプリケーションコードの脆弱性は解消されていましたが、次のステップのOSS脆弱性チェックに引っかかっていました。


アプリケーションコードの脆弱性を修正する

OSSの脆弱性を修正する

Github Actionsのワークフローで検出されたOSSの脆弱性も、アプリケーションコードの脆弱性と同様にVisual Studio Code内の検出結果と一致しています。


OSSの脆弱性を修正する


composer.json内のバージョン表記を修正して、依存性の情報をアップデートします。こちらはfixedディレクトリ内のcomposer.jsonをコピーして、composer update --no-installを実行すれば修正が完了します。


OSSの脆弱性を修正する


修正内容をコミット&プッシュして再度ワークフローを実行してみると、ワークフローが成功していました。


OSSの脆弱性を修正する

OSSの継続監視

ちなみに、途中「Run Snyk to monitor the OSS vulnerabilities」内にてOSSライブラリを継続的にモニタリングするステップを組み込んであります。

OSSの継続監視


URIをクリックすると、composer.lockがプロジェクトとしてSnykの監視対象に含まれた事がわかります。現在は全ての脆弱性を解消している状態なので何も検知も通知もされませんが、今後脆弱性が発覚したタイミングでユーザーにその旨が通知されます。

OSSの継続監視


DockerイメージもOSSと同様にSnykの継続監視対象に含める事ができますが、それは最後にご紹介します。

Dockerイメージの脆弱性は?

実はVulnerability Scanningの中を細かくみると、Run Snyk to check Docker image for vulnerabilitiesというステップで、重大度が高以上の脆弱性が検出されている事がわかります。こちらはDockerイメージの中に残る脆弱性なのですが、今回はあえてパスさせています。


Dockerイメージの脆弱性は?


どんな脆弱性があるかは、「Security」タブの「Code Scanning」メニューで確認できるようにワークフローファイルで設定してあります。


Dockerイメージの脆弱性は?


今回Dockerイメージの脆弱性に関してあえてパスしているのは、使用しているDockerイメージから常に脆弱性を解消しつくすのは現実的に難しいケースがあるからです。もちろん、既知の脆弱性をゼロにする事が理想ではありますが、アプリケーションコードやOSSライブラリの脆弱性に比べて、Dockerイメージの脆弱性は影響範囲が限定的になるケースが多いです。その為、そこにかけるコストと危険性のバランスをみながら落とし所を探っていく事が多いかもしれません。

実際今回使用しているベースイメージであるphp:7.4.1-apacheを、2023年2月7日時点の最新版であるphp:8.2.2-apacheに変更しても依然としてCriticalな脆弱性が1つ残ってしまっていました。この状態をどうしても避けなければならない場合、別のベースイメージを使用するか、スクラッチで作成し直すかの意思決定が必要になるでしょう。この判断を促してくれるという意味でも、Snykを使う価値は大いにあると考えています。


Dockerイメージの脆弱性は?

コンテナレジストリの脆弱性を継続的に検知する

今回Github Actions経由して、Docker Hubにイメージがプッシュされました。仮にこのDockerイメージの脆弱性が解消されているとしても、継続的にイメージの安全性を担保する仕組みが必要です。なぜなら、脆弱性のスキャンはCIの中でしか実行されないからです。


コンテナレジストリの脆弱性を継続的に検知する


Snykの管理コンソールの「Integrations」では、現在Docker HubがConfiguredになっています。これはDocker Hub上にあるDockerイメージが、脆弱性における監視対象として含められる状態である事を意味します。他にもAWSやGCPをはじめ様々な外部レジストリとの連携が可能です。


コンテナレジストリの脆弱性を継続的に検知する

まとめ

簡単なものではありましたが、SnykをCIの中に組み込んで継続的に脆弱性をスキャンする仕組みを整えてみました。皆さんのサービスやプロダクトをスピーディかつセキュアに届ける為の一助となれば幸いです。

  採用情報 | 株式会社divx(ディブエックス) 可能性を広げる転職を。DIVXの採用情報ページです。 株式会社divx(ディブエックス)



お気軽にご相談ください


ご不明な点はお気軽に
お問い合わせください

サービス資料や
お役立ち資料はこちら

DIVXブログ

テックブログ タグ一覧

人気記事ランキング

GoTopイメージ