- 2009-04-19 日 22:01:58
- PHP
スパム投稿の特徴を見つけ出すのに、どんな値を
ログに記録してたらいいのか試行錯誤してたところ、
PHPがあらかじめ用意してくれるスーパーグローバル変数
$_SERVER
の中でキーが HTTP_
で始まるものが
クライアントが送信してきた値だとつい最近知りました。
よく Proxy が付加してくる Via
や X-Forwarded-For
など
全て大文字で、-
(ハイフン)は _
(アンダーバー) に変換され
こんなキーで得られます。
$_SERVER[‘HTTP_VIA’]
$_SERVER[‘HTTP_X_FORWARDED_FOR ‘]
そこでクライアントの値をこんな関数にまとめてみました。
function getClientParams () { $params = array(); $params['time'] = (isset($_SERVER['REQUEST_TIME'])) ? $_SERVER['REQUEST_TIME']: time(); $params['addr'] = $_SERVER['REMOTE_ADDR']; $params['port'] = $_SERVER['REMOTE_PORT']; $params['user'] = (isset($_SERVER['REMOTE_USER'])) ? $_SERVER['REMOTE_USER']: ''; $params['method'] = $_SERVER['REQUEST_METHOD']; $params['uri'] = $_SERVER['REQUEST_URI']; $params['protocol'] = $_SERVER['SERVER_PROTOCOL']; $http = array(); foreach ($_SERVER as $key => $val) { if ('HTTP_' === substr($key, 0, 5)) $http[substr($key, 5)] = $val; } if (count($http)) $params['http'] = $http; return $params; }
でもって、ログには serialize して記録。
$filename = '/home/userdir/logs/spam.log'; error_log(serialize(getClientParams()).PHP_EOL, 3, $filename);
1行1レコードになってるので読み出すときはこんな具合。
/** * Callback unserialize */ function __callback_unserialize ( &$record, $key ) { $record = unserialize(trim($record)); } /** * Load serialized file */ function loadSerialize ( $filename ) { $records = file($filename); if (!isset($records[0])) return null; array_walk($records, '__callback_unserialize')); return $records; } $filename = '/home/userdir/logs/spam.log'; $records = loadSerialize($filename); var_export($records);
- 新しい: SQLインジェクション発見
- 古い: auto_prepend_fileで役割分担