PHPプログラミング

最終更新日:
公開日:

ワークショップ

お問い合わせフォームを作る(5)

入力値のサニタイズ

ワークショップ「お問い合わせフォームを作成する」の第5回目は、フォームにセキュリティ対策として入力値のサニタイズ処理を実装していきます。

この記事のポイント

  • 公開状態のサイトに設置するフォームはセキュリティ対策を考慮する
  • サニタイズ処理を実装する

目次

概要

前回は、フォームの各ページでPOSTパラメータを引き継ぐ設定をしました。
今回は、セキュリティ対策の1つである「入力値のサニタイズ」を実装していきます。

サニタイズとは?

「サニタイズ」は「消毒する」という意味で、プログラミングにおいては入力値などのテキストデータを無害化する意味で使われます。

より具体的には、フォームにHTMLやJavaScriptなどのコード、無効な記号などが入力されたとしても、それらが動作しないよう無効な状態にしてフォームの予期せぬ動作を未然に防ぐ処置です。

サニタイズが無効なときの危険性

仮に、フォームの「氏名」に次のようなJavaScriptコードを入力したとします。

フォームにJavaScriptコードを入力

この状態で「入力内容を確認するボタン」を押すと、以下のような動作をします。

外部の別サイトへ遷移するイメージ

フォームに入力したJavaScriptコードが実行され、外部の別サイトへリダイレクトされてしまいました。

このようにコードが入力されてしまうと意図せぬ動作を引き起こす可能性があり危険です。
しかしフォームは公開状態のサイトに設置するため、常に何かしらのリスクはあると考えてセキュリティ対策を施しておく必要があります。
その一環として、フォームの入力値は必ずサニタイズを行って無害化したテキストデータで扱うようにしていきます。

今回使用しているコードは、前回までに作成したものを使うことを前提としています。
前回のページ:vol.4 入力値の引き継ぎ
前回作成したコードはこちら:vol.4のサンプルコード – GitHub

サニタイズに使用する関数

これからフォームにサニタイズを実装していきますが、まずは使用する関数についてみておきましょう。
サニタイズはhtmlspecialchars関数を使って行います。

htmlspecialchars関数のパラメータ

ちょっと長い関数名ですね。
この関数を使うと、HTMLタグやスクリプトコードを「HTMLエンティティ」へ変換し、無効化することができます。
HTMLエンティティとは、コンピュータが記号を文字として扱うためにあらかじめ定められた文字の名称です。

例えば、HTMLタグ記述で使う「<」であればHTMLエンティティは「&lt;」です。
同じように、他の文字にも対応するHTMLエンティティが存在します。

HTMLファイルに「<br>」と書くと普通に改行が入ってしまいますが、HTMLエンティティで「&lt;br&gt;」と書けば、HTMLタグとして認識されずに通常テキストとして出力することができます。改行もされません。

Note

他の記号のHTMLエンティティについては、別記事「HTMLの記号・特殊文字の文字コード表(文字実体参照、数値文字参照)」を参照してください。

htmlspecialchars関数のパラメータは最大4つ指定できますが、今回は2つ目までを使用します。

1つ目のパラメータはサニタイズしたい文字列を指定します。
今回のフォームのケースでは入力された値が入ります。

2つ目のパラメータは変換ルールを指定する定数が入ります。
指定できる値は数種類ありますが、今回は「ENT_QUOTES」を指定します。
ENT_QUOTES」はシングルクォート、ダブルクォートのどちらもHTMLエンティティへ変換する対象とします。

その他、指定できるパラメータが気になる方は、php.netより詳細を参照してください。
htmlspecialchars関数 – php.net

フォームにサニタイズを実装する

それでは、実際にフォームへサニタイズを実装していきましょう。
index.phpを開いて、以下のコードを入力してください。

Note

赤い箇所は追加するコードを、オレンジの箇所は修正しているコードを示します。

index.php

<?php
//var_dump($_POST);

// 変数の初期化
$page_flag = 0;
$clean = array();

// サニタイズ
if( !empty($_POST) ) {
	foreach( $_POST as $key => $value ) {
		$clean[$key] = htmlspecialchars( $value, ENT_QUOTES);
	}
}

if( !empty($_POST['btn_confirm']) ) {

	$page_flag = 1;

--- 省略 ---

短いコードですが、サニタイズ処理は以上です。
処理の内容を見ていきます。

新しく追加したif文では、POSTパラメータが存在するかを判定しています。
もしPOSTパラメータが渡されなかったときはサニタイズ処理は実行されません。

その中のforeach文ではPOSTパラメータを配列ごと渡し、入力値を1つずつ取り出してサニタイズしていきます。
その後、値を配列$cleanに格納します。

以上の結果から、サニタイズされた入力値は全て$cleanに入っているので、今後の処理でもこの配列にある値を使用するように変更していきます。

今までは全てスーパーグローバルの「$_POST」に入っている値を使ってきましたが、これらを全て$cleanに置き換えていきます。
配列のキーは同じなので、単純に「$_POST」から「$clean」へ置換するだけで大丈夫です。

以上でサニタイズの実装完了です。
次回は、入力された値をチェックするバリデーションを実装します。

今回作成したコードはこちら:vol.5のサンプルコード – GitHub