【问题标题】:XSS keep script tag and avoid attack - why aren't reliableXSS 保留脚本标签并避免攻击 - 为什么不可靠
【发布时间】:2013-08-29 15:42:15
【问题描述】:

我在网上有一些关于 XSS 攻击预防的文章,但我没有找到任何解决方案:

htmlspecialchars(mb_convert_encoding($value, "UTF-8", "UTF-8"),ENT_QUOTES,'UTF-8')

json_encode($value, JSON_HEX_QUOT|JSON_HEX_TAG|JSON_HEX_AMP|JSON_HEX_APOS);

或者干脆strip_tags
此时我每次需要检索和显示一些信息时都会使用这些方法,除了消息,因为它破坏了格式


我需要做的是防止这种情况的XSS攻击:

  • 我有一个上传表单,如果有任何错误,它会返回名称并提醒它;

    echo '<script>parent.noty({text: "File Name:'.json_encode($_FILES['filename']['name'][$i]).' Error Code:'.$_FILES['filename']['error'][$i].'",type:"error",timeout:9000});</script>';
    
  • 用户可以写可以包含h​​tml标签的消息,比如脚本一,我需要保留:我用ckeditor写新消息,当我检索消息时我需要主要格式(

    ...) 保留并使脚本部分无臂

此时我返回文件名时我使用json_encode,但我不确定
编辑
从我得到的 cmets 中我得到的可能性并不多,所以我想知道为什么这些方法不可靠
编辑
这就是我检索消息的方式:

$query = "SELECT 
                    a.enc_id,
                    IF(b.department_name IS NOT NULL, b.department_name,'Unknown'),
                    IF(c.name IS NOT NULL, c.name,IF(a.ticket_status='2','Not Assigned','Unknown'),
                    a.title,
                    CASE a.priority WHEN '0' THEN 'Low' WHEN '1' THEN 'Medium' WHEN '2' THEN 'High' WHEN '3' THEN 'Urgent' WHEN '4' THEN 'Critical' ELSE priority  END,
                    a.created_time,
                    a.last_reply,
                    CASE a.ticket_status WHEN '0' THEN '<span class=\'label label-success\'>Closed</span>' WHEN '1' THEN '<span class=\'label label-important\'>Open</span>' WHEN '2' THEN '<span class=\'label label-warning\'>To Assign</span>' WHEN '3' THEN '<span class=\'label label-important\'>Reported</span>' ELSE 'Error' END 
                FROM ".$SupportTicketsTable." a
                LEFT JOIN ".$SupportDepaTable." b
                    ON  b.id=a.department_id
                LEFT JOIN ".$SupportUserTable." c
                    ON c.id=a.operator_id
                WHERE a.user_id=".$_SESSION['id']." 
                ORDER BY a.last_reply DESC 
                LIMIT 350";
        $STH = $DBH->prepare($query);
        $STH->execute();
        $list=array('response'=>'ret','tickets'=>array('user'=>array()));
        $STH->setFetchMode(PDO::FETCH_ASSOC);
        $a = $STH->fetch();
        if(!empty($a)){
            do{
                $list['tickets']['user'][]=array('id'=>$a['enc_id'],'dname'=>$a['dname'],'opname'=>$a['opname'],'title'=>htmlspecialchars(mb_convert_encoding($a['title'], "UTF-8", "UTF-8"),ENT_QUOTES,'UTF-8'),'priority'=>$a['prio'],'date'=>$a['created_time'],'reply'=>$a['last_reply'],'status'=>$a['stat']);
            }while ($a = $STH->fetch());
        }
...
echo json_encode($list);

【问题讨论】:

  • 你现在的问题是下一个要预订的安全顾问在哪里或什么?
  • 如果你允许用户添加&amp;lt;script&amp;gt; 标签,那么你就完蛋了。除非你构建了一个成熟的人工智能系统,可以分析脚本、任何语言、所有情况下的每一个可能的动作,否则某些事情会通过并弄乱你的系统。
  • 因为它们输出的是&amp;lt;script&amp;gt;,而不是&amp;lt;script&amp;gt;,所以实际代码永远不会进入浏览器将其视为“可执行”的上下文。
  • SO 不是用 php 编写的,所以不......他们不使用它。

标签: php xss


【解决方案1】:

在这种特殊情况下,转义内容的正确方法如下:

echo '...{text: "File Name:"+'.json_encode($_FILES['filename']['name'][$i]).'+" Error code...'

这样做的原因是json_encode 将接受任何输入并使其安全地转储到 JavaScript 上下文中。字符串将被引号包围并适当地转义为有效。但是,您必须先关闭现有引号,然后才能连接您的值以使其正常工作。

也就是说,我假设将此文本放入页面的函数将使用类似 document.createTextNode(arguments[0].text); 的内容来创建文本节点,而不是 HTML 上下文。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-27
    • 2015-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多