详解XMLHttpRequest的跨域资源共享
0x00 背景
在Browser Security-同源策略、伪URL的域这篇文章中提到了浏览器的同源策略,其中提到了XMLHttpRequest严格遵守同源策略,非同源不可请求。但是,在实践当中,经常会出现需要跨域请求资源的情况,比较典型的例如某个子域名向负责进行用户验证的子域名请求用户信息等应用。
以往,有一种解决方案是利用JSONP进行跨域的资源请求,但这种方案存在着几点缺陷:
1)只能进行GET请求
2)缺乏有效的错误捕获机制。因此在XMLHttpRequest v2标准下,提出了CORS(Cross Origin Resourse-Sharing)的模型,试图保证跨域请求的安全性。
现在,各大主流浏览器均支持CORS模型,其中IE 8, IE 9需要使用XDomainRequest进行跨域请求。
0x01 基本模型
虽然说允许了XMLHttpRequest的跨域请求,但是这种许可并不是无条件的。
浏览器在进行请求时也会判断请求的合法性,验证是通过服务器的返回头来进行的,这时就涉及到了具体的请求类型,所以在标准中定义了简单跨域请求。
简单跨域请求就是满足下列条件的请求:
请求方法为GET或POST
请求方法中没有设置请求头(Accept, Accept-Language, Content-Language, Content-Type除外)
如果设置了Content-Type头,其值为application/x-www-form-urlencoded, multipart/form-data或 text/plain
验证简单跨域请求与非简单跨域请求合法性的区别就在于,验证非简单跨域请求前,浏览器向服务器发送一个OPTIONS方法的预检请求来加以判断,如果预检失败,实际请求将被丢弃。而简单跨域请求浏览器会正常发送请求,再对返回头加以判断以检查请求的合法性。在检查失败时,浏览器将会阻止脚本对返回内容的访问。
在http://zone.wooyun.org/content/4917中,LZ因为设定了X-Forward-For头,所以浏览器先发送了预检请求,检查失败后丢弃了实际头,所以造成了LZ的误解。
0x02 请求时发送的HTTP头
简单跨域请求并不会包含下面的HTTP头。而预检请求将会发送以下HTTP头
Origin: 普通的HTTP请求也会带有,在CORS中专门作为Origin信息供后端比对
Access-Control-Request-Method: 接下来请求的方法,例如PUT, DELETE等等
Access-Control-Request-Headers: 自定义的头部,所有用setRequestHeader方法设置的头部都将会以逗号隔开的形式包含在这个头中
其他头,例如实际请求的头部,Cookie头等都将不被包含在预检请求中。
0x03 返回的HTTP头
浏览器主要通过返回的这些HTTP头判断请求是否合法。值得注意的一点是,预检请求通过并不代表请求一定会成功,如果预检请求时服务器返回的HTTP头使浏览器判断请求合法,从而发出了实际请求,但是实际请求的返回头中含有的访问控制头显示请求不合法时,浏览器仍会判定请求不合法,从而向脚本隐藏返回的细节。
Access-Control-Allow-Origin: 允许跨域访问的域,可以是一个域的列表,也可以是通配符"*"。这里要注意Origin规则只对域名有效,并不会对子目录有效。即http://foo.example/subdir/是无效的。但是不同子域名需要分开设置,这里的规则可以参照那篇同源策略
Access-Control-Allow-Credentials: 是否允许请求带有验证信息,这部分将会在下面详细解释
Access-Control-Expose-Headers: 允许脚本访问的返回头,请求成功后,脚本可以在XMLHttpRequest中访问这些头的信息(貌似webkit没有实现这个)
Access-Control-Max-Age: 缓存此次请求的秒数。在这个时间范围内,所有同类型的请求都将不再发送预检请求而是直接使用此次返回的头作为判断依据,非常有用,大幅优化请求次数
Access-Control-Allow-Methods: 允许使用的请求方法,以逗号隔开
Access-Control-Allow-Headers: 允许自定义的头部,以逗号隔开,大小写不敏感
无论是预检请求或是实际请求,如果在Access-Control-Allow-Origin, Access-Control-Allow-Credentials, Access-Control-Allow-Methods, Access-Control-Allow-Headers的检查失败,就会被视为请求失败。
0x04 单独谈谈Credentials
在跨域请求中,默认情况下,HTTP Authentication信息,Cookie头以及用户的SSL证书无论在预检请求中或是在实际请求都是不会被发送的。
但是,通过设置XMLHttpRequest的credentials为true,就会启用认证信息机制。
虽然简单请求还是不需要发送预检请求,但是此时判断请求是否成功需要额外判断Access-Control-Allow-Credentials,如果Access-Control-Allow-Credentials为false,请求失败。
十分需要注意的的一点就是此时Access-Control-Allow-Origin不能为通配符"*"(真是便宜了一帮偷懒的程序员),如果Access-Control-Allow-Origin是通配符"*"的话,仍将认为请求失败
即便是失败的请求,如果返回头中有Set-Cookie的头,浏览器还是会照常设置Cookie
0x05 CORS中的安全隐患
最大的隐患就在于某些偷懒的程序员会将Access-Control-Allow-Origin设置为"*"从而使得这个CORS模型基本失效,但是由于Credentials模型的保护,很多网上的文章认为的信息泄露问题其实并不存在。在这里的风险其实是可以构造DDoS进行攻击。
另外就是我们会发现,虽然无法得到返回值,简单请求其实是发出的,所以POST请求是可以发出的。这时候,其实就和平常的CSRF一样了,所以并不是说保证了跨域请求限定的域就可以不做CSRF防范了。
转载自:http://drops.wooyun.org/tips/188
详解XMLHttpRequest的跨域资源共享的更多相关文章
- 详解SpringBoot应用跨域访问解决方案
一.什么是跨域访问 说到跨域访问,必须先解释一个名词:同源策略.所谓同源策略就是在浏览器端出于安全考量,向服务端发起请求必须满足:协议相同.Host(ip)相同.端口相同的条件,否则访问将被禁止,该访 ...
- 跨域详解之-----Jsonp跨域
一.通过jsonp跨域 在js中,我们直接用XMLHttpRequest请求不同域上的数据时,是不可以的.但是,在页面上引入不同域上的js脚本文件却是可以的,jsonp正是利用这个特性来实现的. 比如 ...
- 跨域资源共享CORS与JSONP
同源策略限制: 同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果没有同源策略,攻击者可以通过JavaScript获取你的邮件以及其他敏感信息,比如说 ...
- VUE SpringCloud 跨域资源共享 CORS 详解
VUE SpringCloud 跨域资源共享 CORS 详解 作者: 张艳涛 日期: 2020年7月28日 本篇文章主要参考:阮一峰的网络日志 » 首页 » 档案 --跨域资源共享 CORS 详解 ...
- 跨域资源共享 CORS 详解
CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing). 它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从 ...
- 跨域资源共享CORS详解
简介 CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing). 它允许浏览器向跨源服务器,发出XMLHttpRequest请 ...
- 跨域资源共享 CORS 详解(转)
add by zhj: 公司在一个web产品上,做前后端分离,前后端提供独立的服务,使用不同的域名,通过http进行交互,在 前端,会涉及到跨域访问的问题,前端使用了CORS,后端同时需要做相应修改, ...
- CORS(跨域资源共享)详解及与JSONP的对比
上篇讲解的JSONP的跨域请求方式,但是在浏览器的支持及请求方式上有局限性,接下来将介绍一种新的跨域请求方式CORS. CORS是一个W3C标准,全称是"跨域资源共享"(Cross ...
- [转] 跨域资源共享 CORS 详解
CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing). 它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从 ...
随机推荐
- MongoDB安装为Windows服务方法与注意事项
MongoDB作为一个基于分布式文件存储的数据库,近两年大受追捧.数据灵活的存取方式和高效的处理使得它广泛用于互联网应用. 最近本人开始在Windows 32位平台下研究MongoDB的使用,为了方便 ...
- SetFocus (GetDlgItem (hwnd, idFocus))函数的各参数的具体含义
Setfocus(HWMD hwnd):将窗口hwnd设置成获得焦点 GetDlgItem (hwnd, idFocus):此函数返回一个句柄 具体参数的含义: hwnd:包含该窗口标志位的对话框的句 ...
- Back to December -- Taylor Swift
Back to December 泰勒·斯威夫特(Taylor Swift),美国乡村音乐女创作歌手,会用木吉他.钢琴演奏. 曾获得美国乡村音 ...
- 个人项目:实现wc.exe(Java)
本项目Github地址:https://github.com/NNewBoy/wc 项目相关要求 基本功能:(已实现) -c 统计文件字符数 -w 统计文件词的数目 -l 统计文件行数 扩展功能:(已 ...
- Android-AndroidManifest.xml默认启动的Activity(探索篇01)
AndroidManifest.xml-->默认启动 MusicBrowserActivity <activity android:name=".MusicBrowserAct ...
- Spring Boot 2 实践记录之 MyBatis 集成的启动时警告信息问题
按笔者 Spring Boot 2 实践记录之 MySQL + MyBatis 配置 中的方式,如果想正确运行,需要在 Mapper 类上添加 @Mapper 注解. 但是加入此注解之后,启动时会出现 ...
- Asp.Net 跨域,Asp.Net MVC 跨域,Session共享,CORS,Asp.Net CORS,Asp.Net MVC CORS,MVC CORS
比如 http://www.test.com 和 http://m.test.com 一.简单粗暴的方法 Web.Config <system.web> <!--其他配置 省略……- ...
- .NET 日志工具 log4net使用
1.NuGet安装log4net. 2.修改配置文件 <?xml version="1.0"?> <configuration> <configSec ...
- Ubuntu安装Apache+PHP
1.Ubuntu 安装Apache 安装Apache sudo apt-get install apache2 修改端口号 打开 etc/apache2/port.config 修改 port 80 ...
- wpf数据绑定 - StringFormat的妙用
写在前面 WPF中常常有这样的情况:需要在UI上显示一些信息,比如显示一张图片的信息,信息结构是: 图片名:Xxx 图片尺寸:Xxx 而其中的 Xxx 通常通过数据绑定来获得, Xxx 前面的内容是需 ...