@blog.justoneplanet.info

日々勉強

XSSを防ごう(PHP)

関数htmlSanitizingは、1番目の引数に無害化したい文字列、2番目の引数は属性値用にするかどうか(true=する、false=しない)を指定すると、無害化した文字列が返る。ちなみにタグは全削除されるようにしてます。

■サンプルソース

<?php
/**
* sanitize for html
* @return (string) converted string for HTML
*/
function htmlSanitizing($value, $attribute = false){
    if(!is_array($value)){
        if($attribute === true){
            if(preg_match('/^javascript:/i', preg_replace('/[\x00-\x20\x22\x27]/', '', $value))){
                $value = preg_replace('/^javascript:/i', '',preg_replace('/[\x00-\x20\x22\x27]/', '', $value));
            }
            $value = htmlspecialchars(strip_tags($value), ENT_QUOTES);
            return $value;
        }
        else{
            $value = htmlspecialchars(strip_tags($value), ENT_QUOTES);
            return $value;
        }
    }
    else{
        foreach($value as $key => &amp;$val){
            $val = htmlSanitizing($val, $attribute);
        }
        unset($val);
        return $value;
    }
}
?>

■おまけ

再帰してるところで、array_mapを使おうとしたのだが、var_dumpをしたところ、連想配列のキーが削除されてしまったので、foreachとリファレンス(参照渡し)で代用することにした。

■追記

/**
* sanitize for html
* @return (string) converted string for HTML
* @param (array)
*        [attribute] => (bool)
*        [striptags] => (bool)
*        [escape] => (string) 'entities' or 'chars'
*        [quotes] => ENT_COMPAT, ENT_QUOTES or ENT_NOQUOTES
*/
function htmlSanitizing($value, $arg = array()){
    if(!is_array($value)){
        $attribute = (isset($arg['attribute']) && $arg['attribute'] === true)? true : false;
        $striptags = (isset($arg['striptags']) && $arg['striptags'] === true)? true : false;
        $escape = (isset($arg['escape']) && $arg['escape'] === 'entities')? 'entities' : 'chars';
        $quotes = (isset($arg['quotes']) && $arg['quotes'] !== '')?     $arg['quotes'] : ENT_QUOTES;
        $value = ($striptags)? strip_tags($value) : $value;
        $value = ($escape === 'entities')? htmlentities($value, $quotes) : htmlspecialchars($value, $quotes);
        if($attribute){
            if(preg_match('/^javascript:/i', preg_replace('/[\x00-\x20\x22\x27]/', '', $value))){
                $value = preg_replace('/^javascript:/i', '',preg_replace('/[\x00-\x20\x22\x27]/', '', $value));
            }
        }
        return $value;
    }
    else{
        foreach($value as $key => &$val){
            $val = htmlSanitizing($val, $arg);
        }
        unset($val);
        return $value;
    }
}

コメントの返事を書いてる時に、いろいろと考えてみまっしたー。。。三項演算子が嫌いな方はいるかもしれませぬが、こんなんドウでしょうか?