[Utility.php] GET, POST, COOKIE を安全に取得するfunction()
篠原 隆司
アフィリエイト広告を利用しています
このページの内容が役に立ったら X (旧twitter) でフォローして頂けると励みになります
挨拶や報告は無しで大丈夫です
Utility.phpに記述しておきたいfunctionを掲載していきます。
記事中【 C_ 】 で始まるコードは定数です。server_dependence.phpを参照してください。
GET, POST, COOKIE を安全に取得するfunction()
GET, POST, COOKIEを取得するとき、$_GET['hoge'] のように取得しますが、
echo $_GET['hoge'];
のように、そのまま出力したり保存やコマンドの一部として使用することは、セキュリティの問題上望ましくありません。
※ スーパーグローバル変数を取得してみるfunction で、本記事の補足をしております。
以下で紹介するfunction()ではこういった問題を解消し、安全な形で外部変数を取得します。
説明は、コードの下に続きます。
/*
* GET, POST, COOKIE 外部変数を取得
*
* [php.ini] or [.htaccess] -> php_flag register_globals Off
*
* @param string $Name : $_GET[$Name], $_POST[$Name], $_COOKIE[$Name]
* @param string $Type : get, post, cookie
* @param string $Charset : utf8, sjis, euc ... etc
* @param bool $Decode : true = urldecode()
*/
function aulta_getOutsideVariable($Name, $Type, $Charset = "utf-8", $Decode = false)
{
$ret = "";
switch (strtolower($Type)){
case "get":
if (isset($_GET[$Name])) $ret = $_GET[$Name];
break;
case "post":
if (isset($_POST[$Name])) $ret = $_POST[$Name];
break;
case "cookie":
if (isset($_COOKIE[$Name])) $ret = $_COOKIE[$Name];
}
$ret = str_replace("\0", "", $ret);
if (strlen($ret) > 0) {
if ($Decode){
$ret = str_replace("+", "%2B", $ret);
$ret = urldecode($ret);
}
$ret = trim(mb_convert_encoding($ret, $Charset
, $Charset . ", JIS, eucjp-win, sjis-win, utf-8"));
$ret = htmlspecialchars($ret, ENT_QUOTES, $Charset);
$ret = str_replace(''', ''', $ret);
$ret = str_replace('"', '"', $ret);
$ret = str_replace("rn", "n", $ret);
$ret = str_replace("r", "n", $ret);
return $ret;
}
return "";
}
[php language=".ini"][/php]
or [.htaccess] -> php_flag register_globals Off
php.ini または、.htaccessにて、register_globals を off にしてください。
参考:register_globalsとは - はてなダイアリー
戻り値について
外部変数を返します。
返される文字列のうち特殊な文字は次のように変換されています。
' -> '
" -> "
& -> &
<
> -> >
改行文字は、 n です。
詳細は、以下のコードの説明を参考にしてください。
引数について
【$Name】
get, post, cookieで取得する名前を渡します。
$_GET['hoge'], $_POST['hoge'], $_COOKIE['hoge'] の'hoge'の部分です。
【$Type】
大文字・小文字は問いません。
get, post, cookie のいずれかを渡します。
【$Charset = "utf-8"】
省略可能です。省略した場合は、"utf-8"が渡されます。
getOutsideVariable() では、指定した文字コードに変換してreturnします。
utf8, euc, sjis など、変換後のキャラセットを指定します。
なお省略時のutf-8は、php、css、javascriptなどを"utf-8"で統一することを前提にしています。他の文字コードでシステムを構築する場合は、目的にあった初期値に変更します。
【$Decode = false】
省略可能です。省略した場合は、falseが渡されます。
URLエンコード済みの外部変数を取得する時、 true を渡します。省略したデフォルト値は false です。falseでは、urlデコードを行いません。
その外部変数が、URLエンコードを施しているかいないかは、そのシステムの設計者であるあなたにしか分かりません。
getOutsideVariable() 中でやっていること
switch (strtolower($Type)){
$Type を小文字に統一し、続く case で振り分け、get, post, cookie の値を $ret に取得します。
$ret = str_replace("\0", "", $ret);
"" を str_replace で 空文字 に変換します。
理由は、[google] php ヌルバイト攻撃を見てください。
if ($Decode){
$ret = str_replace("+", "%2B", $ret);
$ret = urldecode($ret);
}
URLエンコードされた外部変数を取得するとき、URLデコードします。
javascript の encodeURI() でurlエンコードされた文字列を受信し、PHPのurldecode()でデコードした場合、プラス(+)になるべき文字が半角スペースに置き換わってしまいます。
これはencodeURI()で、+の文字が%2Bにurlエンコードされずに+のまま送信されてしまうことに問題があります。urlエンコードされた半角スペースは +(または%20)で表現されるので、+を半角スペースに置き換えているPHPのurldecode()は正しい処理となります。
この理由により、事前に + を %2B に置き換えたうえで、urldecode()で通常の文字列に戻しています。
$ret = trim(mb_convert_encoding($ret, $Charset
, $Charset . ", JIS, eucjp-win, sjis-win, utf-8"));
指定の文字コードに変換することで文字化けを回避します。
$ret = htmlspecialchars($ret, ENT_QUOTES, $Charset);
$ret = str_replace(''', ''', $ret);
$ret = str_replace('"', '"', $ret);
特殊文字をHTMLエンティティに変換します。
htmlspecialchars()をすると、シングルクォート、ダブルクォートの直前に が付加されるので取り除きます。
$ret = str_replace("rn", "n", $ret);
$ret = str_replace("r", "n", $ret);
通常、windowsは rn、macは r、unixはn、がデフォルトの改行文字となっており、ユーザーのPC(ブラウザ)次第で、どの改行文字が送信されてくるか分かりません。そこで、改行文字を n に統一します。