同源策略浅析

为什么使用同源策略?

一个重要原因就是对cookie的保护,cookie 中存着sessionID 。如果已经登录网站,同时又去了任意其他网站,该网站有恶意JS代码。如果没有同源策略,那么这个网站就能通过js 访问document.cookie 得到用户关于的各个网站的sessionID。其中可能有银行网站,通过已经建立好的session连接进行攻击,这里有一个专有名词,CSRF,还有需要注意的是同源策略无法完全防御CSRF,这里需要服务端配合。

什么是同源策略?

URL由协议、域名、端口和路径组成,如果两个URL的协议、域名和端口相同,则表示他们是同源的。同源策略是浏览器上为安全性考虑实施的非常重要的安全策略。限制来自不同源的"document",对当前"document"读取或设置某些属性。在浏览器中,<script>、<img>、<link>、<frame>等标签都可加载跨域资源,而不受同源策略限制,这带"src"属性的标签加载时,实际上是由浏览器发起一次GET请求,不同于XMLHttpRequest,他们通过src属性加载的资源。但浏览器限制了JavaScript的权限,使其不能读、写其中返回的内容。

跨域请求的安全基础是,JavaScript无法修改请求对象的http头部。如果XMLHttpRequest能够跨域请求资源,可能导致敏感信息泄露,比如CSRF的token信息

受同源策略限制的有哪些?

DOM、Cookie、XMLHttpRequest,还有一些第三方插件Flash、Java Applet、Sliverlight、Google Gears等都有自己的控制策略。

如何规避同源策略,即跨域请求?

document.domain属性

如果两个window或者frames包含的脚本可以把domain设置成一样的值,那么就可以规避同源策略,每个window之间可以互相沟通。例如,orders.example.com下页面的脚本和catalog.example.com下页面的脚本可以设置他们的document.domain属性为example.com,从而让这两个站点下面的文档看起来像在同源下,然后就可以让每个文档读取另一个文档的属性。这种方式也不是一直都有用,因为端口号是在内部保存的,有可能被保存成null。换句话说,example.com的端口号80,在我们更新document.domain属性的时候可能会变成null。为null的端口可能不被认为是80,这主要依赖浏览器实现。

跨域资源共享(CORS)

Cross-origin Resource Sharing跨资源共享,使用自定义的HTTP头部让浏览器与服务器沟通,从而决定请求和响应是否成功。这种方式使用了一个新的Origin请求头和一个新的Access-Control-Allow-Origin响应头扩展了HTTP。允许服务端设置Access-Control-Allow-Origin头标识哪些站点可以请求文件,或者设置Access-Control-Allow-Origin头为"*",允许任意站点访问文件。

浏览器,例如Firefox3.5,Safari4,IE10使用这个头允许跨域HTTP请求。

服务器端在HTTP的响应头中加入(页面层次的控制模式):

Access-Control-Allow-Origin: example.com

Access-Control-Request-Method: GET, POST

Access-Control-Allow-Headers: Content-Type, Authorization, Accept, Range, Origin

Access-Control-Expose-Headers: Content-Range

Access-Control-Max-Age: 3600

多个域名之间用逗号分隔,表示对所示域名提供跨域访问权限。"*"表示允许所有域名的跨域访问

客户端可以有两种行为:

1. 发送OPTIONS请求,请求Access-Control信息。如果自己的域名在允许的访问列表中,则发送真正的请求,否则放弃请求发送。

2. 直接发送请求,然后检查response的Access-Control信息,如果自己的域名在允许的访问列表中,则读取response body,否则放弃。本质上服务端的response内容已经到达本地,JavaScript决定是否要去读取。

跨文档通信(window.postMessage方法)

这种方式允许一个页面的脚本发送文本信息到另一个页面的脚本中,不管脚本是否跨域。基本上,它就像是跨域的AJAX,但不是浏览器跟服务器之间交互,而是在两个客户端之间通信。在一个window对象上调用postMessage()会异步的触发window上的onmessage事件,然后触发定义好的事件处理方法。一个页面上的脚本仍然不能直接访问另外一个页面上的方法或者变量,但是他们可以安全的通过消息传递技术交流。

允许程序员跨域在两个窗口/frames间发送数据信息。

窗口A: 发送窗口使用postMessage发送数据 window.postMessage(msg,urlOfB);

窗口B: 接收端,监听“message”事件

window.onmessage(event){

var data=event.data;

var origin=event.origin;

}

JSONP

JSONP利用<script>标签的跨域能力实现跨域数据的访问,请求动态生成的JavaScript脚本同时带一个callback函数名作为参数。其中callback函数本地文档的JavaScript函数,服务器端动态生成的脚本会产生数据,并在代码中以产生的数据为参数调用callback函数。当这段脚本加载到本地文档时,callback函数就被调用。

为了动态实现JSONP请求,可以使用Javascript动态插入<script>标签:

<script type="text/javascript">

// this shows dynamic script insertion

var script = document.createElement('script');

script.setAttribute('src', url);

// load the script

document.getElementsByTagName('head')[0].appendChild(script);

</script>

WebSocket

现代浏览器允许脚本直连一个WebSocket地址而不管同源策略。然而,使用WebSocket URI的时候,在请求中插入Origin头就可以标识脚本请求的源。为了确保跨站安全,WebSocket服务器必须根据允许接受请求的白名单中的源列表比较头数据。与JSONP方法不同的是,该响应函数被传入到创建<script> 标签的构造函数中,检测到已经成功接受到收据的状态后再执行函数

本文分享自微信公众号 - nginx遇上redis(GGame_over_the_world)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-12-23

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Best IDE for Web Development

    Top_10_Full_Stack_Web_Development_IDEs_1.png

    用户4822892
  • js --- ffmpeg rtsp 推流,websocket通信,cnavas 渲染

    小蔚
  • Cesium案例解析(一)——HelloWorld

    感觉网上已经有不少关于cesium的教程了,但是学习一个框架最快的办法就是熟悉其自带的实例了。cesium网站上提供了一系列实例,就想通过这些实例总结下学习ce...

    charlee44
  • cluster模块设置子进程的stdio

    子进程的stdout及stderr需要被设置为某个文件,根据文档 setupMaster 说明,需要设置stdio数组:

    欲休
  • ANCWEB - 基于 ASP.NET CORE 2.0 的 WEB 开发

    VS code 中使用终端,并执行dotnet new webapi 指令创建 ASP.NET CORE WEB API 项目。

    李郑
  • 关于 Promise 的 9 个面试题[每日前端夜话0xFB]

    我们使用构造函数方法创建一个 Promise,并通过 reject 回调立即触发错误。

    疯狂的技术宅
  • Kubernetes client-go实战应用

    以前创建和管理CRD的client库位于:https://github.com/kubernetes/apiextensions-apiserver,但是现在c...

    Allen.Wu
  • 鼠标点击网页出现爱心特效

    将以下代码添加到footer.php里即可(其他网站同理,放在网站页面的页头或页脚)

    AlexTao
  • 每个开发人员都应该知道的11个Linux命令

    本文主要挑选出读者有必要首先学习的 11 个 Linux 命令,如果不熟悉的读者可以在虚拟机或云服务器上实操下,对于开发人员来说,能熟练掌握 Linux 做一些...

    武培轩
  • 2020 年 Node.js 将会有哪些新功能[每日前端夜话0xFA]

    2019 年是 Node.js 诞生的第 10 个年头,npm 上可用的包数量超过了 100 万。Node.js 本身的下载量也在持续增长,同比增长了 40%。...

    疯狂的技术宅

扫码关注云+社区

领取腾讯云代金券