やられアプリ BadTodo - 26.3 NULLバイト攻撃(+XSS)

前回:やられアプリ 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より引用
ヌルバイト攻撃に対する根本的対策は、バイナリセーフの関数のみを用いてアプリケーションを開発することですが、現実にはそれは困難です。なぜなら、ファイル名のように仕様上ヌルバイトを許容しないパラメータがあるからです。このため、アプリケーションの入り口でバイナリセーフの関数を用いて入力値のヌルバイトをチェックし、ヌルバイトがあればエラーにすることにより確実な対応が可能になります。

teratail - ヌルバイト攻撃について

できるだけ新しいPHPを使う。
PHP5.3.4以降ではヌルバイト攻撃対策がされています。 t-komura.hatenadiary.org

次回:やられアプリ BadTodo - 26.4 NULLバイト攻撃(POSTリクエストの場合) - demandosigno

/* -----codeの行番号----- */