js之安全问题:Cookie、CSRF和XSS


Cookie安全性问题

作用

http是无状态的协议。客户端与服务端建立连接传输数据,数据传输完毕就断开连接,下次请求再创建新的链接,所以请求的时候服务器根本不知道是不是同一个用户进行请求。cookie就是为了解决http无状态问题,服务器发送登录凭据Cookie给客户端,用户再次访问的时候就会发送服务器,服务器再进行比对,确认无误就会免密码操作。
每次都会携带在 header 中,对于请求性能影响。
cookie大小限制是4k,是每个name=value的value的值大概是4k

如何使用
1
2
document.cookie = 'username=Ethan'
document.cookie = 'age=18'
生命周期

创建cookie的时候,会给cookie指定一个值:Expire,它就是指定cookie的有效期,也就是cookie的生命周期,超出设置的这个生命周期,cookie就会被清除。如果给这个值Expire设置为0或者负值,那么这样的设置就是在关闭浏览器时,就会清除cookie,这种方式更加安全。

作用域

支持同源策略

为什么不安全
1
2
3
4
5
0、每次请求都会带上cookie,浪费资源
1、最大的原因是因为它存储在浏览器端(用户本地),能够通过浏览器截获cookie(脚本、利用工具抓取等)。
2、cookie以纯文本的形式在浏览器和服务器之间传递,在web通信时极容易被非法用户截获和利用。
3、Flash中有一个getURL()函数,Flash利用它自动打开指定的页面。你在观看Flash动画时,在Flash的内部可以打开一个极小的包含特殊操作的页面,可以向远端输入当前cookie或者用户信息,由于这个是Flash内部的操作,所以网站无法禁止,要想避免,尽量打开本地防火墙以及访问正规网站。
非法用户截获cookie后,在cookie的有效时间内重新发放给服务器,那么这个非法用户就拥有了这个合法用户的所有权限。

IndexedDB

用于客户端存储大量结构化数据(包括文件和blobs)。没有存储上限的(一般来说不会小于 250M)。IndexedDB 是异步的。异步设计是为了防止大量数据的读写,拖慢网页的表现。会一直存在浏览器中,除非被清理。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
IndexedDB不是常用的调用方法,而是请求响应的模式。
function openDB(name){
var request=window.indexedDB.open(name)//建立打开IndexedDB
request.onerror=function (e){
console.log('open indexdb error')
}
request.onsuccess=function (e){
myDB.db=e.target.result//这是一个 IDBDatabase对象,这就是IndexedDB对象
console.log(myDB.db)//此处就可以获取到db实例
}
}
var myDB={
name:'testDB',
version:'1',
db:null
}
openDB(myDB.name)

sessionStorage和localStorage和cookie的区别

1
2
3
作用域:localStorage只要在相同的协议、相同的主机名、相同的端口下,就能读取/修改到同一份localStorage数据。sessionStorage比localStorage更严苛一点,除了协议、主机名、端口外,还要求在同一窗口(也就是浏览器的标签页)下

生命周期:localStorage 是持久化的本地存储,存储在其中的数据是永远不会过期的,使其消失的唯一办法是手动删除;而 sessionStorage 是临时性的本地存储,它是会话级别的存储,当会话结束(页面被关闭)时,存储内容也随之被释放。
如何解决
1
2
3
4
1、设置cookie有效期不要过长
2、设置HttpOnly属性为true(防止js脚本读取cookie信息,有效的防止XSS攻击)
3、用户第一次登录时,保存ip+cookie加密后的token。每次请求,都去将当前cookie和ip组合起来加密后的token与保存的token作对比,只有完全对应才能验证成功。
4、如果网站支持https,那么可以为cookie设置Secure属性为true,它的意思是,cookie只能使用https协议发送给服务器,而https比http更加安全。

CSRF的安全性问题

