SOY Board on SOY Shopの記事で、SOY Shop上で掲示板アプリを展開出来る機能を追加したことを紹介した。
このサイトに設置する為の機能が大体揃ったので、そろそろ設置しようと思ったが、入力フォームの記述の制約が少ないフォームを設置するするのはサイバー攻撃の視点でかなり怖い。
掲示板を設置する前に、巷にあるWebサイト関連のサイバー攻撃を整理することにしよう。
脆弱性について理解するために、Ohmshaから出版されている齋藤孝道著 マスタリングTCP/IP 情報セキュリティ編の著者のページであるWebアプリケーションの脆弱性の解説&体験ページ - 明治大学 情報セキュリティ研究室を参考にすることにした。
上記のページによると、見ておくべき攻撃は
・XSS(クロスサイトスクリプティング)
・SQLインジェクション
・CSRF(クロスサイトリクエストフォージェリ)
あたりになるらしい。
とりあえず、一番目のXSSから見ていこう。
XSSを試す為に下記のファイル構成にして、
. ├── confirm.php └── index.php
index.php
<form action="confirm.php" method="post"> <input type="text" name="hoge" value=""> <input type="submit"> </form>
confirm.php
<?php echo $_POST["hoge"];
のようにして、超簡易的な入力フォームと入力内容の確認画面を設けた。
超簡易的なフォームを表示して、
入力フォームにJavaScriptのコードを入力して送信する。
入力内容の確認画面で入力したJavaScriptのコードが実行されてしまった。
JavaScriptのコードが実行されたら何が問題なのか?
JavaScriptのコードを介して、フォームを設置しているWebサーバに影響を与える事が出来る処理を考えてみると、真っ先に浮かぶのがセッション周りだろう。
何らかの方法でセッションIDを入手できたら、Webサーバに対して悪意あることが出来る。
セッションIDを特定されにくいものにすれば、セッションハイジャックはされにくくなるので、PHP側でログインを必要とするアプリケーションで定期的にsession_regenerate_id()を使用する事で回避しやすくなる。
PHP: session_regenerate_id - Manual
他にもすべきことはあるけれども、それは後ほど他の項目で触れる。
PHPでXSS対策としてよく見聞きする方法が、htmlspecialcharsで<script>を<script>の記述に変えてしまって、JavaScriptのコードを実行できなくしまうこと。
※<や&といったHTML上でシステム的な意味を持つ文字列をHTMLエンティティと呼ぶ
PHP: htmlspecialchars - Manual
Entity (エンティティ) - MDN Web Docs 用語集: ウェブ関連用語の定義 | MDN
confirm.phpを下記のように変更する。
<?php echo htmlspecialchars($_POST["hoge"], ENT_QUOTES, "UTF-8");
このコードにより、文字列中の文字を下記のように変換する
< → <
> → >
& → &
' → '
" → "
この内容を踏まえた上で、
再度、JavaScriptのコードを入力して送信してみると、
JavaScriptのコードが実行されずに、そのままの文字列で出力された。
PHPのhtmlspecialcharsは厄介な事に、文字列中にある全てのHTMLタグの挙動を封じてしまう。
これだと、HTMLを許可したフォームにはならなくなってしまう。
htmlspecialcharsを部分的に利用出来る関数があれば良いんだけどね。
<script>以外でもWebアプリケーションのサーバに影響を与えそうなHTMLタグを見落とさないようにしないとな。
<form>、<input>、<textarea>や<button>あたりは使えないようにしておいた方が無難だろう。
追記
SOY CMSで利用しているSOY2では、htmlspecialcharsの対応をHTMLLabelを介して簡単に行えるようにしている
SOY2HTMLでsoy:idを作る - HTMLLabel編