はじめに
まず「依存ライブラリのセキュリティチェックツール」とは?ということですが、このようなツールの呼び方が定まっていないため本記事ではこのような呼び方にしています。
(強いて言えば、Software Composition Analysツールと呼ばれているツール群)
これらのツールの特徴として、動作しているアプリケーションが依存しているライブラリやパッケージに既知の脆弱性が存在していないかをバージョン情報などをもとに検査します。脆弱性があるバージョンのライブラリがあるとアラートを出す挙動をします。
従来から利用されている Burp Suite や OWASP ZAP などのWebセキュリティ診断ツールは実際にアプリケーションを動作させて、その挙動から脆弱性を検出します。それに対して「依存ライブラリのセキュリティチェックツール」はアプリケーションを動作させずに検査します。ツールの動作が全く異なるので、検査内容も大きく違います。
どちらかといったらWordPressの検査に利用される WPScan に検査内容は近いです。どちらも利用しているプラグイン(ライブラリ)のバージョン情報で検出するのがメインとなっているからです。
それでも検査を実施できる範囲は異なります。
WPScan はネット越しに公開されているサイト全てに検査することが可能です。対して「依存ライブラリのセキュリティチェックツール」はアプリケーションが依存しているライブラリが記述されているファイル(Gemfile.lock や composer.lock)が検査対象になりますので、それらのファイルを閲覧できる権限者のみが検査を実施できます。それらのファイルに依存関係はほぼ全て記述されているので、依存関係を全て取得するのが難しいネット越しでの検査に比べてより厳密な検査ができます。
そして近頃、Webアプリケーションなどのソフトウェアに依存しているライブラリに既知の脆弱性が潜んでいないかを検査するために、セキュリティチェックツールを提供・利用するサービスが増えてきている気がしています。
▼ Snyk もセキュリティチェックツールを開発/提供している企業であり資金調達が上手くいっている模様。 jp.techcrunch.com
まずは、手軽に導入することができるOSSのセキュリティチェックツールを使用してみて、どのような検査結果を得ることができるのかなどを確認してみます。
ついでに検出された脆弱性の情報はどこから取得しているのかなども確認してきます。
言語別 ツール一覧
昨今では様々な言語に対応したセキュリティツールが存在しています。
本記事では「PHP」「Ruby」「Python」「Java」「JavaScript」の5つの言語に対応したツールを各言語一つづつ紹介していきます。
今回紹介するツールはどれもOSSなのでセキュリティ関連のツールに興味のある人はコードを読んでみても良いかと。
PHP
まず初めにPHPのセキュリティチェックツールを使ってみます。
有名なものに security-checker がありますので、これを紹介します。
sensiolabs / security-checker
検査時にcomposer.lock
ファイルを指定することから、composer.lock
に記述されたPHPの依存ライブラリのバージョン情報から脆弱性を検出していることが分かります。
使い方
検査用のスクリプトを取得したら、1つのコマンドでセキュリティの検査が可能です。
# security-checker のスクリプトを取得 $ wget https://get.sensiolabs.org/security-checker.phar # 検査の開始 $ php security-checker.phar security:check composer.lock Symfony Security Check Report ============================= 2 packages have known vulnerabilities. symfony/http-foundation (v3.4.32) --------------------------------- * [CVE-2019-18888][]: Prevent argument injection in a MimeTypeGuesser symfony/http-kernel (v3.4.32) ----------------------------- * [CVE-2019-18887][]: Use constant time comparison in UriSigner [CVE-2019-18888]: https://symfony.com/cve-2019-18888 [CVE-2019-18887]: https://symfony.com/cve-2019-18887 Note that this checker can only detect vulnerabilities that are referenced in the SensioLabs security advisories database. Execute this command regularly to check the newly discovered vulnerabilities.
検査の結果、「CVE-2019-18888」と「CVE-2019-18887」の脆弱性が「symfony/http-foundation」と「symfony/http-kernel」から検出されました。
脆弱性データベース
プルリクベースで新しい脆弱性の追加などの更新が行われており、今後も引き続き更新は行われていきそうです。
他の言語のセキュリティチェックツールも同様に、ほとんどの脆弱性データベースは様々に人によって頻繁に更新されています。
Web版
Web版も用意されており、インストールなども必要なく利用することができます。
検査対象となるcomposer.lock
ファイルをアップロードすることで検査が可能です。
▼ 検査結果
Ruby
rubysec / bundler-audit
使い方
試しに適当にRailsプロジェクトを作成し、そのプロジェクトに対して検査を実施していきます。
# bundler-audit をインストール $ gem install bundler-audit # 検査対象のディレクトリに移動 $ cd ~/RubymineProjects/railsTestApp/ # 検査を実施 $ bundle-audit bundle-audit Name: actionview Version: 5.1.6 Advisory: CVE-2019-5419 Criticality: Unknown URL: https://groups.google.com/forum/#!topic/rubyonrails-security/GN7w9fFAQeI Title: Denial of Service Vulnerability in Action View Solution: upgrade to >= 6.0.0.beta3, >= 5.2.2.1, ~> 5.2.2, >= 5.1.6.2, ~> 5.1.6, >= 5.0.7.2, ~> 5.0.7, >= 4.2.11.1, ~> 4.2.11 Name: actionview Version: 5.1.6 Advisory: CVE-2019-5418 Criticality: Unknown URL: https://groups.google.com/forum/#!topic/rubyonrails-security/pFRKI96Sm8Q Title: File Content Disclosure in Action View Solution: upgrade to >= 4.2.11.1, ~> 4.2.11, >= 5.0.7.2, ~> 5.0.7, >= 5.1.6.2, ~> 5.1.6, >= 5.2.2.1, ~> 5.2.2, >= 6.0.0.beta3
検出した脆弱性は17個あり列挙するとこんな感じです。
CVE-2019-5419 CVE-2019-5418 CVE-2018-16476 CVE-2019-5421 CVE-2019-16109 CVE-2019-15587 CVE-2018-16468 CVE-2019-5477 CVE-2019-11068 CVE-2018-14404 CVE-2019-13117 CVE-2015-9284 CVE-2019-16770 CVE-2018-16470 CVE-2019-16782 CVE-2019-16892 CVE-2018-1000544
昨年発見された rack(CVE-2019-16782)の脆弱性も検出されており、検出に用いられる脆弱性データベースも更新されていることが分かります。
次は脆弱性データベースを見てみることにします。
脆弱性データベース - rubysec / ruby-advisory-db
検出のために用いられている脆弱性データベースは 「rubysec / ruby-advisory-db」リポジトリにあります。
github.com
Python
pyupio / safety
脆弱性データベース
使い方
# 脆弱性データベースを取得 $ pip install safety-db # safetyのインストール $ pip install safety # 依存ライブラリの確認。古いDjangoがあります。 $ cat requirements.txt Django==1.7.5 # 検査の開始 $ safety check -r requirements.txt ╒══════════════════════════════════════════════════════════════════════════════╕ │ │ │ /$$$$$$ /$$ │ │ /$$__ $$ | $$ │ │ /$$$$$$$ /$$$$$$ | $$ \__//$$$$$$ /$$$$$$ /$$ /$$ │ │ /$$_____/ |____ $$| $$$$ /$$__ $$|_ $$_/ | $$ | $$ │ │ | $$$$$$ /$$$$$$$| $$_/ | $$$$$$$$ | $$ | $$ | $$ │ │ \____ $$ /$$__ $$| $$ | $$_____/ | $$ /$$| $$ | $$ │ │ /$$$$$$$/| $$$$$$$| $$ | $$$$$$$ | $$$$/| $$$$$$$ │ │ |_______/ \_______/|__/ \_______/ \___/ \____ $$ │ │ /$$ | $$ │ │ | $$$$$$/ │ │ by pyup.io \______/ │ │ │ ╞══════════════════════════════════════════════════════════════════════════════╡ │ REPORT │ │ checked 5 packages, using default DB │ ╞════════════════════════════╤═══════════╤══════════════════════════╤══════════╡ │ package │ installed │ affected │ ID │ ╞════════════════════════════╧═══════════╧══════════════════════════╧══════════╡ │ django │ 1.7.5 │ <1.7.11 │ 25714 │ │ django │ 1.7.5 │ <1.7.6 │ 25715 │ │ django │ 1.7.5 │ <1.8.10 │ 33074 │ │ django │ 1.7.5 │ <1.8.10 │ 33073 │ │ django │ 1.7.5 │ <1.8.15 │ 25718 │ │ django │ 1.7.5 │ >=1.7,<1.7.10 │ 25728 │ │ django │ 1.7.5 │ >=1.7,<1.7.10 │ 25727 │ │ django │ 1.7.5 │ >=1.7,<1.7.7 │ 25731 │ │ django │ 1.7.5 │ >=1.7,<1.7.7 │ 25713 │ │ django │ 1.7.5 │ >=1.7,<1.7.9 │ 25725 │ │ django │ 1.7.5 │ >=1.7,<1.7.9 │ 25726 │ ╘══════════════════════════════════════════════════════════════════════════════╛
いくつかの脆弱性が検出されました。しかし脆弱性の詳細情報は出力されていない状態です。
--full-report
オプションを付与することで、脆弱性の詳細情報を出力することができます。
詳細情報レポートの取得。 --full-report オプション
--full-report
オプションを付与することで、検出した脆弱性の詳細を表示することが可能です。
$ safety check -r requirements.txt --full-report ╒══════════════════════════════════════════════════════════════════════════════╕ │ │ │ /$$$$$$ /$$ │ │ /$$__ $$ | $$ │ │ /$$$$$$$ /$$$$$$ | $$ \__//$$$$$$ /$$$$$$ /$$ /$$ │ │ /$$_____/ |____ $$| $$$$ /$$__ $$|_ $$_/ | $$ | $$ │ │ | $$$$$$ /$$$$$$$| $$_/ | $$$$$$$$ | $$ | $$ | $$ │ │ \____ $$ /$$__ $$| $$ | $$_____/ | $$ /$$| $$ | $$ │ │ /$$$$$$$/| $$$$$$$| $$ | $$$$$$$ | $$$$/| $$$$$$$ │ │ |_______/ \_______/|__/ \_______/ \___/ \____ $$ │ │ /$$ | $$ │ │ | $$$$$$/ │ │ by pyup.io \______/ │ │ │ ╞══════════════════════════════════════════════════════════════════════════════╡ │ REPORT │ │ checked 5 packages, using default DB │ ╞════════════════════════════╤═══════════╤══════════════════════════╤══════════╡ │ package │ installed │ affected │ ID │ ╞════════════════════════════╧═══════════╧══════════════════════════╧══════════╡ │ django │ 1.7.5 │ <1.7.11 │ 25714 │ ╞══════════════════════════════════════════════════════════════════════════════╡ │ The get_format function in utils/formats.py in Django before 1.7.x before │ │ 1.7.11, 1.8.x before 1.8.7, and 1.9.x before 1.9rc2 might allow remote │ │ attackers to obtain sensitive application secrets via a settings key in │ │ place of a date/time format setting, as demonstrated by SECRET_KEY. │ ╞══════════════════════════════════════════════════════════════════════════════╡ │ django │ 1.7.5 │ <1.7.6 │ 25715 │ ╞══════════════════════════════════════════════════════════════════════════════╡ │ Cross-site scripting (XSS) vulnerability in the contents function in │ │ admin/helpers.py in Django before 1.7.6 and 1.8 before 1.8b2 allows remote │ │ attackers to inject arbitrary web script or HTML via a model attribute in │ (以下省略)
Java
jeremylong / DependencyCheck
OWASPツールのDependencyCheckですが、MavenやGradleなどの様々なJavaプロジェクトに対応しています。
今回はGradleのプロジェクトを対象にツールを使用しますので、「dependency-check-gradle
」というライブラリをGradleに追記します。
Gradle用 jeremylong/dependency-check-gradle
使用方法は簡単で「./gradlew dependencyCheckAnalyze
」コマンドを実行するだけです。
検査が開始されますので、しばらくすると脆弱性が存在しているライブラリの一覧が表示されます。
整形されずに出力されるので少々見づらいですが、このツールの良い点としてHTML形式のレポートが自動的に保存されるようになっている。
私の環境だと「./build/reports/dependency-check-report.html
」に保存されていました。
出力内容をブラウザで確認してみます。
ブラウザ上での確認だと非常に見やすく、脆弱性の詳細情報への遷移もラクで便利です。
JavaScript
Npm標準ツール - npm-audit
npmコマンドに標準で付属されているnpm audit
サブコマンドです。
脆弱なパッケージをアップデートする " npm audit fix " コマンド
npm audit fix
コマンドを使用することで、脆弱性見つかっているパッケージのアップデートを行うことができます。
以下がそのコマンドを使用してパッケージのアップデートが行われるまでの流れです。
$ cat package-lock.json | grep '"hot-formula-parser"' -A 1 "hot-formula-parser": { "version": "3.0.0",
npm audit fix
コマンドを実行します。1つの脆弱性が見つかり、修正した旨のメッセージが表示されました。
$ npm audit fix npm WARN vuln_hot-formula-parser_RCE No repository field. npm WARN vuln_hot-formula-parser_RCE No license field. + hot-formula-parser@3.0.2 updated 1 package in 0.316s fixed 1 of 1 vulnerability in 5 scanned packages
依存パッケージを確認してみると、バージョンが上がっていることが確認できます。
$ cat package-lock.json | grep '"hot-formula-parser"' -A 1 "hot-formula-parser": { "version": "3.0.2",
確認のために再度npm audit
コマンドを実行します。
脆弱性は見つからず、修正されたことが確認できます。
$ npm audit === npm audit security report === found 0 vulnerabilities in 5 scanned packages
まとめ
どのツールもリポジトリが依存するライブラリのバージョンを利用して検査しています。
そのため実際にアプリケーションが動作する環境に影響を及ぼすことなくセキュリティの検査を実施することが可能です。
今回紹介したツールは、主に各自の環境にインストールして利用するものでした。しかし、そのような手間をかけるかけることなく「検査対象のリポジトリを登録するだけで脆弱性が存在しているライブラリが存在する場合にアラートを出してくれるサービス」も存在しています。
一番身近なものはGitHubだと思います。リポジトリが依存しているライブラリに脆弱性が見つかったら下画像のようにアラートが表示されます。
これは脆弱性が放置されている良くない例です・・・。ちなみにリポジトリ所有者のみにアラートが見えるようになっています。
Github以外にも Snyk や yamory といったサービスがあります。
どちらも無料プランがあり、導入も簡単であることから両方利用していますがどちらも使いやすくオススメです。趣味で開発している人も使ってみるとよいかと。
更新履歴
- 2019年1月29日 新規作成