APIサーバの脆弱性診断をVAddyで実行してチェック

VAddyは、[継続的なWeb脆弱性診断が簡単に実現できるSaaSです](https://vaddy.net/ja/)。
CIと簡単に連携でき、継続的なセキュリティテストが実現できます。

モバイルアプリだけでなくWebアプリケーションでも裏側はRestAPIにして、裏の処理は全てAPIサーバが担当するケースが増えてきました。
今回はAPIサーバの脆弱性検査をVAddyを使って実施し、予め仕込んでおいたコマンドインジェクションの脆弱性を発見するところを試してみたいと思います。

## RestAPIの脆弱性検査
APIサーバとの通信はGET, POST, PUT, DELETEのメソッドを使い、実際のデータはJSONデータと成っているケースが多いと思います。
JSONデータをそのままAPIサーバに投げている場合は、脆弱性検査の時にもJSONの中身を把握して、キーに対応する値を検査用データに変えて検査する必要があります。

VAddyはJSONデータを介したAPIサーバの検査ができるようになってます。また、PUTやDELETEなどのメソッドにも対応しています。実際にお客様からヒアリングした結果、VAddyを使ってiOSやAndroidアプリのAPIサーバを検査している方もいます。

## 検査対象のサンプルアプリケーション
JSONをPOSTして処理する簡単なアプリケーションを作成して検査を行います。
PHPで、受け取ったJSONの中の値を使ってコマンドの引数にそのまま渡します。

```php
<?php
$json = file_get_contents('php://input');
$data = json_decode($json);

$title = $data->Articles->title;
system("ls ${title}");

echo htmlspecialchars($title, ENT_QUOTES) . "\n";
```

## JSONデータをPOSTしてみる
作ったサンプルアプリケーションに対してJSONデータをPOSTしてみます。
curlコマンドを使って、Articlesの中にtitleとbodyパラメータを持つJSONデータを投げ、動作を確認します。

```bash
curl -v \
-H "Accept: application/json" -H "Content-type: application/json" \
-X PUT -d '{"Articles":{"title":"index.php", "body":"bodyhoge"}}' \
http://wp-demo.vaddy.net/jsondemo.php
```


## VAddyが検査する対象のURLを登録（クロール）
ではこのアプリケーションをVAddyで検査してみます。
検査の前に、検査対象となる画面のURLやパラメータをVAddyに登録します。VAddyはこれを正常ケースのシナリオファイルとして扱い、検査していきます。

今回は通信が分かりやすいように、APIサーバに対してcurlコマンドを使ってクロールデータを作成してみます。
ブラウザを使ったクロールデータの作成方法もありますので、こちらの記事([10分でWebアプリの脆弱性検査ができた！VAddyでWordPressをスキャンしてみる](http://qiita.com/ichikaway/items/1ca084d86bd2f3810daa))を参考にしてください。


今回の検査対象のURLは、`http://wp-demo.vaddy.net/jsondemo.php`です。

```bash
#!/bin/sh

PROXY='--proxy http://54.92.84.100:28888'
#PROXY=''

## (1)
curl $PROXY -k 'http://wp-demo.vaddy.net/vaddy-e537ba1a24ca35a.html?action=begin&project_id=12345'

## (2)
curl $PROXY -k 'http://wp-demo.vaddy.net/jsondemo.php'

## (3)
curl $PROXY -k \
-H "Accept: application/json" -H "Content-type: application/json" \
-XPOST -d '{"Articles":{"title":"index.php", "body":"bodyhoge"}}' \
'http://wp-demo.vaddy.net/jsondemo.php'


## (4)
sleep 1;
curl $PROXY -k 'http://wp-demo.vaddy.net/vaddy-e537ba1a24ca35a.html?action=commit&project_id=12345'
```

もしhttpsのサイトをクロールする場合は、クロール時に証明書エラーが出ますので、curlの `-k` オプションもしくは `--insecure` オプションを全てのcurlコマンド実行時に付与してください。

最初に変数`PROXY`にcurlのproxyオプションをセットします。これはVAddyのProxyサーバのIPとポート番号です。この`PROXY`変数をcurlで使うと、すべての通信がVAddyのProxyサーバ経由で検査対象サーバに流れます。ここでVAddyは検査の元になるクロールデータを記録するのです。
ポート番号はプロジェクトごとに異なる場合がありますので、VAddyの画面からご確認ください。

(1)と(4)はクロールデータの開始と終了を実行するURLになります。開始URLから終了URLまでの間に投げたHTTPリクエストが検査の対象となります。

(3)では、POSTでJSONデータを送信しています。送信時にヘッダで`application/json`を指定しています。


これを実行すると、クロールデータがVAddy上に作成されます。
![スクリーンショット 2016-12-19 15.50.37.png](https://qiita-image-store.s3.amazonaws.com/0/61278/933b784c-c0bc-15be-1223-788bd0565bd7.png)

## VAddyで検査実行

VAddyの検査開始画面に行って、VAddyの検査を開始します。
今回はこのようなエラーが見つかりました。

![スクリーンショット 2016-12-19 15.51.13.png](https://qiita-image-store.s3.amazonaws.com/0/61278/7cc39ec0-1448-a3e5-748a-3d32d85de772.png)

`jsondemo.php`で扱うJSONデータの`title`パラメータに、コマンドインジェクションの脆弱性があったことが分かります。あとは、実際のソースコードで`title`パラメータを扱っている箇所を特定して修正していくだけです。

## さいごに

モバイルアプリケーションであっても、裏側のAPIサーバ(RestAPI)はHTTPベースのアプリケーションであることが多いと思います。VAddyを使って気軽にAPIサーバの検査も実施してみてください。
そして、一度検査した後もコードの修正のたびに脆弱性検査を実行してみてください。早めに脆弱性を発見して対策していくほうがリスクや工数の面で有利です。
VAddyは継続的インテグレーションに統合しやすいように設計しています。

### ビールネタ

香りが強く、非常に美味しいビールをたくさん作っているデンマークのミッケラー(Mikkeller)はオススメです。残念ながら渋谷にあるミッケラーバーは閉店になりましたが、ボトルビールは気軽に買えます。
私が好きなのは19種類のホップを使った[19 IPA](http://goodbeer.jp/scb/shop/shop.cgi?No=1014)です。他にもたくさんのIPAがあります。
http://goodbeer.jp/brewery/mikkeller/product.html