Regulations

リクエストに関する規約

2008年2月3日

$_GET, $_POST, $_COOKIE 使用時の規約を定めることにした。こうすることで、少ないリソース量で有効なセキュリティ対策が行える。

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');
    }
}

コメント

コメントはありません

コメント送信