リクエストに関する規約
2008年2月3日
$_GET, $_POST, $_COOKIE 使用時の規約を定めることにした。こうすることで、少ないリソース量で有効なセキュリティ対策が行える。
1)キー名が『binary』で終わる場合以外は、ヌルバイトは使用禁止。
2)キー名が『id』で終わる場合は、数値のみを利用。
3)キー名が『path』で終わる場合、URLもしくはファイルなどのパスを指定できる。ただし、日本語使用不可。
4)キー名が『text』で終わる場合、ヌルバイト以外なら何でも使用可。
5)上のどれにも当てはまらない場合、英数字、ピリオド、ハイフン、アンダースコア、スラッシュおよび日本語のみが使用可能。
6)URIに『#』および2つ以上の『?』を含むものを禁止。
(080208 改定)
キー名が『binary』で終わる場合に、ヌルバイトを受け付けるようにした。また、6)の条件を追加した。
coreクラスにおける、該当部分のコードは以下のとおり。
1)キー名が『binary』で終わる場合以外は、ヌルバイトは使用禁止。
2)キー名が『id』で終わる場合は、数値のみを利用。
3)キー名が『path』で終わる場合、URLもしくはファイルなどのパスを指定できる。ただし、日本語使用不可。
4)キー名が『text』で終わる場合、ヌルバイト以外なら何でも使用可。
5)上のどれにも当てはまらない場合、英数字、ピリオド、ハイフン、アンダースコア、スラッシュおよび日本語のみが使用可能。
6)URIに『#』および2つ以上の『?』を含むものを禁止。
(080208 改定)
キー名が『binary』で終わる場合に、ヌルバイトを受け付けるようにした。また、6)の条件を追加した。
coreクラスにおける、該当部分のコードは以下のとおり。
private function forSecurity(){ // Remove unnecessary cookie settings foreach($_COOKIE as $key=>$value) { if (strpos($key,_CONF_COOKIEPREFIX)===0) continue; unset($_COOKIE[$key]); unset($_REQUEST[$key]); } // Check NULL byte in string. self::checkRequest($_REQUEST); // Remove $_COOKIE keys in $_REQUEST // This is for avoiding bugs due to cookie keys. foreach($_COOKIE as $key=>$value) unset($_REQUEST[$key]); // Send content-type with character set anyway, to avoid XSS by invalid character like UTF-7. @header('Content-Type: text/html; charset=iso-8859-1'); // MISC if (!empty($_SERVER['HTTP_REFERER'])) { if (!preg_match('!^(http|https|ftp)://!',$_SERVER['HTTP_REFERER'])) unset($_SERVER['HTTP_REFERER']); } if (preg_match('/(#|\?[^\?]*\?)/',$_SERVER['REQUEST_URI'])) { exit("<html><body>URI shouldn't contain '#' and 2x'?'. Please check the browser/robot setting.</body></html>"); } } private function checkRequest(&$request,$requestkey=null){ if (is_array($request)) { foreach($request as $key=>&$value) self::checkRequest($value,$requestkey===null?$key:$requestkey); } else { if (preg_match('/binary$/i',$requestkey)) return; elseif (strpos($request,"\0")!==false) exit('Null byte cannot be used.'); switch(true){ case preg_match('/text$/i',$requestkey): return; case preg_match('/id$/i',$requestkey): if (is_numeric($request)) return; else break; case preg_match('/path$/i',$requestkey): if (preg_match('/^([0-9a-zA-Z\x80-\xFF\-_\.:\/\\]*)$/',$request)) return; else break; default: if (preg_match('/^([0-9a-zA-Z\x80-\xFF\-_\.\/]*)$/',$request)) return; else break; } exit('Request type mismatch'); } }