同源策略及规避方法

所谓同源策略(Same origin policy),其实就是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。

何谓同源策略:

同源即是指域名、协议与端口相同,不同源的客户端脚本(JavaScript、ActionScript)在没明确授权的情况下,不能读写对方的资源。详细情况见下图:

同源策略及规避方法_第1张图片

同源策略的目的:

它的目的是为了保证用户信息的安全,防止恶意的网站窃取数据。

试想一下,如果你登录了某个人空间网站,该网站保存了你登录状态的cookie,而一个恶意网站可以随意读取该网站的cookie,那么事情就大条了,如果你没有退出登录状态,调皮一点的黑客可能会冒充你去发一张抠脚大汉卖萌的图片,吓坏你的朋友,而别有用心的黑客可能就会窃取你的个人信息去做一些违法乱纪的事情,Web世界将毫无安全可言!

同源策略具体限制那些行为:

总体来看。对于非同源情况,目前有如下严格限制:

a.Cookie、LocalStorage 和 IndexDB 无法读取

b.DOM 无法获得

c.AJAX 请求不能发送

虽然同源策略是为了用户安全考虑,但是用户的某些合理的请求却也遭到了限制,带来了一些不方便之处,所以,怎么样才能在合理情况下规避同源策略呢?

规避方法:

跨域资源共享CORS

CORS含义:

CORS是一个W3C标准,它允许浏览器跨越服务器,发出AJAX请求,从而克服AJAX的同源限制。

CORS与用户无关,浏览器会自动检测AJAX请求,若该请求跨域,则自动附加一些必要的请求头,无需用户多加操作,它实现的关键点在于服务器,只要服务器实现了CORS接口,那么就可以实现CORS跨源通信。

CORS请求分类:

对于一个CORS的HTTP请求来说,根据请求方法和HTTP请求头的不同,浏览器将其分为“简单请求”和“非简单请求”两种方式。

简单请求:满足以下两个条件的即为简单请求

a、请求方法为HEAD、GET、POST中的一种;

b、HTTP请求头不超过这些字段Accept、Accept-Language、Content-LanguageLast-Event-ID、Content-Type(只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain)

非简单请求:不同时满足上面两个条件的请求即为非简单请求

CORS简单请求实现方法:

a、用户发起跨源AJAX请求

b、浏览器检测该请求。若该请求为简单请求,则在请求头信息内添加如下字段并发送:

Origin: 协议+域名+端口

Origin字段:指明本次请求来自哪里

c、服务器接收到信息,检测该Origin字段是否在许可范围内

d、若该字段在许可范围内,则在响应头信息内添加如下字段后返回:

Access-Control-Allow-Origin: 协议+域名+端口
Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers:字段名称

Access-Control-Allow-Origin:(必须)该字段值有两种情况,与请求头Origin字段相同,表示同意该域名跨域访问,或者为一个星号“*”,表示接收任意域名访问。

Access-Control-Allow-Credentials:(可选)该字段值为一个布尔值,默认为true,表示服务器允许浏览器将cookie与请求一并发送给服务器。该字段有且仅有这一个值,若服务器不同意发送Cookie给自己,则删除该字段即可。另外,该字段必须搭配“withCredentials”属性使用。“withCredentials”属性默认为false,表示浏览器发送请求时不发送cookie凭据。若要发送,需设置为true,且“Access-Control-Allow-Origin”字段的值不可以为“*”,必须指定明确的、与请求网页一致的域名。总而言之,“withCredentials”属性告诉AJAX是否发送cookie凭据,“Access-Control-Allow-Credentials”告诉服务器是否接受cookie凭据,发送时,二者缺一不可。

Access-Control-Expose-Headers:(可选)该字段值为响应头的字段名称,默认情况下,XMLHttpRequest对象的getResponseHeader()方法只能获得6个基本字段。该值可以指定getResponseHeader()方法可以获得的其他字段的名称。

浏览器检测响应头有包含“Access-Control-Allow-Origin”字段,证明跨域成功,获得信息。

e、若该字段不在许可范围内,则不添加任何信息,正常返回HTTP响应

浏览器检测响应头没有包含“Access-Control-Allow-Origin”字段,证明跨域失败,抛出错误,该错误可被AJAX的onerror回调函数捕获。

CORS非简单请求实现方法:

a、用户发起跨源AJAX请求

b、浏览器检测该请求,若该请求为非简单请求,则浏览器在正式通信前发起一次“预检”请求

OPTIONS /cors HTTP/1.1
Origin: http://api.bob.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: X-Custom-Header
预检请求使用“options”方法,表示该请求为询问请求

一个关键字段“origin”:表示正式通信请求来自哪里

“Access-Control-Request-Method”:表示正式通信请求需要用到的请求方法

“Access-Control-Request-Headers”:表示正式通信请求需要使用的额外的头信息

c、服务器检测该预检请求提供的三个字段

d、若同意跨源通信,则在响应头信息内添加如下字段后返回:

Access-Control-Allow-Origin:协议+域名+端口
Access-Control-Allow-Methods:请求方式
Access-Control-Allow-Headers: 额外的请求头
Access-Control-Allow-Credentials: true
Access-Control-Max-Age: 预检请求有效期

Access-Control-Allow-Origin:(必须)该字段值有两种情况,与请求头Origin字段相同,表示同意该域名跨域访问,或者为一个星号“*”,表示接收任意域名访问。

Access-Control-Allow-Methods:(必须)该字段值为服务器允许的所有跨域方法,不限于预检中请求的字段,避免了请求方法不同而造成的多次预检。

Access-Control-Allow-Headers:(分情况)若请求头包含“Access-Control-Request-Headers”字段,则为必须,若请求头未包含“Access-Control-Request-Headers”字段则不需要。该字段指明服务器支持的所有头信息字段。

Access-Control-Allow-Credentials:(可选)与简单请求含义相同,具体见上文。

Access-Control-Max-Age:(可选)该字段表明了预检的有效期,在有效期内相同请求不必再次预检。

浏览器检测响应头有包含“Access-Control-Allow-Origin”字段,证明服务器同意该跨域通信,执行f步骤。

e、若不同意跨源通信,则不添加任何信息,正常返回HTTP响应

浏览器检测响应头没有包含“Access-Control-Allow-Origin”字段,证明服务器不同意该跨域通信,抛出错误,该错误可被AJAX的onerror回调函数捕获。

f、d步骤完成,证明同意跨源通信,则浏览器开始发送正式请求,具体方法与简单请求相同。


JSONP

JSONP含义:

JSONP(JSON with Padding)是JSON的一种“使用模式”,它是一个简单高效的跨域方式,HTML中的script标签可以加载并执行其他域的javascript,于是我们可以通过script标记来动态加载其他域的资源

JSONP实现原理:

用我觉得最通俗易懂的方式来概括就是:本地有一个函数,它拥有一个参数,这个参数就是我们要跨域获得的信息。我们通过

你可能感兴趣的:(Web安全)