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サーバに影響を与える事が出来る処理を考えてみると、真っ先に浮かぶのがセッション周りだろう。

セッションハイジャック - Wikipedia


何らかの方法でセッションIDを入手できたら、Webサーバに対して悪意あることが出来る。

セッションIDを特定されにくいものにすれば、セッションハイジャックはされにくくなるので、PHP側でログインを必要とするアプリケーションで定期的にsession_regenerate_id()を使用する事で回避しやすくなる。

PHP: session_regenerate_id - Manual


他にもすべきことはあるけれども、それは後ほど他の項目で触れる。




PHPでXSS対策としてよく見聞きする方法が、htmlspecialcharsで<script>を&lt;script&gt;の記述に変えてしまって、JavaScriptのコードを実行できなくしまうこと。

※<や&といったHTML上でシステム的な意味を持つ文字列をHTMLエンティティと呼ぶ

PHP: htmlspecialchars - Manual

Entity (エンティティ) - MDN Web Docs 用語集: ウェブ関連用語の定義 | MDN


confirm.phpを下記のように変更する。

<?php
echo htmlspecialchars($_POST["hoge"], ENT_QUOTES, "UTF-8");

このコードにより、文字列中の文字を下記のように変換する

< → &lt;

> → &gt;

& → &amp;

' → &#039;

" → &quot;


この内容を踏まえた上で、



再度、JavaScriptのコードを入力して送信してみると、



JavaScriptのコードが実行されずに、そのままの文字列で出力された。




PHPのhtmlspecialcharsは厄介な事に、文字列中にある全てのHTMLタグの挙動を封じてしまう。

これだと、HTMLを許可したフォームにはならなくなってしまう。


htmlspecialcharsを部分的に利用出来る関数があれば良いんだけどね。

<script>以外でもWebアプリケーションのサーバに影響を与えそうなHTMLタグを見落とさないようにしないとな。

<form>、<input>、<textarea>や<button>あたりは使えないようにしておいた方が無難だろう。

クロスサイトスクリプティング - Wikipedia


追記

SOY CMSで利用しているSOY2では、htmlspecialcharsの対応をHTMLLabelを介して簡単に行えるようにしている

SOY2HTMLでsoy:idを作る - HTMLLabel編