【问题标题】:Secure Node.js chat (avoid XSS)安全的 Node.js 聊天(避免 XSS)
【发布时间】:2013-06-20 23:51:54
【问题描述】:

我正在使用 Node.js 和 socket.io 构建一个简单的小聊天

当用户键入他的消息时,它会广播给所有其他用户。

服务器发送消息:

io.sockets.emit('fromServerToClient', { "message": message });

客户端显示它:

socket.on('fromServerToClient', function (data) {
    $('#messages').append(data.message + '<br />');
});

但是当您发送类似&lt;script&gt;alert(1);&lt;/script&gt; 的内容时,它会在每个客户端浏览器上执行。

这是一个严重的安全漏洞,我想尽可能避免它。 我见过有人逃避&amp;, &lt;, &gt; and " 字符,但我认为这还不够!

我怎样才能 100% 确定我的聊天中没有 XSS 漏洞?

顺便说一句,我总是指定字符集以避免 UTF-7 攻击。

感谢您的帮助。

【问题讨论】:

    标签: javascript node.js security socket.io xss


    【解决方案1】:

    不要使用.html(),因为这基本上是在类固醇上使用eval - 能够导致多种语言的解释。

    文本总是被解释为文本:

    $('#messages').append($("<div>", {
        text: data.message
    }));
    

    【讨论】:

    • 非常感谢这个非常好的答案。没想到这么简单,可以说效果很好。
    【解决方案2】:

    这里最好的方法是让服务器什么都不做!

    是的,你没看错。 “转义”内容的正确位置是输出它的位置,在它被输出的上下文中。这就是所谓的过滤输入,退出。

    因此,在您的情况下,客户端应该为您处理转义。有趣的是,jQuery(看起来你正在使用它)有一个方法可以为你做到这一点:$.fn.text()。所以你的客户端代码变成了:

    socket.on('fromServerToClient', function (data) {
        $('#messages').append($('<div></div>').text(data.message));
    });
    

    我添加了div,以便可以适当地设置每条消息的样式...

    但是你的服务器端应该与这个转义无关。

    现在,您可以决定在服务器上过滤掉任何看起来像 HTML 的内容,这称为过滤(或者将其替换掉,或者拒绝它)。但绝对不能逃避!

    【讨论】:

    • 谢谢,这也很有帮助;)
    • 小心:“客户应该为你处理转义”并不总是一个好主意。例如,假设您的客户在发送消息之前对其进行了转义(说话的人就是转义文本的人)。这将是一个安全问题,因为客户端可以操纵转义代码以不转义任何内容。所以在选择合适的客户时要小心!
    • @TheBronx:这总是是个好主意,并且在大多数情况下是实现实际安全性的唯一方法。请注意,“客户端”是指实际显示它的任何内容(将其注入 HTML)。如果您的服务器呈现 HTML,则服务器会进行转义。至于在发送之前转义,从一开始就是错误的,这就是不安全的原因。 Filter In, Escape Out 的定义非常明确并且可以工作。如果你偏离了那个,它就在你身上......客户端必须输出数据之前转义它。不是在发送之前...
    • @ircmaxell 我知道你想说什么,我认为它是正确的。但这对于新手来说可能会感到困惑,因为在聊天中,写作者和阅读者都是应用程序的“客户”。只是想澄清一下,对不起。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-08
    • 2020-09-10
    • 1970-01-01
    相关资源
    最近更新 更多