【发布时间】:2014-03-14 14:18:34
【问题描述】:
假设我有一个来自用户 ($input) 的字符串。我可以去strip tags,只允许允许的标签进入。我可以使用htmlspecialchars() 转换为文本。我什至可以用文本替换所有我不想要的标签。
function html($input) {
$input = '<bl>'.htmlspecialchars($input).'</bl>'; // bl is a custom tag that I style (stands for block)
global $open;
$open = []; //Array of open tags
for ($i = 0; $i < strlen($input); $i++) {
if (!in_array('code', $open) && !in_array('codebl', $open)) { //If we are parsing
$input = preg_replace_callback('#^(.{'.$i.'})<(em|i|del|sub|sup|sml|code|kbd|pre|codebl|quote|bl|sbl)>\s*#s', function($match) {
global $open; //...then add new tags to the array
array_push($open,$match[2]);
return $match[1].'<'.$match[2].'>'; //And replace them
}, $input);
$input = preg_replace_callback('#^(.{'.$i.'})(https?):\/\/([^\s"\(\)<>]+)#', function($m) {
return $m[1].'<a href="'.$m[2].'://'.$m[3].'" target="_blank">'.$m[3].'</a>';
}, $input, -1, $num); //Simple linking
$i += $num * 9;
$input = preg_replace_callback('#^(.{'.$i.'})\n\n#', function($m) {
return $m[1].'</bl><bl>';
}, $input); // More of this bl element
}
if (end($open)) { //Close tags
$input = preg_replace_callback('#^(.{'.$i.'})</('.end($open).')>#s', function($match) {
global $open;
array_pop($open);
return trim($match[1]).'</'.$match[2].'>';
}, $input);
}
}
while ($open) { //Handle unclosed tags
$input .= '</'.end($open).'>';
array_pop($open);
}
return $input;
}
问题是,在那之后,就没有办法直接写&lt;i&lgt;&lt;/i&gt;,因为它会自动解析成<i></i>(如果你写<i></i>)或&amplt;i&ampgt;&amplt;/i&ampgt;(如果你写@ 987654331@)。我希望用户能够输入 &lt;(或任何其他 HTML 实体)并返回 &lt;。如果我只是将其直接发送到未解析的浏览器,它将(显然)容易受到黑客正在尝试(并且我让)放置在我的网站上的任何巫术的攻击。那么,我怎样才能让用户使用任何预定义的 HTML 标签集,同时仍然让他们使用 html 实体?
【问题讨论】:
-
改用 HTMLPurifier。 striptags 是核弹,htmlpurifier 可以是手术刀(但也支持核武器)。
-
查看此链接 [stackoverflow.com][1] [stackoverflow.com][2] [1]:stackoverflow.com/questions/1732348/… [2]:stackoverflow.com/questions/3577641/…
-
@Mortzea 你的链接太丑了……好吧,它们很有帮助。
标签: php html validation parsing user-generated-content