簡単なプログラムを作成してみよう
入力値チェックの基本
いよいよ今回が連載最終回です。本記事では、総仕上げとして、セキュリティーについて解説した後、簡単なアプリケーションを作成し、実際にPHPがどのように動くかを体験できるようにしていきます。
前回は、formを使ったデータの受け渡しについて学びました。formのデータを受け取る方法は単純ですが、サイト閲覧者が入力したデータは、必ずしもサイト運営者が要望するデータではない場合があります。
例えば、テキスト文章を入力する場所に、HTMLタグやJavaScriptコードが入っていたらどうしますか。半角の数字が入ってほしいのに、全角文字が入っていたらどうしましょう。こういった不正なデータ入力を防止するために、入力値チェックが必要になってきます。
入力値チェックは、JavaScriptのように、クライアントサイド(ブラウザ側)でチェックする方法と、サーバーサイドでチェックする方法の2つが存在します。
クライアントサイドでのチェックは、どちらかというとユーザービリティ向上のために行った方が便利です。しかし、JavaScriptなどはブラウザの設定でOffにされる場合があるので、クライアントサイド側でのチェックに頼ることはできませんので、必ずサーバーサイドでのチェックが必要になります。PHPはサーバーサイドのプログラムになるので、PHPで入力値チェックをすることになります。
入力値チェックの考え方は、ブラックリスト方式とホワイトリスト方式があります。
ブラックリスト方式は、入力値として入ってはいけない不正なデータのリスト(ブラックリスト)を持っていて、ブラックリストに載っているデータを阻止するというものです。ブラックリストに抜けがあると、不正なデータを許してしまうという欠点があります。
ホワイトリスト方式は、正しいデータのリスト(ホワイトリスト)を持っていて、ホワイトリストに無いデータは、すべて入力を阻止するというものです。入力値として正しいデータしか許さないので、強固なセキュリティーを確保することができます。
セキュリティー対策(htmlspecialchars)
前回、フォームで受け取ったデータを変数に入れた状態で説明が終わりました。受け取ったデータをそのまま画面表示しても、問題が起こらない場合が多いのですが、1つだけ注意してほしいことがあります。
それは、JavaScriptの入力です。悪意のある人はJavaScriptコードを使って、悪いことをしようと考えます。JavaScriptコードが実行できる環境を与えてしまうと、クロスサイトスクリプティング(http://ja.wikipedia.org/wiki/%E3%82%AF%E3%83%AD%E3%82%B9%E3%82%B5%E3%82%A4%E3%83%88%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0)というセキュリティー上致命的な問題が起こる可能性があります。
よって、ユーザーから受け取った文字列をecho文で画面出力するときは、クロスサイトスクリプティング対策をする必要があります。具体的には、htmlspecialchars()という関数を使って、出力値をエスケープすることで対応します。
では、htmlspecialchars()が無い場合と有る場合の処理の違いについて解説していきましょう。下記は、htmlspecialchars()が無い場合で、PHPコード内で変数にJavaScriptが含まれており、その変数を単純にecho文で出力した例です。
$str ="";
echo $str;
?>
この場合、JavaScriptが解釈されて、ブラウザ上で実行されてしまいます。
下記は、htmlspecialchars()が有る場合で、JavaScriptが含まれている変数を出力する前に、htmlspecialchars()で変換処理をさせています。
$str ="";
echo htmlspecialchars($str, ENT_QUOTES);
?>
この場合は、JavaScriptは実行されず、ブラウザ上ではスクリプトコードを含めて正常に表示されます。
これは、「」という文字列が、htmlspecialchars()という関数を使って、「<script>alert('test')</script>」に変換されているからです。
htmlspecialchars()は、図1のような変換ルールに基づいて、文字列を変換してくれます。htmlspecialchars()には、「ENT_QUOTES」という変換のオプションがありますが、シングルクオート(')も変換対象にするために、必ず「ENT_QUOTES」オプションも付けてください。
安全にプログラムを運用するために、ユーザーからの入力値をecho文で表示するときは、「htmlspecialchars("文字列", ENT_QUOTES)」という変換を実施しましょう。