我整天都在阅读关于从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
  • 接收方js将值输出到我的html
  • 中的表中

    一切都好吧?不。我正在运行一些测试,发现这可能是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。该分析将以以下两种可能性之一得出结论:

  • 可以在 anchor 标记的href属性内安全地输出URL
  • 无法在 anchor 标记的href属性内安全地输出URL

  • 如果是后者,则将href属性保留为空,或者使用另一个HTML标签,该HTML标签在单击时不会执行某些浏览器操作;一个很好的候选者是span标签。

    需要明确的是,没有额外的工作是不可能的。没有哪个函数可以保留URL的外观,也不能使其在 anchor 中可单击。

    关于javascript - 用户在标签中显示时提交的网址和安全性,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24583752/

    10-12 07:35
    查看更多