xss过滤方法

用的白名单过滤,是我们的论坛自用的方法,也许考虑不周,欢迎来黑我们的论坛!
https://www.ebcms.com/forum.html

// 安全过滤
function safe_html($html){
    $elements = [
        'html'      =>  [],
        'body'      =>  [],
        'a'         =>  ['target', 'href', 'title', 'class', 'style'],
        'abbr'      =>  ['title', 'class', 'style'],
        'address'   =>  ['class', 'style'],
        'area'      =>  ['shape', 'coords', 'href', 'alt'],
        'article'   =>  [],
        'aside'     =>  [],
        'audio'     =>  ['autoplay', 'controls', 'loop', 'preload', 'src', 'class', 'style'],
        'b'         =>  ['class', 'style'],
        'bdi'       =>  ['dir'],
        'bdo'       =>  ['dir'],
        'big'       =>  [],
        'blockquote'=>  ['cite', 'class', 'style'],
        'br'        =>  [],
        'caption'   =>  ['class', 'style'],
        'center'    =>  [],
        'cite'      =>  [],
        'code'      =>  ['class', 'style'],
        'col'       =>  ['align', 'valign', 'span', 'width', 'class', 'style'],
        'colgroup'  =>  ['align', 'valign', 'span', 'width', 'class', 'style'],
        'dd'        =>  ['class', 'style'],
        'del'       =>  ['datetime'],
        'details'   =>  ['open'],
        'div'       =>  ['class', 'style'],
        'dl'        =>  ['class', 'style'],
        'dt'        =>  ['class', 'style'],
        'em'        =>  ['class', 'style'],
        'font'      =>  ['color', 'size', 'face'],
        'footer'    =>  [],
        'h1'        =>  ['class', 'style'],
        'h2'        =>  ['class', 'style'],
        'h3'        =>  ['class', 'style'],
        'h4'        =>  ['class', 'style'],
        'h5'        =>  ['class', 'style'],
        'h6'        =>  ['class', 'style'],
        'header'    =>  [],
        'hr'        =>  [],
        'i'         =>  ['class', 'style'],
        'img'       =>  ['src', 'alt', 'title', 'width', 'height', 'id', 'class'],
        'ins'       =>  ['datetime'],
        'li'        =>  ['class', 'style'],
        'mark'      =>  [],
        'nav'       =>  [],
        'ol'        =>  ['class', 'style'],
        'p'         =>  ['class', 'style'],
        'pre'       =>  ['class', 'style'],
        's'         =>  [],
        'section'   =>  [],
        'small'     =>  [],
        'span'      =>  ['class', 'style'],
        'sub'       =>  ['class', 'style'],
        'sup'       =>  ['class', 'style'],
        'strong'    =>  ['class', 'style'],
        'table'     =>  ['width', 'border', 'align', 'valign', 'class', 'style'],
        'tbody'     =>  ['align', 'valign', 'class', 'style'],
        'td'        =>  ['width', 'rowspan', 'colspan', 'align', 'valign', 'class', 'style'],
        'tfoot'     =>  ['align', 'valign', 'class', 'style'],
        'th'        =>  ['width', 'rowspan', 'colspan', 'align', 'valign', 'class', 'style'],
        'thead'     =>  ['align', 'valign', 'class', 'style'],
        'tr'        =>  ['rowspan', 'align', 'valign', 'class', 'style'],
        'tt'        =>  [],
        'u'         =>  [],
        'ul'        =>  ['class', 'style'],
        'video'     =>  ['autoplay', 'controls', 'loop', 'preload', 'src', 'height', 'width', 'class', 'style'],
        'embed'     =>  ['src', 'height','align', 'width', 'class', 'style','type','pluginspage','wmode','play','loop','menu','allowscriptaccess','allowfullscreen'],
        'source'    =>  ['src', 'type']
    ];
    $html = strip_tags($html,'<'.implode('><', array_keys($elements)).'>');
    $xml = new DOMDocument();
    libxml_use_internal_errors(true);
    if (!strlen($html)){
        return '';
    }
    if ($xml->loadHTML('<meta http-equiv="Content-Type" content="text/html; charset=utf-8">' . $html)){
        foreach ($xml->getElementsByTagName("*") as $element){
            if (!isset($elements[$element->tagName])){
                $element->parentNode->removeChild($element);
            }else{
                for ($k = $element->attributes->length - 1; $k >= 0; --$k) {
                    if (!in_array($element->attributes->item($k) -> nodeName, $elements[$element->tagName])){
                        $element->removeAttributeNode($element->attributes->item($k));
                    }elseif (in_array($element->attributes->item($k) -> nodeName, ['href','src','style','background','size'])) {
                        $_keywords = ['javascript:','javascript.:','vbscript:','vbscript.:',':expression'];
                        $find = false;
                        foreach ($_keywords as $a => $b) {
                            if (false !== strpos(strtolower($element->attributes->item($k)->nodeValue),$b)) {
                                $find = true;
                            }
                        }
                        if ($find) {
                            $element->removeAttributeNode($element->attributes->item($k));
                        }
                    }
                }
            }
        }
    }
    $html = substr($xml->saveHTML($xml->documentElement), 12, -14);
    $html = strip_tags($html,'<'.implode('><', array_keys($elements)).'>');
    return $html;
}

当然 还有一种漏洞就是url权限操作链接,可能引起版主误操作。

原文地址:https://www.cnblogs.com/bluealine/p/11040905.html