我整天都在阅读关于从xss保护我的输出的信息。目前,我正在使用:
htmlspecialchars($str, ENT_QUOTES, 'UTF-8');
当在我的html中显示代码时,它对于防止代码很有用。我遇到了另一个问题,那就是显示可用的网址。
URL是用户提交的,并存储在数据库中。我在插入时使用带有准备好的语句/绑定(bind)的PDO,所以我不必担心SQL注入(inject),而可以在输出和使用这些URL时使用xss。
典型的例子是这样的:
$str = "http://www.example.com/
值,因为它存储在数据库中htmlspecialchars($str, ENT_QUOTES, 'UTF-8');
对其进行转义(默认情况下,我在从db中获取的所有值都执行此操作,因为我在html中显示了大多数值)'<a href="'.$str.'" data-window="external"><i class="fa fa-external-link"></i> '.$str.'</a>'
,其中$ str已被转义json_encode(array of all the values)
传递给js 一切都好吧?不。我正在运行一些测试,发现这可能是xss。这是一个测试值,当在生成的html表中单击时,显示js警报:
javascript://%0Aalert('XSS');
因此,除了在数据库插入时对此进行过滤之外(出于显示目的,我仍然希望完全按照db的显示方式进行显示)...如何防止在此出现xss?我今天读了很多东西,但是很多人都提到了urlencode,但这不是完整的URL。其他人提到了FILTER_VALIDATE_URL,但是,这似乎一点也不奏效。
有没有办法显示该网址,从而阻止该网址实际运行(xss运行)?
编辑:
好的,因此研究一下给定的“dupe”可以提供以下解决方案:
$url = 'http://username:password@hostname/path?arg=value#anchor';
$tmp = parse_url($url);
if ($tmp['scheme'] === 'http') {
echo 'is http://';
}
if (in_array($tmp['scheme'], array('http', 'skype', 'call')) {
echo 'is allowed protocol';
}
在这种情况下,实际上并不能解决我的问题,因为我希望按原样显示,只需确保链接不起作用即可。看来这似乎是不可能的。
关于上述解决方案,似乎答案是对数据库输入进行过滤,因此,作为协议(protocol)的javascript永远不会输入到数据库中,或者当触发此协议(protocol)时,我会显示“错误”消息而不是实际的url。
还有其他想法或可能性吗?
最佳答案
是的,有:请勿将其放在 anchor 标记中。如果过滤URL就像通过本机PHP函数传递一样容易,它可以神奇地在可点击的 anchor 标记中显示一种类型的URL,而在 anchor 标记中不可显示另一种URL,则XSS将被降级为PHP Web的脚注应用程序安全性,即使是那样。
您必须在输出之前分析每个URL。该分析将以以下两种可能性之一得出结论:
href
属性内安全地输出URL 。 href
属性内安全地输出URL 。 如果是后者,则将
href
属性保留为空,或者使用另一个HTML标签,该HTML标签在单击时不会执行某些浏览器操作;一个很好的候选者是span
标签。需要明确的是,没有额外的工作是不可能的。没有哪个函数可以保留URL的外观,也不能使其在 anchor 中可单击。
关于javascript - 用户在标签中显示时提交的网址和安全性,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24583752/