前回:やられアプリ BadTodo - 26.2 NULLバイト攻撃(+SQLインジェクション) - demandosigno
前回と同じ場所で今度はXSSを試します。
入力値
https://todo.example.jp/api/v1/is_valid_id.php?id=hoge%00%3Cscript%3Ealert(1)%3C/script%3E
Nullバイト(%00)を入れているためバリデーションは回避できているようです(true)
しかし入力値が何も出力されないためXSSは発動しません。
(JSONを返しているのに Content-Type が application/json ではなく text/html であることも問題の一つですがまた後日。JSONであれば古いIEでもなければXSSは発火しません)
前回SQLインジェクションを試した際に、シングルクォーテーション'
= %27
の入力でSQLエラーを出せることが分かりました。
試しに%27と少しの文字列を入れてみます。
https://todo.example.jp/api/v1/is_valid_id.php?id=hoge%00%27hoge
これで入力値をレスポンスに出力できそうです。
さらにスクリプトを追加してみます。
https://todo.example.jp/api/v1/is_valid_id.php?id=hoge%00%27hoge%3Cscript%3Ealert(%22XSS%22)%3C/script%3E
表示上はこう。
ソース上はこう。
ダブルクォーテーションやスラッシュが円記号¥(バックスラッシュ)でエスケープ処理されています。
そこで /
を使わないイベントハンドラのスクリプトで試します。
https://todo.example.jp/api/v1/is_valid_id.php?id=hoge%00%27hoge%3Cimg%20src=0%20onerror=%27alert(1)%27%3E
XSSが発動しました。
ソース上では次の通り。
img の src=0 としているため存在せず error イベントが発生します。
対策
安全なWebアプリケーションの作り方 第2版 p.108より引用
ヌルバイト攻撃に対する根本的対策は、バイナリセーフの関数のみを用いてアプリケーションを開発することですが、現実にはそれは困難です。なぜなら、ファイル名のように仕様上ヌルバイトを許容しないパラメータがあるからです。このため、アプリケーションの入り口でバイナリセーフの関数を用いて入力値のヌルバイトをチェックし、ヌルバイトがあればエラーにすることにより確実な対応が可能になります。
できるだけ新しいPHPを使う。
PHP5.3.4以降ではヌルバイト攻撃対策がされています。
t-komura.hatenadiary.org
次回:やられアプリ BadTodo - 26.4 NULLバイト攻撃(POSTリクエストの場合) - demandosigno