【问题标题】:Apply htmlentities to stripped tags将 htmlentities 应用于剥离的标签
【发布时间】:2016-05-09 08:09:02
【问题描述】:

研究链接:

How do you apply htmlentities selectively?PHP function to strip tags, except a list of whitelisted tags and attributes

它们很接近,但并不像预期的那样。

我尝试了什么?

<?php
define('CHARSET', 'UTF-8');
define('REPLACE_FLAGS', ENT_HTML5);

function htmlcleaned($string) {
    $string = htmlentities($string);
    return str_replace(
    array("&lt;i&gt;", "&lt;b&gt;", "&lt;/i&gt;", "&lt;/b&gt;", "&lt;p&gt;", "&lt;/p&gt;"),
    array("<i>", "<b>", "</i>", "</b>", "<p>", "</p>"), $string);
}

echo htmlcleaned("<p>How are you?</p><p><b>This is bold</b></p><p><i>This is italic</i></p><p><u>This is underline</u></p><p><br></p><ul><li>This is list item 1</li><li>This is list item 2</li></ul><p><br></p><ol><li>This is ordered list item 1</li><li>This is ordered list item 2</li></ol><p><a target='_blank' style='color: #1c5c76;' href='http://www.google.com'>http://www.google.com</a></p><p>This is plain text again.<br></p><script>alert('attempt csrf');</script><p><p>This is P tag example</p></p>");
?>

我想达到什么目标?

如果输入是:

<b><script>alert("something");</script></b>

那么输出将是:

<b>&lt;script&rt;("something");&lt;/script$rt;</b>

没有具体的黑名单,但有具体的白名单。

【问题讨论】:

  • 如果第二个链接包含您可以尝试调整的解决方案,您出于什么原因列出了“研究链接”?
  • @MarcinOrlowski 再读一遍我的问题,你可能知道:)
  • @deceze 谢谢。我可能会寻找 DOMDocument...

标签: php regex html-entities strip-tags


【解决方案1】:

此功能可能会对您有所帮助,它没有经过高度测试。它将在除您指定的标签之外的所有标签上执行 htmlentities

function html_entity_decode_matches($matches){
    return html_entity_decode($matches[0]); 
}
function htmlentities_exclude($string, $exclude_array){
    $string = htmlentities($string); //htmlentities all
    $ent_sl = "&gt;"; //>
    if (is_array($exclude_array) AND !empty($exclude_array)){
        foreach($exclude_array as $exc){
            $exc = str_replace(array("<", ">"), "", $exc);
            $ent = str_replace("/", "\/", htmlentities("<{$exc}"));
            $ent_e = str_replace("/", "\/", htmlentities("</{$exc}>"));
            //do decode on <tag...>
            $string = preg_replace_callback("/{$ent}(.*?){$ent_sl}/", "html_entity_decode_matches", $string);
            //do decode on <\tag>
            $string = preg_replace_callback("/{$ent_e}/", "html_entity_decode_matches", $string);
        }
    }
    return $string;
}

echo htmlentities_exclude('<b><script>alert("something");</script></b>', array("<b>"));

Output:
<b>&lt;script&gt;alert(&quot;something&quot;);&lt;/script&gt;</b>

【讨论】:

    【解决方案2】:

    您可以使用 PHP DOM 对象来实现这一点,首先您创建一个元素(在您的情况下是 )并提供编码字符串作为其主体(内部 HTML),如下所示,

        <?php
            define('CHARSET', 'UTF-8');
            define('REPLACE_FLAGS', ENT_HTML5);
            function htmlcleaned($string) {
                return str_replace(array("<", ">"), array("&lt;", "&gt;"), $string);
            }
            $dom = new DOMDocument('1.0', 'utf-8');
            $element = $dom->createElement('b', htmlcleaned('<script>alert("something");</script>'));
            $dom->appendChild($element);
            $html = $dom->saveXML();
            echo $html;
        ?>
    

    您可以使用内置函数而不是创建这样的函数,

    <?php
        define('CHARSET', 'UTF-8');
        define('REPLACE_FLAGS', ENT_HTML5);
        $dom = new DOMDocument('1.0', 'utf-8');
        $element = $dom->createElement('b', htmlspecialchars('<script>alert("something");</script>', ENT_NOQUOTES));
        $dom->appendChild($element);
        $html = $dom->saveXML();
        echo $html;
    ?>
    

    【讨论】:

    • 好答案.. 但是它更像是清理用户输入...但是如果
    猜你喜欢
    • 2012-05-27
    • 2014-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多