用户在标记中显示时提交的URL和安全性

时间:2014-07-05 06:40:32

标签: javascript php xss

我整天都在阅读有关保护xss输出的信息。目前我正在使用:

htmlspecialchars($str, ENT_QUOTES, 'UTF-8');

它在我的html中显示时防止代码效果很好。我遇到了另一个问题,那就是显示可用的网址。

网址是用户提交并存储在数据库中。我在插入时使用带有预处理语句/绑定的PDO,所以我不担心SQL注入,而是输出和使用这些URL时的xss。

典型的例子就是这样:

  1. $str = "http://www.example.com/值,因为它存储在数据库中
  2. 我运行htmlspecialchars($str, ENT_QUOTES, 'UTF-8');来逃避它(默认情况下,我在数据库中获取所有值,因为我在html中显示了大部分值)
  3. 格式为'<a href="'.$str.'" data-window="external"><i class="fa fa-external-link"></i> '.$str.'</a>',其中$ str已被转义
  4. json_encode(array of all the values)
  5. 传递给js
  6. 接收js将值输出到我的html
  7. 中的表格

    一切都好吗?不。我正在运行一些测试,发现这个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>

    还有其他想法或可能吗?

1 个答案:

答案 0 :(得分:0)

  

是否无法显示,但阻止网址实际工作(xss工作)?

是的,有:不要将其放在锚标记中。如果过滤URL就像通过本机PHP函数一样简单,它可以在可点击的锚标记中神奇地显示一种类型的URL,而另一种类型的URL在锚标记中无法点击,XSS将被降级为PHP Web的脚注应用程序安全性,即便如此。

您必须在输出之前分析每个网址。这种分析将以两种可能性之一结束:

  1. 可以在锚标记的href属性中安全地输出网址
  2. 网址无法在锚标记的href属性中安全输出。
  3. 如果是后者,请将href属性设置为空,或者使用另一个HTML标签,该标签在单击时不会执行某些浏览器操作;一个好的候选者是span标签。

    要明确的是,如果没有额外的工作,你无法做到这一点。没有任何一个函数可以保留URL的外观,也不会使其在锚点中可单击。