PHP SCHOOL.biz

PHPの学習をする為のブログです。プログラム未経験の方にも理解できるよう基本的な、PHPの知識について身に付けることができるようにわかりやすい内容にしていきたいと思っています。


PHPでのフォームのバリデーション

この章と次の章では、PHPを使用してフォームデータをバリデートする方法を紹介します。

PHPでの入力のバリデート処理

PHPフォームを処理する際のセキュリティを意識しよう!
これらのページでは、セキュリティを考慮してPHPフォームを処理する方法を示します。フォームデータの適切な検証は、フォームをハッカーやスパマーから守るために重要です!

この章で作業するHTMLフォームには、必須のオプションのテキストフィールド、ラジオボタン、送信ボタンなどのさまざまな入力フィールドがあります。

上記のフォームのバリデートをする要件は次のとおりです。

フィールド バリデートルール
Name 必須 + 文字と空白のみを入力を許可する。
E-mail 必須 + 有効なメールアドレス(@)の入力を許可します。
Website 任意。存在する場合は、有効なURLの入力を許可します。
Comment 任意。複数行入力フィールド(テキストエリア)
Gender 必須。選択する必要があります。

まず、htmlのフォームのコードを見てみましょう。

テキストフィールド

名前、メール、およびウェブサイトのフィールドはテキストで、コメントフィールドはテキストエリアです。 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>
ラジオボタン

性別の項目はラジオボタンで、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"]);?>">

フォームをsubmitした際には、フォームデータはPOSTで送信されます。

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

したがって、$ _SERVER ["PHP_SELF"]は、別のページに飛ぶのではなく、送信されたフォームデータをそのページ自体に送信します。
これにより、フォームと同じページにエラーメッセージが表示されます。

htmlspecialchars()関数とな何か?
htmlspecialchars()関数は、特殊文字をHTMLエンティティに変換します。これは、<および>のようなHTML文字を&lt; &gt;に変換することを意味します。これにより、HTMLまたはJavascriptコード(クロスサイトスクリプティング攻撃)をフォームに挿入することにより、攻撃者がコードを悪用することを防ぎます。

PHPフォームセキュリティに関する注意すべきこと。

$ _SERVER ["PHP_SELF"]変数はハッカーに悪用されることがあります。
あなたのページでPHP_SELFがそのまま使用されている場合、クロスサイトスクリプティング(XSS)攻撃をされる可能性があります。

クロスサイトスクリプティング(XSS)は、Webアプリケーションで一般的に見られる種類のコンピュータセキュリティの脆弱性です。 XSSを使用すると、攻撃者は他のユーザーが閲覧したWebページにクライアントにスクリプトを挿入できます。

"test_form.php"という名前のページに次のフォームがあるとします。

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

ユーザーが「http://www.example.com/test_form.php」のようなアドレスバーにURLを入力すると、上記のコードは次のように変換されます。

<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でアラートを表示させるスクリプトです。ページが読み込まれると、JavaScriptコードが実行されます(ユーザーに警告ボックスが表示されます)。これは、PHP_SELF変数がどのように悪用されるかという単純で無害な例です。

タグ内には、任意のJavaScriptコードを追加できることができます。ハッカーは、ユーザーを別のサーバー上のファイルにリダイレクトすることもできます。そのファイルには、グローバル変数を変更したり、フォームを別のアドレスに送信してユーザーデータを保存するなどの悪意のあるコードを格納できます。

$_SERVER["PHP_SELF"]の悪用を防ぐためには?

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

フォームもコードは、下記のようになります。

<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"], ENT_QUOTES, 'UTF-8');?>">

htmlspecialchars()関数は、特殊文字をHTMLエンティティに変換します。ユーザがPHP_SELF変数を利用しようとすると、次のような結果になります。

<form method="post" action="test_form.php/&quot;&gt;&lt;script&gt;alert('hacked')&lt;/script&gt;">

これで悪意のある攻撃は阻止され、安全になります。

PHPでのフォームのバリデート

まずやるべきことは、すべての変数をPHPのhtmlspecialchars()関数に渡すことです。
htmlspecialchars()関数を使用すると、ユーザーがテキストフィールドに次の項目を送信しようとすると、

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

これはHTMLエスケープコードとして処理されるため、実行されません。

&lt; script&gt; location.href( 'http://www.hacked.com')&lt; / script&gt; 

に変換される。

この処理をすることで、テキストエリアに入力された文字をページ上または電子メール内に表示することが安全になります。
ユーザーがフォームを送信した際に、さらに2つのことを行います。
ユーザー入力データから不要な文字(余分なスペース、タブ、改行)を取り除く(PHPのtrim()関数を使用)
ユーザ入力データからバックスラッシュ(\)を削除する(PHPのstripslashes()関数を使用)
次のステップは、すべてのチェックを行う関数を作成することです(同じコードを何度も繰り返し書くよりもずっと便利です)。
関数test_input()の名前を付けます。
さて、各$ _POST変数をtest_input()関数でチェックすると、スクリプトは次のようになります:

<!DOCTYPE HTML>  
<html>
<head>
</head>
<body>  

<?php
// define variables and set to empty values
$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, ENT_QUOTES, 'UTF-8');
  return $data;
}
?>

<h2>PHP Form Validation Example</h2>
<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"], ENT_QUOTES, 'UTF-8');?>">  
  Name: <input type="text" name="name">
  <br><br>
  E-mail: <input type="text" name="email">
  <br><br>
  Website: <input type="text" name="website">
  <br><br>
  Comment: <textarea name="comment" rows="5" cols="40"></textarea>
  <br><br>
  Gender:
  <input type="radio" name="gender" value="female">Female
  <input type="radio" name="gender" value="male">Male
  <br><br>
  <input type="submit" name="submit" value="Submit">  
</form>

<?php
echo "<h2>Your Input:</h2>";
echo $name;
echo "<br>";
echo $email;
echo "<br>";
echo $website;
echo "<br>";
echo $comment;
echo "<br>";
echo $gender;
?>

</body>
</html>

実行結果

スクリプトの開始時に、$ _SERVER ["REQUEST_METHOD"]を使用してフォームが送信されたかどうかを確認します。 リクエストメソッドがPOSTの場合は、フォームが送信されており、入力フォームの検証をします。フォームが送信されていない場合は、検証をスキップして空白のフォームを表示します。
ただし、上記の例では、すべての入力フィールドは任意入力です。ユーザーがデータを入力しなくてもスクリプトは正常に動作します。
次のステップでは、入力フィールドを必要に応じて作成し、必要に応じてエラーメッセージを作成します。