0. はじめに
前回、WordPressのセキュリティ診断ツールではカスタマイズ部分の脆弱性を検出できないという記事でWordpressにXSS(クロスサイトスクリプティング)の脆弱性を埋め込んだのですが、これが思ったより苦戦したので、誰かの役に立つかどうか分かりませんが、記録に残しておきたいと思います。
1. 苦戦ポイントその1 Wordfence のブロック
前回の検証を行うにあたり、簡単に検証したかったので、最も単純なXSSを実装することを考えました。
つまり、ユーザからの入力をブラウザに表示する箇所があれば良いことになります。
少し探したところ、Wordpressの標準テーマで、検索結果ページでそれらしい箇所がありました。
ユーザからの入力をそのまま出力しているので、この出力をサニタイズせずに出力してあげればうまく行きそうです。
念のための確認として、デフォルトの状態ではXSSの脆弱性がないことを確認してみます。
確認の仕方は、検索ボックスに以下のようにJavascriptのコードを入力します。
<script>alert("hello")</script>
それでは実際に<script>alert("hello")</script>と入力してみます。
ばーん。
Wordfenceにブロックされたようです、、、
素晴らしいですね、Wordfence。
まぁ、テストサイトなので一時的にWordfenceを無効化して解決です。
気を取り直して<script>alert("hello")</script>と入力してみます。
ばばーん。
ああ、検索結果がゼロの時は検索文字列を出力しないのね、、、
ということで、次はソースコードをいじります。
2. 苦戦ポイントその2 WordPressのサニタイズ
上記のテストから、検索結果ページで検索文字列を出力してやるために、ソースコードを加工する必要があることが分かりました。
そして、いざ実装してみたのが以下です。
1 2 3 4 5 6 |
<?php if ( have_posts() ) : ?> <h1 class="page-title"><?php printf( __( 'Search Results for: %s', 'twentyseventeen' ), '<span>' . get_search_query() . '</span>' ); ?></h1> <?php else : ?> <!-- ここを下のように変更 -- <h1 class="page-title"><?php _e( 'Nothing Found', 'twentyseventeen' ); ?></h1> --> <h1 class="page-title"><?php printf( '何も見つかりませんでした。 %s', '<span>' . get_search_query() . '</span>' ); ?></h1> <?php endif; ?> |
これで、<script>alert("hello")</script>と検索ボックスに入力すると、、、
どーん。
そのまま表示されました。
というわけで、WordpressがきちんとXSS対策されていることが分かりました。
さて、次はここから、XSSを埋め込むために、サニタイズ処理を外してやる必要があります。
しかし良く見ると、get_search_query()の戻り値ってサニタイズされてないな?と気付きました。
そんなはずはないので、get_search_query()の中身をの覗いてみると以下のようになっています。
1 2 3 4 5 6 7 |
function get_search_query( $escaped = true ) { $query = apply_filters( 'get_search_query', get_query_var( 's' ) ); if ( $escaped ) $query = esc_attr( $query ); return $query; } |
なるほど。
引数がない時は自動的にサニタイズ用の関数であるesc_attr( $query )が使われているようです。
なので、以下のように、引数にfalseを渡して呼び出してやれば、サニタイズを外すことができそうです。
1 |
<h1 class="page-title"><?php printf( '何も見つかりませんでした。 %s', '<span>' . get_search_query(false) . '</span>' ); ?></h1> |
これでどうだ!と満を持して実行してみます。
ばばばーん。
あああ、ChromeのXSSブロックに引っかかったようです。
3. 苦戦ポイントその3 Chromeのブロック
Chromeを含む最近のいわゆるモダンブラウザでは、XSS(クロスサイトスクリプティング)の疑いがあるアクセスをブロックする機能が標準で備わっています。
この機能の正式名称はChromeではXSS Auditorといいます。
そしてこの機能は、Chromeを起動する際、以下のように特殊な引数をつけることで無効化できます。
"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --args --disable-xss-auditor
以下のように、ショートカットを作っておくと便利です。
ここで、はまりポイントが2点ありました。
ひとつは、ネットで検索すると古い情報が引っかかってしまう事です。
というか、そもそもこの引数の体系も、Chromeのアップデートによっていつ変更されるか分からない類のもののようです。
なので、古い情報があちこちに出回っているようです。
例えば、引数は--disable-web-securityにする、といっていたり、Chromeが使用するユーザディレクトリを指定するために、--user-data-dir="%UserProfile%\AppData\Local\Google\Chrome\User Data"を付けないとダメ、といった具合です。
少なくとも2018年9月の時点では--args --disable-xss-auditorを付けるだけで行けます。
逆に言えば、この仕様も将来変更されている可能性があるのでご注意ください。
そしてもう一つは、Chromeを一度全てクローズしなければいけないということです。
タスクマネージャでChromeのプロセスが残っていたら全部終了してしまいましょう。
4. まとめ
Webサイトの脆弱性はいとも簡単に混入する、と思っていましたが、いざ意図的に再現しようと思うとなかなか難しいことが分かりました。
まぁ、わざと脆弱性を実装するなんて人はそんなにいないと思いますが、この記事が誰かの役に立てばいいな、と思います。