我整天都在阅读有关保护xss输出的信息。目前我正在使用:
htmlspecialchars($str, ENT_QUOTES, 'UTF-8');
它在我的html中显示时防止代码效果很好。我遇到了另一个问题,那就是显示可用的网址。
网址是用户提交并存储在数据库中。我在插入时使用带有预处理语句/绑定的PDO,所以我不担心SQL注入,而是输出和使用这些URL时的xss。
典型的例子就是这样:
$str = "http://www.example.com/
值,因为它存储在数据库中htmlspecialchars($str, ENT_QUOTES, 'UTF-8');
来逃避它(默认情况下,我在数据库中获取所有值,因为我在html中显示了大部分值)'<a href="'.$str.'" data-window="external"><i class="fa fa-external-link"></i> '.$str.'</a>'
,其中$ str已被转义json_encode(array of all the values)
一切都好吗?不。我正在运行一些测试,发现这个xss是可能的。这是一个测试值,显示在生成的html表中单击时的js警告:
javascript://%0Aalert('XSS');
因此,除了在数据库插入时过滤此内容(我仍然希望完全按照数据库中的显示进行显示)...如何在此处阻止xss?我今天已经阅读了很多东西,很多都提到了urlencode,但是,这不是完整的网址。其他人提到了FILTER_VALIDATE_URL,但是,它似乎根本不起作用。
是否无法显示,但阻止网址实际工作(xss工作)?
修改
好的,所以看看我被给予的“欺骗”它提供了以下解决方案:
$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';
}
在这种情况下,它确实没有解决我的问题,因为我最好想要按原样显示,只是确保链接不起作用。这似乎开始似乎不可能。
关于上面的解决方案,似乎答案是过滤数据库输入,因此javascript作为协议永远不会进入数据库,或者我触发此协议时显示“错误”消息而不是实际网址。 / p>
还有其他想法或可能吗?
答案 0 :(得分:0)
是否无法显示,但阻止网址实际工作(xss工作)?
是的,有:不要将其放在锚标记中。如果过滤URL就像通过本机PHP函数一样简单,它可以在可点击的锚标记中神奇地显示一种类型的URL,而另一种类型的URL在锚标记中无法点击,XSS将被降级为PHP Web的脚注应用程序安全性,即便如此。
您必须在输出之前分析每个网址。这种分析将以两种可能性之一结束:
href
属性中安全地输出网址 。href
属性中安全输出。如果是后者,请将href
属性设置为空,或者使用另一个HTML标签,该标签在单击时不会执行某些浏览器操作;一个好的候选者是span
标签。
要明确的是,如果没有额外的工作,你无法做到这一点。没有任何一个函数可以保留URL的外观,也不会使其在锚点中可单击。