タイトル
 メニューにないコーナーはTopからいけます
TOP覚え書きWebAppSecurity → This Page
ウェブアプリケーション作成時のセキュリティ注意点

送信データ内容の信頼性

クライアントから送信されてきたデータを信用するな

別の章で「クライアント側での入力値チェック」について説明したので、
意図していないデータが送信されることがあるのは分かったと思います。
そこで <input type="text">, <input type="password">, <textarea> に関しては
JavaScript のチェックだけでなくサーバ側のチェックも追加することになると思いますが、
では <input type="radio">, <input type="hidden">, <select> の値はどうでしょうか?
「入力チェックがなくても想定外の値になることはないし大丈夫」
などと思っていると大変な目にあうかもしれません。

以下は年齢層と結婚の有無を登録する画面です。
前の画面からログインし、ユーザ情報変更を選択したらこの画面にくるとでも思って下さい。
年齢層は select タグのリストから選択するので、リストにない値を指定することは出来ません。
結婚の有無も radio から選択するので、どちらかしか選択できません。
また、隠し項目として hidden にユーザの ID である 12345 という値も持たせてあります。
図:画面例

また、以下がこの画面のソースです。
<html>
<body>

<form name="frmTest" action="./ChangeUserInfo.php" method="post">
	<table>
	<tr>
		<td>年齢層</td>
		<td>
			<select name="selAge">
			<option value="1">〜19</option>
			<option value="2">20〜29</option>
			<option value="3">30〜39</option>
			<option value="4">40〜49</option>
			<option value="5">50〜</option>
			</select>
		</td>
	</tr>
	<tr>
		<td>結婚の有無</td>
		<td>
			<input type="radio" name="radMarriage" value="0" checked>未婚<br>
			<input type="radio" name="radMarriage" value="1">結婚している
		</td>
	</tr>
	</table>
	<input type="hidden" name="txtID" value="12345">
	<input type="submit" value="登録">
</form>

</body>
</html>

上記例の問題点

通常、上記例は確かにブラウザ上で別の値に変えて送信することは出来ません。
しかし、ブラウザのプラグイン(FireFox の WebDeveloper など)を使って
フォーム上の値を無理やり変更して送信したり、
そもそも HTML をローカルに保存し、改変して送信することが可能です。
改変する場合、以下のように改変して送信することが可能です。
<html>
<body>

<!-- form タグの action 属性をフルパスに変更 -->
<form name="frmTest" action="http://www.Test.co.jp/Test/ChangeUserInfo.php" method="post">
	<table>
	<tr>
		<td>年齢層</td>
		<td>
			<select name="selAge">
			<option value="1">〜19</option>
			<option value="2">20〜29</option>
			<option value="3">30〜39</option>
			<option value="4">40〜49</option>
			<option value="5">50〜59</option>
			<option value="6">60〜</option>	<!-- 追加 -->
			</select>
		</td>
	</tr>
	<tr>
		<td>結婚の有無</td>
		<td>
			<input type="radio" name="radMarriage" value="0" checked>未婚<br>
			<input type="radio" name="radMarriage" value="1">結婚している
			<input type="radio" name="radMarriage" value="2">離婚しました	<!-- 追加 -->
		</td>
	</tr>
	</table>
	<input type="hidden" name="txtID" value="99999">	<!-- 変更 -->
	<input type="submit" value="登録">
</form>

</body>
</html>

この HTML ファイルからデータを送信されると、想定外のデータをデータベースに登録することになり、
場合によってはそのデータを使っている各種画面で影響が出ます。
作った画面の値が常に送信されると思ってはいけません。

対応策

1.サーバ側での入力値チェックの強化
 上記例でいうと selAge の value 値が 1〜5 以外であればエラー、
 radMarriage の value 値が 0 か 1 以外であればエラーとする処理をサーバ側に組み込みます。
2.セッションの利用
 上記例でいうと txtID の利用は廃止し、ユーザの ID はセッション変数に保持させます。
 ただし、クッキーを無効にされていると使えないので注意が必要です。

ちなみに、入力画面→確認画面→登録処理という遷移をする構成の場合、
入力チェックは「入力画面→確認画面」だけでなく、必ず「確認画面→登録処理」のタイミングでも行いましょう。
なぜなら「入力画面」だけでなく、「確認画面」も改変される可能性があるからです。

TOP覚え書きWebAppSecurity → This Page
Valid CSS!