6

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

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

服务器发送消息:

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

客户端显示它:

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

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

这是一个严重的安全漏洞,我想尽可能避免它。我见过人们逃避&, <, > and "角色,但我认为这还不够!

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

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

谢谢你的帮助。

4

2 回答 2

9

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

文本总是被解释为文本:

$('#messages').append($("<div>", {
    text: data.message
}));
于 2013-06-20T23:57:16.757 回答
3

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

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

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

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

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

但是您的服务器端应该与此转义无关。

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

于 2013-06-20T23:57:35.523 回答