2013-06-20 5 views
6

Я строю простой поболтать с Node.js и Socket.ioSecure Node.js чат (избежать XSS)

Когда пользователь его сообщение, оно транслируется всем остальным пользователям.

Сервер отправляет сообщение:

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

Client отображает его:

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

Но когда вы посылаете что-то вроде <script>alert(1);</script>, она выполняется на каждом клиентском браузере.

Это серьезный недостаток безопасности, и я хочу избежать его как можно большего. Я видел, как люди бежали &, <, > and " персонажей, но я не думаю, что этого достаточно!

Как я могу быть на 100% уверен, что у меня нет уязвимости XSS в чате?

Кстати, я всегда указываю кодировку, чтобы избежать атак UTF-7.

Благодарим за помощь.

ответ

8

Не используйте .html(), потому что это в основном eval на стероидах - способный вызывать интерпретацию большого разнообразия языков.

Текст всегда интерпретируется как текст, хотя:

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

Большое спасибо за этот очень хороший ответ. Я не думал, что это будет так просто, и я могу сказать, что он отлично работает. – mimipc

3

Лучший способ здесь, на сервере ничего не делать!

Да, вы читали это правильно. Правильное место для «escape-контента» - это то место, где оно выводится, в том контексте, в котором он выводится. Это называется Filter-In, Escape out.

Так что в вашем случае клиент должен справиться с побегом для вас. Забавно, что jQuery (похоже, что вы используете) имеет метод, который делает это для вас: $.fn.text(). Так что ваш клиентский код становится:

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

Я добавил div так, что каждое сообщение может быть стилизован соответствующим образом ...

Но вашей стороне сервера не должны иметь ничего общего с этим избежать.

Теперь вы можете отфильтровать все, что похоже на HTML на сервере, которое будет называться Filtering (и либо заменить его, либо отклонить). Но определенно не избежать этого!

+0

Спасибо, это тоже помогло;) – mimipc

+1

будьте осторожны: «клиент должен справиться с побегом для вас» - это не всегда хорошая идея. Например, представьте, что ваш клиент избегает сообщения перед его отправкой (тот, кто говорит, тот, кто избегает текста). Это будет проблемой безопасности, поскольку клиент может манипулировать экранирующим кодом, чтобы ничего не избежать. Поэтому будьте осторожны при выборе правильного клиента! – TheBronx

+0

@ TheBronx: Это всегда * хорошая идея, и в большинстве случаев это единственный способ добиться реальной безопасности.Обратите внимание, что под «клиентом» я подразумеваю, что на самом деле его отображает (вводя его в HTML). Если ваш сервер отображает HTML, сервер будет выполнять экранирование. Что касается ускользания перед отправкой, это неправильно с самого начала, и именно поэтому это будет небезопасно. Filter In, Escape Out очень хорошо определен и, как известно, работает. Если вы отклоняетесь от этого, это на вас ... Клиент * должен * избегать его до * вывода * данных. Не перед отправкой ... – ircmaxell