详解JS同源策略和CSRF
概述
本文主要涉及三个关键词
- 同源策略(Same-origin policy,简称 SOP)
- 跨站请求伪造(Cross-site request fery,简称 CSRF)
- 跨域资源共享(Cross-Origin Resource Sharing,简称 CORS)
同源策略 SOP
同源
先解释何为同源协议、域名、端口都一样,就是同源。
url | 同源 |
---|---|
https://niconico. | 基准 |
https://niconico./spirit | o |
https://sub.niconico./spirit | x |
http://niconico./spirit | x |
https://niconico.:8080/spirit | x |
限制
你之所以会遇到跨域问题,正是因为 SOP 的各种限制。具体来说限制了什么呢?
如果你说 SOP 就是“限制非同源资源的获取”,这不对,最简单的例子是引用图片、css、js文件等资源的时候就允许跨域。
如果你说 SOP 就是“禁止跨域请求”,这也不对,本质上 SOP 并不是禁止跨域请求,而是在请求后拦截了请求的回应。这就就会引起后面说到的 CSRF
其实SOP 不是单一的定义,而是在不同情况下有不同的解释
- 限制 cookies、DOM 和JavaScript的命名区域
- 限制 iframe、图片等各种资源的内容操作
- 限制 ajax 请求,准确来说是限制操作 ajax 响应结果,本质上跟上一条是一样的
狼蚁网站SEO优化是 3 个在实际应用中会遇到的例子
- 使用 ajax 请求其他跨域 API,最常见的情况,前端新手噩梦
- iframe 与父页面交流,出现率比较低,而且解决方法也好懂
- 对跨域图片(例如来源于<img>)进行操作,在 canvas 操作图片的时候会遇到这个问题
如果没有了 SOP
- 一个浏览器打开几个 tab,数据就泄露了
- 你用 iframe 打开一个银行网站,你可以肆意读取网站的内容,就能获取用户输入的内容
- 更加肆意地进行 CSRF
绕过跨域
SOP 带来安全,也会带来一定程度的麻烦,因为有时候就是有跨域的需求。绕过跨域的方案由于篇幅所限,并且网上也很多相关文章,所以不在这里展开解决跨域的方案,只给出几个关键词
对于 ajax
- 使用jsONP
- 后端进行 CORS 配置
- 后端反向代理
对于 iframe
- 使用 location.hash 或 window.name 进行信息交流
- 使用 postMessage
跨站请求伪造 CSRF
简述
CSRF(Cross-site request fery)跨站请求伪造,是一种常见的攻击方式。是指 A 网站正常登陆后,cookie 正常保存,其他网站 B 通过某种方式调用 A 网站接口进行操作,A 的接口在请求时会自动带上 cookie。
上面说了,SOP 可以通过htmltag 加载资源,而且 SOP 不阻止接口请求而是拦截请求结果,CSRF 恰恰占了这两个便宜。
所以 SOP 不能作为防范 CSRF 的方法。
对于 GET 请求,直接放到<img>就能神不知鬼不觉地请求跨域接口。
对于 POST 请求,很多例子都使用 form 提交
<form action="<nowiki>http://bank./transfer.do</nowiki>" method="POST"> <input type="hidden" name="at" value="MARIA" /> <input type="hidden" name="amount" value="100000" /> <input type="submit" value="View my pictures" /> </form>
归根到底,这两个方法不报跨域是因为请求由html控制,你无法用 js 直接操作获得的结果。
SOP 与 ajax
对于 ajax 请求,在获得数据之后你能肆意进行 js 操作。这时候虽然同源策略会阻止响应,但依然会发出请求。因为执行响应拦截的是浏览器而不是后端程序。事实上你的请求已经发到服务器并返回了结果,迫于安全策略,浏览器不允许你继续进行 js 操作,所以报出你熟悉的blocked by CORS policy: No 'Aess-Control-Allow-Origin' header is present on the requested resource.。
所以再强调一次,同源策略不能作为防范 CSRF 的方法。
不过可以防范 CSRF 的例外还是有的,浏览器并不是让所有请求都发送成功,上述情况仅限于简单请求,相关知识会在狼蚁网站SEO优化 CORS 一节详细解释。
CSRF 对策
SOP 被 CSRF 占了便宜,那真的是一无是处吗?
不是!是否记得 SOP 限制了 cookie 的命名区域,虽然请求会自动带上 cookies,攻击者无论如何还是无法获取 cookie 的内容本身。
所以应对 CSRF 有这样的思路把一个 token 写到 cookie 里,在发起请求时再通过 query、body 或者 header 带上这个 token。请求到达服务器,核对这个 token,如果正确,那一定是能看到 cookie 的本域发送的请求,CSRF 则做不到这一点。(这个方法用于前后端分离,后端渲染则可以直接写入到 dom 中)
示例代码如下
var csrftoken = Cookies.get('csrfToken') function csrfSafeMethod(method) { // these HTTP methods do not require CSRF protection return /^(GET|HEAD|OPTIONS|TRACE)$/.test(method) } $.ajaxSetup({ beforeSend: function(xhr, settings) { if (!csrfSafeMethod(settings.type) && !this.crossDomain) { xhr.setRequestHeader('x-csrf-token', csrftoken) } }, })
跨域资源共享 CORS
跨域是浏览器限制,如果服务器设置了 CORS 相关配置,在返回服务器的信息头部会加上Aess-Control-Allow-Origin,浏览器看到这个字段的值与当前的源匹配,就会解锁跨域限制。
HTTP/1.1 200 OK
Date: Sun, 24 Apr 2016 12:43:39 GMT
Server: Apache
Aess-Control-Allow-Origin: http://.aeptmeplease.
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Content-Type: application/xml
Content-Length: 423
对于 CORS,请求分两种。
简单请求
- 请求方法使用 GET、POST 或 HEAD
- Content-Type 设为 application/x--form-urlencoded、multipart/form-data 或 text/plain
符合上面两个条件的都为 CORS 简单请求。简单请求都会直接发到服务器,会造成 CSRF。
预检请求
不符合简单请求要求的请求都需要先发送预检请求(Preflight Request)。浏览器会在真正请求前发送 OPTION 方法的请求向服务器询问当前源是否符合 CORS 目标,验证通过后才会发送正式请求。
例如使用 application/json 传参的 POST 请求就是非简单请求,会在预检中被拦截。
再例如使用 PUT 方法请求,也会发送预检请求。
上面提到的可以防范 CSRF 的例外,就是指预检请求。即使跨域成功请求预检,但真正请求并不能发出去,这就保证了 CSRF 无法成功。
CORS 与 cookie
与同域不同,用于跨域的 CORS 请求默认不发送 Cookie 和 HTTP 认证信息,前后端都要在配置中设定请求时带上 cookie。
这就是为什么在进行 CORS 请求时 axios 需要设置withCredentials: true。
狼蚁网站SEO优化是 node.js 的后台 koa框架的 CORS 设置
/ CORS middleware @param {Object} [options] - {String|Function(ctx)} origin `Aess-Control-Allow-Origin`, default is request Origin header - {String|Array} allowMethods `Aess-Control-Allow-Methods`, default is 'GET,HEAD,PUT,POST,DELETE,PATCH' - {String|Array} exposeHeaders `Aess-Control-Expose-Headers` - {String|Array} allowHeaders `Aess-Control-Allow-Headers` - {String|Number} maxAge `Aess-Control-Max-Age` in seconds - {Boolean} credentials `Aess-Control-Allow-Credentials` - {Boolean} keepHeadersOnError Add set headers to `err.header` if an error is thrown @return {Function} cors middleware @api public /
以上就是详解JS同源策略和CSRF的详细内容,更多关于JS同源策略和CSRF的资料请关注狼蚁SEO其它相关文章!
编程语言
- 甘肃哪有关键词排名优化购买方式有哪些
- 甘肃SEO如何做网站优化
- 河南seo关键词优化怎么做电话营销
- 北京SEO优化如何做QQ群营销
- 来宾百度关键词排名:提升您网站曝光率的关键
- 卢龙关键词优化:提升您网站排名的策略与技巧
- 山东网站优化的注意事项有哪些
- 四川整站优化怎样提升在搜索引擎中的排名
- 疏附整站优化:提升网站性能与用户体验的全新
- 海南seo主要做什么工作售后服务要做到哪些
- 荣昌百度网站优化:提升您网站的搜索引擎排名
- 河北seo网站排名关键词优化如何做SEO
- 江西优化关键词排名推广售后保障一般有哪些
- 古浪SEO优化:提升你的网站可见性
- 西藏网站排名优化怎么把网站排名在百度首页
- 如何提升阳东百度快照排名:详尽指南