[PHP-users 15448]$HTTP_POST_VARSなどをarray_map()で処理する場合の問題について

Osamu Shigematsu m5issige @ mr.hitachi-medical.co.jp
2003年 5月 22日 (木) 19:05:58 JST


こんにちは。重松です。

(かなり振りが長いのですが。。。)
GET/POST/Cookie のデータをまとめて sanitize する必要があります。
この処理は、以下の要件を満たせればと思っています。

	- PHP 4 以降でなるべく幅広く使用可能
	- $HTTP_GET_VARS ...etc を使う
	- magic_quotes_gpc の設定に依存しない (強制 OFF)

(pukiwiki init.php 1.42 2003/04/30 より引用)

    137 /////////////////////////////////////////////////
    138 // 入力値の整形
    139 if (get_magic_quotes_gpc()) {
    140     $get = $post = $cookie = array();
    141     foreach($HTTP_GET_VARS as $key => $value) {
    142         if (!is_array($value)) {
    143             $get[$key] = stripslashes($value);
    144         }
    145     }
    146     foreach($HTTP_POST_VARS as $key => $value) {
    147         $post[$key] = stripslashes($value);
    148     }
    149     foreach($HTTP_COOKIE_VARS as $key => $value) {
    150         $cookie[$key] = stripslashes($value);
    151     }
    152 }
    153 else {
    154     $post = is_array($HTTP_POST_VARS) ? $HTTP_POST_VARS : array();
    155     $get = is_array($HTTP_GET_VARS) ? $HTTP_GET_VARS : array();
    156     $cookie = is_array($HTTP_COOKIE_VARS) ? $HTTP_COOKIE_VARS : array();
    157 }

上記、pukiwiki のコードを参考にしようと思いましたが、
foreach を使っているので低速ですし、
それ以前の問題として、配列の入れ子に対処していないと思ます。

このことは、NULL byte attack 脆弱性 (GET)、
データの破損 (POST/Cookie) を意味すると思います。

汎用ではないのだから、仕方ないのかもしれませんが、
自作する必要がでてきました。

そこで、

<?php
// dump.cgi
header('Content-type: plain/text');
var_dump($HTTP_GET_VARS);
?>

というスクリプトを用意して、コマンドラインから、

	$ w3m http://localhost/dump.cgi?x[][][]=x

として簡単に配列を入れ子にできることは確認できました。
# php3 だとできなかったと記憶しています。

また、

	$ w3m http://localhost/dump.cgi?

では、空配列、

	$ w3m http://localhost/dump.cgi?x

では、x がキーで、データが空の配列が返され、
常に配列であることを確認しました。

また、マニュアルには明記されていないようですが、array_map() は
配列が入れ子になっていても、すべての配列でない要素に対して、
再帰的に指定された関数を呼び出すようです。
(PHP 4.3.2RC2 でテストしました)

[PHP-users 10914] からのスレッドを踏まえると、foreach に対し、
array_map() を使用するのは、速度の面でも大きなアドバンテージがあります。

以上の私の環境に基づく事実、

	(1) $HTTP_XXX_VARS は常に配列
	(2) array_map() は高速で、入れ子の問題も解決

から、array_map() を使いたいと思ったのですが、
[PHP-users 13915] からの一連のスレッドを見ると、array_map() は
参照渡し仕様上できない、ということのようです。

振りが大変長くなりましたが、

(1), (2) は、そうであると期待して差し障りはありませんか?
$HTTP_GET_VARS あたりは、値渡しで、上書きは可能でしょうか?
それとも、一旦コピーをとる必要があるのでしょうか?

実際には以下のコードで処理したいと考えています。
アドバイスよろしくお願いいたします。

function remove_null($str) {
	return str_replace("\0", ``, $str);
}

function sanitize($ary) {
	if (get_magic_quotes_gpc()) {
		$ary = array_map('stripslashes', $ary);
	}
	return array_map('remove_null', $ary);
}

$get = sanitize($HTTP_GET_VARS); // 値渡しになる?

-- 
Osamu Shigematsu <m5issige @ mr.hitachi-medical.co.jp>



PHP-users メーリングリストの案内