概念及原理
1
2
3
4
5
6
7
8
全称:跨站请求伪造。
概念:攻击者盗用了你的身份,伪装成你发送恶意请求。
攻击原理:
1、用户C访问正常网站A时进行登录,浏览器保存A的cookie
2、用户C再访问攻击网站B,网站B上有某个隐藏的链接或者图片标签会自动请求网站A的URL地址,例如表单提交,传指定的参数
如:<img src=”http://bank.example/withdraw?account=bob&amount=1000000&for=黑客 />
3、而攻击网站B在访问网站A的时候,浏览器会自动带上网站A的cookie
4、所以网站A在接收到请求之后可判断当前用户是登录状态,所以根据用户的权限做具体的操作逻辑,造成伪造成功
防范措施
1
2
3
4
5
6
7
8
9
1、验证HTTP Referer字段
根据 HTTP 协议,在 HTTP 头中有一个字段叫 Referer,它记录了该 HTTP 请求的来源地址。也就是说,服务器会验证客户端的请求来源,如果本网站请求的则响应,否则不响应。
缺点:1.每个浏览器对于 Referer 的具体实现可能有差别,并不能保证浏览器自身没有安全漏洞。对于某些浏览器,比如 IE6 或 FF2,目前已经有一些方法可以篡改 Referer 值。2.用户自己可以设置浏览器使其在发送请求时不再提供 Referer

2、在HTTP 头中自定义属性并验证
在HTTP的head中放入token,在用户登陆后产生token放于session或cookie中,然后在每次请求时服务器把token从session或cookie中拿出,与本次请求中的token 进行比对。由于token的存在,攻击者无法再构造出一个完整的URL实施CSRF攻击。但在处理多个页面共存问题时,当某个页面消耗掉token后,其他页面的表单保存的还是被消耗掉的那个token,其他页面的表单提交时会出现token错误。

3、验证码
应用程序和用户进行交互过程中,特别是账户交易这种核心步骤,强制用户输入验证码,才能完成最终请求。

XSS的安全问题

概念及原理
1
2
3
4
5
6
7
8
9
10
11
12
13
1、全称
跨域脚本攻击

2、XSS攻击的核心原理是
不需要你做任何的登录认证,它会通过合法的操作(比如在url中输入、在评论框中输入),向你的页面注入脚本(可能是js、hmtl代码块等)。

3、攻击方式
1、反射型:XSS代码出现在url,referer 中注入可执行脚本代码(https://xxx.com/xxx?default=<script>alert(document.cookie)</script>),通过用户点击操作,通过 HTTP 的 GET 和 POST 请求就能完成一次攻击,拿到用户隐私数据。
2、存储型:存储型XSS和反射型XSS的差别在于,一般存在于 Form 表单提交等交互功能,将提交的代码会存储在服务器端(数据库、内存、文件系统等),当前端页面获得后端从数据库中读出的注入代码时,恰好将其渲染执行。
满足条件:POST 请求提交表单后端没做转义直接入库。后端从数据库中取出数据没做转义直接输出给前端。前端拿到后端数据没做转义直接渲染成 DOM。

4、攻击的结果
盗用Cookie,破坏页面的正常结构,插入广告等恶意内容
XSS的防范措施
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 反射型
1、Web 页面渲染的所有内容或者渲染的数据都必须来自于服务端。
2、尽量不要从 URL,document.referrer,document.forms 等这种 DOM API 中获取数据直接渲染。
3、尽量不要使用 eval, new Function()等可执行字符串的方法。

// 存储型
1、编码
对用户输入的数据进行HTML Entity编码。比如<script>alert(1)</script>,若不进行任何处理,则浏览器会执行alert的js操作,实现XSS注入。进行编码处理之后,L在浏览器中的显示结果就是<script>alert(1)</script>,实现了将$var作为纯文本进行输出。
2、过滤
移除用户输入的和事件相关的属性。如onerror可以自动触发攻击,还有onclick等。(总而言是,过滤掉一些不安全的内容)
移除用户输入的Style节点、Script节点、Iframe节点。(尤其是Script节点,它可是支持跨域的呀,一定要移除)。
3、校正
避免直接对HTML Entity进行解码,使用DOM Parse转换,校正不配对的DOM标签。
DOM Parse的作用是把文本解析成DOM结构。

// CSP方式
CSP 本质上就是建立白名单,开发者明确告诉浏览器哪些外部资源可以加载和执行。我们只需要配置规则,如何拦截是由浏览器自己实现的。我们可以通过这种方式来尽量减少 XSS 攻击。
设置 HTTP Header 中的 Content-Security-Policy:
Content-Security-Policy: default-src 'self' // 只允许加载本站资源
Content-Security-Policy: img-src https://* // 只允许加载 HTTPS 协议图片
Content-Security-Policy: child-src 'none' // 允许加载任何来源框架

CSRF和XSS的区别

CSRF:1、需要用户先登录网站A,获取 cookie。2、是利用网站A本身的漏洞,去请求网站A的api。
XSS:1、不需要登录。2、是向网站 A 注入 JS代码,然后执行 JS 里的代码,篡改网站A的内容。