PHP中的用户输入过滤
-
06-07-2019 - |
题
我目前正在处理一项要求用户提交网站上显示的帖子和评论的应用程序。众所周知,用户输入不可信,所以我使用htmlspecialchars($ string,ENT_QUOTES)来处理用户的帖子和评论。
现在,我想要忽略某些某些html标签。例如<b><br />
和更多标签。我怎么能这样做,以便htmlspecialchars在过滤其他标签时忽略某些标签。
解决方案
解决方案a)
使用htmlspecialchars的strip_tags,并将所需的标签列入白名单。
更好的解决方案b)
使用bbcodes,并为所需标签提供别名,例如:[b]粗体[/ b]
其他提示
由于当前的HTML过滤器不完整或不安全,使用BBCode很累?- <!> gt; HTML Purifier
HTML Purifier是一个用PHP编写的符合标准的HTML过滤器库。 HTML Purifier不仅会删除所有恶意代码(更好地称为XSS),而且还需要经过全面审核,安全且宽松的白名单,...
您可以替换带引号的字符串以重新插入允许的标记。例如:<b>
标签:
$string = str_replace(array('<b>', </>), array('<b>', '</b>'), $string);
我只允许非常独特,完整的标签尽可能安全。即如果你不必使用正则表达式,它可能导致非常讨厌的错误。
我强烈建议你使用Zend_Filter来过滤用户输入。具体来说,请看: http://framework.zend.com/手动/ EN / zend.filter.html#zend.filter.introduction.using
这并不像你想象的那样简单,因为 htmlspecialchars()
或 htmlentities()
提供忽略某些选项的任何选项标签(这两个函数甚至不知道标签概念的含义)。
您可以使用其他一些方法来允许用户格式化自己的帖子,例如: BBCode ,纺织品或 Markdown 。有适用于所有这些的PHP解析器。
如果您必须坚持使用html标签,您可以采用一些预处理来重新格式化允许的标签,以便它们不会受到 <a>
。然后,您可以对结果进行后处理,以将格式更改回普通的HTML标记。以下示例将此过程可视化为一个简单的<=> - 标记。请注意,使用正则表达式处理HTML是容易出错的,并不总是可行的方法 - 我将在本例中仅为了简单起见而使用它。
$input = preg_replace('~<(/?\w+([^>]*?))>~', '|#$1#|', $input);
$input = htmlspecialchars($input);
$inoput = preg_replace('~|#(/?\w+(.*?))#|~', '<$1>', $input);
这是未经测试的,肯定需要做更多的工作。