PHPフォーム検証

このセクションと次のセクションでは、PHPを使用してフォームデータを確認する方法について説明します。

PHPフォーム検証

ヒント:PHPフォームの処理では安全性を重視してください!

これらのページでは、PHPフォームを安全に処理する方法を展示します。HTMLフォームデータに対する適切な検証は、ハッキングやスパムメールを防ぐために重要です!

後で使用するHTMLフォームには、必須および任意のテキストフィールド、ラジオボタンおよび送信ボタンなど、さまざまな入力フィールドが含まれています:

上記のフォームは以下の検証ルールを使用しています:

フィールド 検証ルール
Name 必須。アルファベットとスペースを含む必要があります。
E-mail 必須。有効なメールアドレス(@と.を含む)を含む必要があります。
Website 任意。記入するときは、有効なURLを含む必要があります。
Comment 任意。複数行の入力フィールド(テキストボックス)
Gender 必須。必ず選択してください。

まず、このフォームの純粋なHTMLコードを見てみましょう:

テキストフィールド

name、email、websiteはテキスト入力要素で、commentフィールドはテキストボックスです。HTMLコードは以下のようです:

Name: <input type="text" name="name">
E-mail: <input type="text" name="email">
Website: <input type="text" name="website">
Comment: <textarea name="comment" rows="5" cols="40"></textarea>

オプションボタン

genderフィールドはオプションボタンで、HTMLコードは以下のようです:

Gender:
<input type="radio" name="gender" value="female">Female
<input type="radio" name="gender" value="male">Male

フォーム要素

フォームのHTMLコードは以下のようです:

<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>

このフォームを提出する際、method="post"を通じてフォームデータを送信します。

$_SERVER["PHP_SELF"]変数とは何ですか?

$_SERVER["PHP_SELF"]は、現在実行中のスクリプトのファイル名を返す一種のスーパーグローバル変数です。

したがって、$_SERVER["PHP_SELF"]は、フォームデータをページ自体に送信し、別のページに遷移しません。そのため、ユーザーはフォームページでエラーメッセージを取得できます。

htmlspecialchars() 関数とは何ですか?

htmlspecialchars() 関数は特殊文字を HTML エスケープ文字に変換します。これは、< や > などの HTML 文字が < や > に置き換わることを意味します。これにより、攻撃者がフォームに HTML や JavaScript コード(クロスサイトスクリプティング攻撃)を注入してコードを悪用することを防ぐことができます。

PHP フォームのセキュリティに関する重要なヒント

$_SERVER["PHP_SELF"] 変数はハッカーに利用されることがあります!

PHP_SELF を使用しているページでは、ユーザーがアンダースコアを入力してクロスサイトスクリプティング(XSS)を実行することができます。

ヒント:クロスサイトスクリプティング(XSS)は、Webアプリケーションに常见なコンピューターセキュリティの脆弱性の種類で、攻撃者が他のユーザーがブラウジングしているウェブページにクライアントスクリプトを注入することができます。

例えば「test_form.php」という名前のページに以下のフォームがあります:

<form method="post" action="<?php echo $_SERVER["PHP_SELF"];?>">

今、ユーザーが正常な URL にアクセスした場合、例えば「http://www.example.com/test_form.php」、上記のコードは以下のように変換されます:

<form method="post" action="test_form.php">

今のところ、すべて正常です。

ただし、ユーザーが以下の URL をアドレスバーに入力した場合:

http://www.example.com/test_form.php/%22%3E%3Cscript%3Ealert('hacked')%3C/script%3E

この場合、上記のコードは以下のように変換されます:

<form method="post" action="test_form.php"/><script>alert('hacked')</script>

このコードはスクリプトとアラートコマンドを追加しており、このページが読み込まれた後、JavaScript コードが実行されます(ユーザーにはアラートボックスが表示されます)。これは PHP_SELF 変数がどのように利用されるかの単純で無害な例です。

意識すべきこと <script> タグ内にどんな JavaScript コードも追加できます!ハッカーがユーザーを別のサーバー上のファイルにリダイレクトし、そのファイル内の悪意のあるコードがグローバル変数を変更したり、フォームを他の場所に提出してユーザーのデータを保存したりすることができます。

$_SERVER["PHP_SELF"]が利用されるのを防ぐ方法は?

htmlspecialchars() 関数を使用することで、$_SERVER["PHP_SELF"]が利用されるのを防ぐことができます。

フォームのコードは以下のようです:

<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">

htmlspecialchars() 関数は特殊文字を HTML エンティティに変換します。今、ユーザーが PHP_SELF 変数を利用しようとすると、以下のような出力がなされます:

<form method="post" action="test_form.php/"><script>alert('hacked')</script>">

利用不可能、危害なし!

PHPを使用してフォームデータを検証

まず最初に、PHPの htmlspecialchars() 関数を通じてすべての変数を渡します。

htmlspecialchars() 関数を使用してから、ユーザーがテキストフィールドに以下のような内容を提出しようとすると:

<script>location.href('http://www.hacked.com')</script>

- このコードは実行されません。なぜなら、エスケープされたコードとして保存されるからです。以下のようになります:

<script>location.href('http://www.hacked.com')</script>

今のこのコードは、ページに表示されるか、メールに含まれる場合に安全です。

ユーザーがこのフォームを提出した際には、以下の二つのことを行います:

  1. (PHPの trim() 関数を通じて)ユーザー入力データの不必要な文字(余分なスペース、タブ、改行)を取り除きます。
  2. (PHPの stripslashes() 関数を通じて)ユーザー入力データの反斜杠(\)を削除します。

次に、効率を高めるために、チェック関数を作成します(コードを一つずつ書くよりも効率的です)。

この関数を test_input() と名付けます。

今では、test_input() 関数を通じて各 $_POST 変数をチェックすることができます。スクリプトは以下のようです:

<?php
// 変数を定義し、空値に設定
$name = $email = $gender = $comment = $website = "";
if ($_SERVER["REQUEST_METHOD"] == "POST") {
  $name = test_input($_POST["name"]);
  $email = test_input($_POST["email"]);
  $website = test_input($_POST["website"]);
  $comment = test_input($_POST["comment"]);
  $gender = test_input($_POST["gender"]);
}
function test_input($data) {
  $data = trim($data);
  $data = stripslashes($data);
  $data = htmlspecialchars($data);
  return $data;
}
?>

実行例

スクリプトの先頭で、フォームが $_SERVER["REQUEST_METHOD"] を使用して送信されているかを確認しました。REQUEST_METHOD が POST なら、フォームが送信されています - それを検証する必要があります。送信されていない場合、検証をスキップし、空白のフォームを表示します。

しかし、上記の例では、すべての入力フィールドが任意です。ユーザーがデータを入力しない場合でも、スクリプトが正常に動作します。

次のステップは、必須入力フィールドを作成し、必要に応じて使用するエラーメッセージを作成することです。