最近のPHPプロジェクトでは、外部ライブラリを管理するのにComposerを利用することが多いです。
Composerを利用とバージョンや依存関係の自動解決などを自動に行ってくれるため非常に便利ですが、Composerではパッケージを自由に登録できるため、予期せぬセキュリティ問題を抱えてしまうリスクがあります。
このような心配を少しでも解消したい場合、security-checkerパッケージを利用すると良いです。
https://security.sensiolabs.org/で提供されているsecurity-checkerパッケージを利用することで、既知のセキュリティホールを含んだパッケージを利用していないかを簡単にチェックできます。使用しているライブラリに問題がある場合は、どのライブラリに何の問題があるか、また問題が何のCVE(共通脆弱性識別子)に抵触しているかをレポートしてくれます。
security-checkerパッケージを取得する
security-checkerパッケージは、composerを使ってコマンド1つでダウンロードできます。
$ composer require sensiolabs/security-checker
Using version ^4.1 for sensiolabs/security-checker
./composer.json has been created
Loading composer repositories with package information
...
Generating autoload files
インストールしたsecurity-checkerパッケージを実行してみる
composer requireの実行が完了したら、vendor\binの下にあるスクリプトを実行し、ヘルプが表示されることを確認します。
$ vendor\bin\security-checker.bat
SensioLabs Security Checker 4
Usage:
command [options] [arguments]
Options:
-h, --help Display this help message
-q, --quiet Do not output any message
-V, --version Display this application version
--ansi Force ANSI output
--no-ansi Disable ANSI output
-n, --no-interaction Do not ask any interactive question
-v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
Available commands:
help Displays help for a command
list Lists commands
security
security:check Checks security issues in your project dependencies
ヘルプの最後の行を見ると、"security:check"コマンドがセキュリティ脆弱性チェック用のコマンドであることが分かります。
チェックする対象のプロジェクトを作る
別のディレクトリ(今回はc:\workを使用)に移動し、composer requireでパッケージを取得します。今回はテストのためaws-sdk-phpパッケージを追加してみます。
下記の例では、パッケージ取得時にバージョン番号3.1.0を敢えて指定して実行しています。
$ cd C:\work
$ composer require aws/aws-sdk-php 3.1.0
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 6 installs, 0 updates, 0 removals
- Installing mtdowling/jmespath.php (2.4.0): Downloading (failed)
Downloading (100%)
- Installing psr/http-message (1.0.1): Downloading (100%)
- Installing guzzlehttp/psr7 (1.4.2): Downloading (100%)
- Installing guzzlehttp/promises (v1.3.1): Downloading (100%)
- Installing guzzlehttp/guzzle (6.3.0): Loading from cache
- Installing aws/aws-sdk-php (3.1.0): Downloading (100%)
guzzlehttp/guzzle suggests installing psr/log (Required for using the Log middleware)
Writing lock file
Generating autoload files
※今回はsecurity-checkerのパッケージと開発プロジェクトを分けていますが、もちろん、開発プロジェクトのdevパッケージとしてsecurity-checkerを指定しても良いです。
security-checkerでチェックを行う
チェック対象のプロジェクトをC:\workに作ったので、composer.lockファイルがこのディレクトリに作成されています。
先ほどチェックした通り、"security:check"を指定して、脆弱性チェックを行ってみます。
$ vendor\bin\security-checker.bat security:check C:\work\composer.lock
Symfony Security Check Report
=============================
// Checked file: C:\work\composer.lock
[ERROR] 1 packages have known vulnerabilities.
aws/aws-sdk-php (3.1.0)
-----------------------
* CVE-2015-5723: Security Misconfiguration Vulnerability in the AWS SDK for PHP
https://github.com/aws/aws-sdk-php/releases/tag/3.2.1
! [NOTE] 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.
エラー"[ERROR] 1 packages have known vulnerabilities."が出力され、脆弱性のあるパッケージであるaws/aws-sdk-phpのver3.1.0を使用していることが検出されました。
実際のコンソール出力は、以下のように赤字で表示されるので、結果を一目で判断できます。
対象パッケージをバージョンアップしてみる
aws/aws-sdk-phpのver3.1.0に脆弱性があることが分かったので、対象プロジェクトでパッケージのバージョンを3.2.1に更新してみます。
$ cd c:\work
# comopser.jsonで指定したバージョンを変更する (説明の為sedで文字列置換してます)
$ sed -i "s/3\.1\.0/3\.2\.1/g" composer.json
# composer.jsonのバージョン指定が3.2.1になったことを確認
$ more composer.json
{
"require": {
"aws/aws-sdk-php": "3.2.1"
}
}
# パッケージの更新を実行
$ composer update
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 0 installs, 1 update, 0 removals
- Updating aws/aws-sdk-php (3.1.0 => 3.2.1): Downloading (100%)
Writing lock file
Generating autoload files
バージョンアップ後に再度チェックしてみます。
以下のように" [OK] No packages have known vulnerabilities."と表示され、このバージョンのaws-sdk-phpパッケージには既知の脆弱性が含まれないことが分かります。
$ vendor\bin\security-checker.bat security:check C:\work\composer.lock
Symfony Security Check Report
=============================
// Checked file: C:\work\composer.lock
[OK] No packages have known vulnerabilities.
! [NOTE] 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.
security-checkerでチェックできる脆弱性とは?
security-checkerでチェックは、既知の脆弱性のみです。ダウンロードしたパッケージのソースコードを静的解析して脆弱性チェックしているわけではないため、このチェックがOKでも未知の脆弱性が潜在しているリスクはあり得ます。
ですが、既知の脆弱性を抱えたパッケージを使ってしまっていないかチェックできるだけでも、かなり便利なツールです。
まとめ
Composerを利用して外部パッケージを管理している場合、security-checkerを使うことで既知の脆弱性を抱えたライブラリを使用していないかのチェックを容易に行うことができます。
コマンドを手動で実行して確認するのも良いですが、脆弱性は後になってから報告されることもあるため、JenkinsなどのCIツールで定期的に実行させておくと安心です。