深入CORS:历史,工作原理和最好的例子
学习同源策略和CORS(Cross-Origin-Resource-Sharing)(跨域资源共享)的历史的演变,深入理解CORS和不同类型的跨域访问策略以及一些最好的例子。
文章目录
- 你的浏览器控制台报错了
- 起点:第一个子资源标签
- 域与跨域
- 跨域请求的危害
- 同源策略
- 进入CORS
- 跨域写
- 预请求
- 跨域读
- 如何使用好CORS
- 一些好例子
- 所有请求都允许
- Keeping it in the family
- NULL域
- 跳过Cookies,如果你能的话
- 附加阅读
- 后记
你的浏览器控制台报错了
我确定你在浏览器的控㓡台见过上面的报错或者它们的变体。如果你没有见过,不用担心,你总会遇到的。对于所有开发人员来说,遇到CORS错误是常事。
在开发过程中遇到些种问题可能是烦人的,但实际上,在一个配置异常的web服务器上,网络上的攻击者或者推动网络标准的组织来说,CORS是一种非常有用的机制。
首先,让我们回到起点。
起点:第一个子资源标签
子资源标签是一个请求被嵌入到文档或者一个请求在上下文中被执行的HTML标签。在1993年,第一个子资源标签 <img>
出现了。为了兼容 <img>
标签,网络页面变得更漂亮了,但也更复杂了。
所以,如果你的浏览器想要渲染一个带有 <img>
标签的网页,它就必须从域中请求子资源。当浏览器请求的子资源与域在协议,主机名和端口上任何一个不同时,这就是一个跨域请求。
域与跨域
域被从三个方向定义:协议,完整的主机名和端口。例如:http://example.com
和 https://example.com
是不同域的。第一个使用 http
协议,而第二个使用 https
协议。而且默认的 http
协议使用80端口,而 https
协议使用443端口。所以在这个例子中,这两个域因为协议和端口不同而不周域,尽管它们的主机名是一样的。
同理,你知道如果三个条件中其中有一个不同,那域就是不同的。
下面是我们总结与 https://blog.example.com/posts/foo.html
域同源或者跨域结果的例子:
URL | 结果 | 原因 |
---|---|---|
https://blog.example.com/posts/bar.html
|
同源 | 只有路径不同 |
https://blog.example.com/contact.html
|
同源 | 只有路径不同 |
http://blog.example.com/posts/bar.html
|
不同源 | 协议不同 |
https://blog.example.com:8080/posts/bar.html
|
不同源 |
端口不同( https:// 默认使用443端口)
|
https://example.com/posts/bar.html
|
不同源 | 主机名不同 |
其中一个跨域请求例子:一个来自 http://example.com/posts/bar.html
页面想请求从 https://example.com
来的子资源。
跨域请求的危害
现在我们知道了什么是同源和跨域,让我们看看会发生什么大事。
当我们介绍出现了第一个子资源标签 <img>
的时候,我们就已经打开了闸门,之后我们有了 <script>
,<frame>
,<video>
,<audio>
,<iframe>
,<link>
,<form>
等等更多的子资源标签。这些子资源标签都可以发出同源或者跨域请求。
我们想像一个CORS不存在而且所有跨域请求都被允许的世界。
想像这样一个场景:我从 evil.com
得到一个带 <script>
标签的页面,从表面上看,这是一个简单的页面,能显示一些有用的信息。但是在 <script>
标签里面有我精心设计的代码,会发送一个精心设计的 DELETE /account
请求到银行的服务器。你只要加载一次这个页面,JavaScript脚本就会被执行,异步请求就会调用银行的API。
惊喜不惊喜?你只要在网页上浏览一些信息,你就能收到成功删除银行账号的邮件。事实上我猜它能向银行做任何事情。
为了让我邪恶的 <script>
标签能工作,在请求中你的浏览器还必须带从银行网站得到的凭证(cookies)。这是为什么银行服务器能认识你并知道删除哪个账号的原因。
现在让我们看一个不那么邪恶的例子。
我想查看一个在Awesome Corp工作的朋友,他工作的内网是 intra.awesome-corp.com
。在我的网站 dangerous.com
我有一个 <img src="https://intra.awesome-corp.com/avatars/john-doe.png">
标签。
未能与内网 intra.awesome-corp.com
建立有效会话的用户,头像将不会渲染,会出现一个错误。但是,当你登录内网,访问过一次我的网站,我就知道你建立了有效会话。
这意味着我能得到你的一些信息。对我来说直接攻击可能比较困难,但是知道你登录Awesome Corp仍然是一个潜在的攻击媒介。
这两个过于简单的例子显示出的威胁说明了同源策略和CORS的必要。跨域请求的危险多种多样。一些可以缓解,另一些则是不能缓解的-它建立在网络的本质上。因为CORS,大量的攻击媒介被压缩。
在了解CORS之前,我们要先了解一下同源策略。
同源策略
同源策略可以通过阻止不同源的资源加载来预防跨源攻击。但是这个策略还是允许一些标签如 <img>
嵌入不同源的资源的。
同源策略每一次出现在1995年的2.02版本的网景浏览器(Netscape Navigator)上。源头是为了保护跨源访问DOM。
虽然同源策略没有明确的标准,但是所有现代浏览器都以某种形式实现了它,最后IETF在RFC6454中定义了同源策略的标准。
同源策略被定义成了下面的规则集:
标签 | 跨域策略 | 注意 |
---|---|---|
<iframe>
|
允许嵌入 |
取决于 X-Frame-Options
|
<link>
|
允许嵌入 |
属性 Content-Type 可能需要
|
允许写 |
同源策略解决了很多问题,但是也有点严格了。从单页应用到重媒体网站,同源策略并没有留下足够的余地去调整这些规则。
CORS出生的目标就是调整同源策略以适应不同的跨域访问。
进入CORS
现在我们知道了源的定义,跨域请求的缺点和浏览器实现的同源策略。
是时候了解CORS(跨域资源分享)了。CORS是一种允许控制通过网络访问网页上的子资源的机制。这种机制定义了三种子资源访问策略:
- 跨域写
- 跨域嵌入
- 跨域读
在我们解释每一种策略之前,需要意识到非常重要的一点是:浏览器允许某种类型的跨域请求,并不代表服务器会接受这类请求。
跨域写 代表链接,重定向和表单提交。当你的浏览器开启CORS时,这些都是被允许的。而且还有一种叫预请求的机制对跨域写进行调整。所以默认允许进行跨域写也并不代表它能成功。我们会在稍后讨论它。
跨域嵌入代表子资源加载,如:<script>
,<link>
,<img>
,<video>
,<audio>
,<object>
,<embed>
,<iframe>
等等。这些默认都被允许。<iframe>
比较特殊——它的目的是嵌入另外的页面,是否允许嵌入被 X-Frame-options
请求头控制。
当是其它标签时,它们很自然的会触发跨域请求。这是为什么CORS要区分跨域读和跨域嵌入的原因。
跨域读代表通过调用AJAX或者 fetch
函数加载子资源。它们在你的浏览器中默认是被禁止的。这是在页面中嵌入子资源的一个解决方法。但是这种方法在现代浏览器中被另一个策略控制。
如果你的浏览器是最新的,所有的这些策略应该已经都实现了。
跨域写
跨域写可能是问题的。让我们通过例子写实际看看CORS。
首先,我们设置一个简单的Crystal HTTP服务器(使用 Kemal)(我自己使用express服务实现了一个相同的):
require "kemal"port = ENV["PORT"].to_i || 4000get "/" do"Hello world!"
endget "/greet" do"Hey!"
endpost "/greet" do |env|name = env.params.json["name"].as(String)"Hello, #{name}!"
endKemal.config.port = port
Kemal.run
这一个简单的请求,路径是 /greet
,有一个name参数,返回一个 Hello #{name}!
字符串。为了运行这个服务器,你可以用下面的命令:
$ crystal run server.cr
它将会启动服务到 localhost:4000
。如果现在我们使用浏览器访问这个路径,会得到一个简单的 “Hello World”页面。
深入CORS:历史,工作原理和最好的例子相关推荐
- 2023最新全网素材解析网站工作原理,附带小例子。
我算是比较早接触素材网站的,因为之前就是做设计的,那时候没那么多套路,分享推广就可以获得网站永久VIP,然后,现在变得吃相极其难看了,各类型的VIP区分,想让客户二次付费.由此就诞生了很多代下的服务, ...
- 区块链凭什么改变这个世界?从它的工作原理谈起
比特币曾被视为一种"惊世骇俗"的产物,然而现在整个世界都在为之疯狂. 自经济衰退以来,加密虚拟货币受到高度追捧,并被称为解决传统金融体系内不公平与腐败问题的良药.支持者们深信,随着 ...
- 显卡的结构和工作原理及发展历史与现状
显卡的结构和工作原理及发展历史与现状 一.显卡的基本结构 1.线路板. 目前显卡的线路板一般采用的是6层或4层PCB线路板.显卡的线路板是显卡载体,显卡上的所有元器件都是集成在这上面的,所以PCB板也 ...
- 真空三极管:发明历史和物理工作原理
真空三极管是:发明历史与工作原理 Triode Vacuum Tube: History & Physics Kathy老师讲述的有趣科学历史 01 Triode Valve Before ...
- 科普:探地雷达发展历史、天线分类,结构组成和工作原理
(一)探地雷达方法 探地雷达方法是一种用于确定地下介质分布的广谱(10MHz~3GHz)电磁技术.一个天线发射高频宽频带电磁波,另一个天线接收地下介质界面的反射波.利用回波的回程时间.振幅和波形资料等 ...
- CPU的发展历史和工作原理
发展历史∶ CPU出现于大规模集成电路时代,处理器架构设计的迭代更新以及集成电路工艺的不断提升促使其不断发展完善.从最初专用于数学计算到广泛应用于通用计算,从4位到8位.16位.32位处理器,最后到6 ...
- 2021年大数据ELK(十八):Beats 简单介绍和FileBeat工作原理
全网最详细的大数据ELK文章系列,强烈建议收藏加关注! 新文章都已经列出历史文章目录,帮助大家回顾前面的知识重点. 目录 Beats 简单介绍和FileBeat工作原理 一.Beats 二.FileB ...
- 图解 Git 工作原理
来源:深度学习爱好者本文约2600字,建议阅读5分钟本文图解Git中的最常用命令.如果你稍微理解Git的工作原理,这篇文章能够让你理解的更透彻. 基本用法 上面的四条命令在工作目录.暂存目录(也叫做索 ...
- 人类将可能操控AI?神经网络语言处理工作原理被破解
近期,来自麻省理工学院计算机科学人工智能实验室(CSAIL)和卡塔尔计算研究所的研究人员已经通过新的解释技术,来分析神经网络做机器翻译和语音识别的训练过程. 神经网络通过分析大量的训练数据来学习并执行 ...
最新文章
- 用鞋子给视障人士导航!这款“导盲鞋”可检测4米外障碍物,振动提醒躲避,一双2w5...
- ubuntu install opengl
- makefile常见伪目标(.PHONY 不会去检查目标文件)
- 【已解决】Linux远程桌面连接-VNC
- 解决Navicat 出错:1130-host . is not allowed to connect to this MySql server,MySQL
- 临近年关,修复ASP.NET Core因浏览器内核版本引发的单点登录故障
- Unity 2D工具:工作流介绍
- python有趣小程序-第一个有趣的python小程序
- git 客户端_GEE 学习笔记 3: 客户端连接远程服务器的 Jupyter ( git 作为本地工具)
- silvaco器件仿真bug整理
- c预言plc编程语言,【讨论】对于PLC的编程语言STL、LAD、SCL等,你用的哪种语言呢?...
- 身为码农,为12306说两句公道话
- linux iio子系统
- C/C++音乐播放(亲测有效)
- 计步器(Pedometer)实现原理简介
- excel熵值法计算权重_SPSS主成分分析 | 权重计算amp;极差法标准化超详细教程!(下)...
- 关于Keil编译程序出现“File has been changed outside the editor,reload?”的解决方法
- dataTables -- ajax 分页基本使用
- Python实现base64编码文件转化为jpg/png/jpeg/格式图片
- Linux进程通信(一)——pipe管道
热门文章
- MATLAB学习笔记一:基础知识
- pic单片机配置字c语言,PIC单片机配置字说明及使用.pdf
- 解决问题:安装Visio版本冲突(MSI与即点即用)
- 服务器许可证密钥,如何生成和验证软件许可证密钥?
- ibm服务器如何查硬件支持型号,ibm服务器硬件安装步骤是怎样
- 《程序设计实践》中文版pdf
- 商家编号_caiji_004 机器人词库
- 获取文件的大小(fseek和ftell函数)
- 正确处理下载文件时HTTP头的编码问题(Content-Disposition),safari下载文件 中文名乱码问题
- Mac常见问题|Safari下载文件没有反应的解决方法