今思いついている「インジェクション攻撃が防げるバリデーション関数」の残存リスク
昨日の記事で紹介した「ほぼ全てのインジェクション攻撃が防げるバリデーション関数」に残るリスクですが、フィードバックなどをいくつか得ました。twitterなどでコメントしてくださった方々、ありがとうございます。
いただいたフィードバックなども踏まえ、今のところ私が思いついている攻撃できるケースは以下です。気になって夜も眠れない人がいるかも知れませんので公表することにしました。
- SQL文のカラム名に外部からの入力をそのまま渡している場合、想定外のカラム名を指定されて情報が漏洩
- UnicodeのU+00A0(nbsp)のような別の文字や見えない文字によりユーザを騙す(例えば、なりすましなど)
- 表示の際に全角→半角変換するサイト(昔の携帯サイトなど)での全角文字によるXSS(徳丸さんのご指摘)
カラム名などの識別子の指定
1.は元記事にありますが、以下のようなコードがあった場合(これは設計ミスですが)、攻撃者はカラム名を自由に指定できますので、カラム名がわかればそのカラムの情報を表示させることができるかも知れません。
$sql = "SELECT ".$_GET['field_name']." FROM mytable";
ORDER BY
句のカラム名についても上記同様文字列として受け取るようなコードの場合(これも設計ミスです)、想定外のカラムでソートされ予期しない情報が漏洩する可能性があります。
Unicode文字による詐称
2.は「validation」と「vaIidation」のような紛らわしい文字によりユーザを誤認させるという昔からある攻撃です。Unicodeを使うと「kenjis」と「kenjis」のような人間には判別不能な表示が可能になります。
一応、PoCのコードを書いておきます。以下の結果は「Different」です。コピペすれば動くと思います。
<?php
if ('kenjis' === 'kenjis') {
echo 'The same' . PHP_EOL;
} else {
echo 'Different' . PHP_EOL;
}
また、U+0020などが区切り文字として解釈されインジェクションが成立する処理系があるのではないか?というコメントもいただきました。そういう処理系があるのかどうかはわかりませんが。
@kenji_s U+00A0のような空白文字の意味を考えれば字句解析の区切り文字として扱われるほうがむしろ自然で、「U+0020 と \r\n\t だけが字句解析時の区切り文字だからSQLインジェクションが成立しない」のは偶然ではないかという意味です。
— vulnerable this is a (@ajiyoshi) 2015, 6月 17
全角半角変換
3.は半角記号はバリデーション関数で弾いていますが、全角の「<」「>」などは通りますので、表示の際に文字を半角に変換をすればXSSが可能になる余地があります。このケースは対応がちょっと難しいですね。もし、出力するHTMLを表示の際に一括で変換していたら設計ミスということになりましょうか。
ということで、今のところこの程度です。
もっと、データをぶっこ抜くとか派手なのができるといい?んですが、今のところやはり無理そうです。
これは!という攻撃方法を思いついた方は是非お教えください。
Date: 2015/06/18