最新記事
(06/29)
(06/04)
(06/03)
(05/30)
(05/28)
|
ニュース
この欄には、このブログの内容に関連するニュースを掲載する予定です。
|
PHP 入力値の無害化(htmlspecialchars,htmlentities)
PHPで会員登録システムを作りたい。そのために必要な知識をひとつひとつ確認していこうと思っています。今回のテーマは、「入力値の無害化」。
入力値のチェックは、クライアントサイドでもJavaScriptを利用すれば可能です。しかしながら、JavaScriptを無効にしている場合には、このチェック機能が働きません。サーバーサイドでも入力値をチェックし、危険なスクリプトが働かないようにする必要があります。
これまでのサンプルでは、「PHP入門」的な面を重視していたので、できるだけ単純な記述にしていました。このため、セキュリティ面の考慮はしていませんでした。セキュアなサイトを目指すのであれば、自分自身でそれなりに勉強すべきです。私自身、PHPの初心者であり、またWEBサイトを構築した経験もありません。このブログで示すサンプルは、あくまで初心者が勉強の過程で作成したものです。もっと上手な方法はあると思います。要するに、サンプルを利用してトラブルが起きても、私を責めないでくださいということです。
さて、「危険なスクリプトの排除」というテーマに戻ります。
インタラクティブなサイトでは、フォーム画面で入力された文字列を送信させて、何らかの処理を行います。入力された文字列が想定内のものであれば、何も悪さはしないでしょう。しかしながら、世の中には悪い人やウッカリ屋さんもいて、想定外の文字列を送信してしまう人もいるようです。そういう文字列をチェックしたり、排除する仕組みを用意しておかないと、そのサイトが無茶苦茶になったり、秘密情報を漏洩させてしまうことになります。
送信される文字列にJavaScriptの記述を潜りこませるだけでも、いろいろなことができるようです。
これを避ける手段としては、送信される文字列の長さを制限することが考えられます。スクリプトを送り込もうとすれば、そのスクリプトの長さだけ文字列が長くなるからです。
しかしながら、送信してもらいたいデータは、ユーザーidのように長さ制限できるものとは限りません。長い文章を送ってもらう場合もあるでしょう。他の手段も考える必要があります。
スクリプトが持つ特徴を捉えて、これに該当する文字は拒否するか、無害な文字に置き換えることが次に考えられます。スクリプトの多くは「<」で始まります。これを文字列から取り除くか「<」に置き換えることができれば、そのスクリプトは実行できません。この仕組みを実現する関数がPHPには用意されています。「htmlspecialchars」と「htmlentities」です。
「htmlspecialchars」は、 特殊文字をHTMLエンティティに変換する関数です。変換される特殊文字は
& → &
< → <
> → >
" → "(ダブルクオート。ENT_NOQUOTESが設定されていない場合)
' → '(シングルクオート。ENT_QUOTESが設定されている場合)
「htmlentities」は、適用可能な文字を全てHTMLエンティティに変換する関数です。上記の特殊文字より変換対象となるのが多いのでしょう。一般的には「htmlspecialchars」が利用されることが多いようです。
さて、サンプルを見てみましょう。まずは、登録情報入力フォームです。「PHP ログイン管理1」のソースとほぼ同じです。新たにメールアドレスの項目を加え、説明文は省略しています。
[ソース]regist_member1.php
上の入力フォームからは、'confirm1.php' に対して'usrid'と'pwd'と'mail'が送信されます。'confirm1.php' では、このデータを受けて、ユーザーの仮登録を行います。ここでは、'usrid'と'pwd'と'mail'を受信して、文字列を無害化する部分だけを'confirm1-1.php' として示しましょう。
[ソース]confirm1-1.php
入力値のチェックは、クライアントサイドでもJavaScriptを利用すれば可能です。しかしながら、JavaScriptを無効にしている場合には、このチェック機能が働きません。サーバーサイドでも入力値をチェックし、危険なスクリプトが働かないようにする必要があります。
これまでのサンプルでは、「PHP入門」的な面を重視していたので、できるだけ単純な記述にしていました。このため、セキュリティ面の考慮はしていませんでした。セキュアなサイトを目指すのであれば、自分自身でそれなりに勉強すべきです。私自身、PHPの初心者であり、またWEBサイトを構築した経験もありません。このブログで示すサンプルは、あくまで初心者が勉強の過程で作成したものです。もっと上手な方法はあると思います。要するに、サンプルを利用してトラブルが起きても、私を責めないでくださいということです。
さて、「危険なスクリプトの排除」というテーマに戻ります。
インタラクティブなサイトでは、フォーム画面で入力された文字列を送信させて、何らかの処理を行います。入力された文字列が想定内のものであれば、何も悪さはしないでしょう。しかしながら、世の中には悪い人やウッカリ屋さんもいて、想定外の文字列を送信してしまう人もいるようです。そういう文字列をチェックしたり、排除する仕組みを用意しておかないと、そのサイトが無茶苦茶になったり、秘密情報を漏洩させてしまうことになります。
送信される文字列にJavaScriptの記述を潜りこませるだけでも、いろいろなことができるようです。
これを避ける手段としては、送信される文字列の長さを制限することが考えられます。スクリプトを送り込もうとすれば、そのスクリプトの長さだけ文字列が長くなるからです。
しかしながら、送信してもらいたいデータは、ユーザーidのように長さ制限できるものとは限りません。長い文章を送ってもらう場合もあるでしょう。他の手段も考える必要があります。
スクリプトが持つ特徴を捉えて、これに該当する文字は拒否するか、無害な文字に置き換えることが次に考えられます。スクリプトの多くは「<」で始まります。これを文字列から取り除くか「<」に置き換えることができれば、そのスクリプトは実行できません。この仕組みを実現する関数がPHPには用意されています。「htmlspecialchars」と「htmlentities」です。
「htmlspecialchars」は、 特殊文字をHTMLエンティティに変換する関数です。変換される特殊文字は
& → &
< → <
> → >
" → "(ダブルクオート。ENT_NOQUOTESが設定されていない場合)
' → '(シングルクオート。ENT_QUOTESが設定されている場合)
「htmlentities」は、適用可能な文字を全てHTMLエンティティに変換する関数です。上記の特殊文字より変換対象となるのが多いのでしょう。一般的には「htmlspecialchars」が利用されることが多いようです。
さて、サンプルを見てみましょう。まずは、登録情報入力フォームです。「PHP ログイン管理1」のソースとほぼ同じです。新たにメールアドレスの項目を加え、説明文は省略しています。
[ソース]regist_member1.php
<?php
session_start();
if($_SESSION["usrid"]){
header("Location:membertop.php");
exit;
}
?>
<html>
<head>
<title>ログイン1</title>
</head>
<body>
<form action='confirm1.php' method='post'>
ユーザーid:<input type='text' name="usrid">
パスワード:<input type='password' name="pwd">
メールアドレス:<input type='text' name="mail">
<input type='submit' value="送信">
</form>
</body>
</html>
上の入力フォームからは、'confirm1.php' に対して'usrid'と'pwd'と'mail'が送信されます。'confirm1.php' では、このデータを受けて、ユーザーの仮登録を行います。ここでは、'usrid'と'pwd'と'mail'を受信して、文字列を無害化する部分だけを'confirm1-1.php' として示しましょう。
[ソース]confirm1-1.php
<?php
$usrid = htmlspecialchars($_POST["usrid"]);
$pwd = htmlspecialchars($_POST["pwd"]);
$mail = htmlspecialchars($_POST["mail"]);
?>
PR