根据同源策略,浏览器默认是不允许XMLHttpRequest对象问非同一站点下的资源的,即用ajax方式访问非同一域名下的资源会出错。比如当google要通过ajax去访问百度的数据,是不行的。

所谓同源,是要求协议,域名,端口都相同。

比如 http://www.aaa.com 和下列URL相比,都不属于同源。

https://www.aaa.com

http://www.aaa.com:8080

http://aaa.com

但下面这种属于同源:

http://username:password@www.aaa.com

禁用跨域访问资源是为了安全,但会牺牲便利性。因此就出现了好几种跨域访问资源的方法。其中一种是称之为CORS的技术(Cross-origin resource sharing)。

CORS的概念

所谓CORS(Cross-origin resource sharing ),是指通过XMLHttpRequest的ajax方式访问其他域名下资源,而不是在A域名的页面上点击打开一个B域名的页面。引入不同域上的js脚本文件也是没用问题的。出于安全考虑,跨域请求不能访问document.cookie对象。

CORS技术允许跨域访问多种资源,比如javascript,字体文件等,这种技术对XMLHttpRequest做了升级,使之可以进行跨域访问。但不是所有的浏览器都支持CORS技术。Firefox和Chrome等浏览器支持的比较好,稍微新一点的版本都支持。IE比较搓,IE10才真正支持这个机制,IE10以下需要用XDomainRequest这个对象,这是IE特有的。

当然不是说浏览器支持了就立刻可以跨域访问了,CORS技术中最重要的关键点是响应头里的Access-Control-Allow-Origin这个Header。 此Header是W3C标准定义的用来检查是可否接受跨域请求的一个标识。实现过程大致如下:A域名中发起跨域请求到B域名,B域名如果发送响应头Access-Control-Allow-Origin: A域名,那么A域名的这次跨域请求就能成功。反之则不成功。这里有一个称之为Preflighted requests 的步骤,这一步骤中,浏览器发起一个OPTIONS请求,去服务器验证是否支持跨域访问。(

用chrome去查看这个option请求始终看不到,只有当跨域访问请求非正常(比如本人笔误,将请求type的get误写成了gey)的情况下,才会看到有个OPTIONS请求,如图:

非常奇怪,不知道为何。

CORS的实现

举个例子。

有2个站点,分别绑定了www.myhost1.com和www.myhost2.com:8001这个两个域名。

假设www.myhost2.com:8001下的a.html文件,需要访问www.myhost1.com域名下的b.aspx文件,代码如下。

a文件代码如下,点击按钮就会去跨域访问b页面:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<!DOCTYPE html>  
< html  lang = "en"  xmlns="
http://www.w3.org/1999/xhtml
">    
< head >    
< meta  charset = "utf-8"  />    
< title >Apage</ title >    
< script  type = "text/javascript"  src="
http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.8.0.js
"></ script >    
< script >    
$(function () {    
var options = {    
type: 'get',    
url: "
http://www.myhost1.com/mysite/cors/b.aspx
",    
success: function (result) {    
alert(result);    
}    
};    
$("#btn1").click(function () {    
$.ajax(options);    
});    
});    
</ script >    
</ head >    
< body >    
< input  type = "button"  id = "btn1"  value = "load page b"  />    
</ body >    
</ html >

b文件为一个aspx文件,代码非常简单,显示时间

1
2
<%@ Page Language= "C#"  %>
<%=DateTime.Now%>

A文件的地址为http://www.myhost2.com:8001/a.html

A文件的请求是按照get方式读取的,当A文件点击按钮,会弹出B文件的内容。由于同源策略,会看到如下错误:

为了避免这个错误,在www.myhost1.com主机的Http响应标头里加上Access-Control-Allow-Origin:http://www.myhost2.com:8001,注意不要打上最后一个斜杠/,意思是允许http://www.myhost2.com:8001这个域名中的XMLHttpRequest对象跨域访问www.myhost1.com主机下的资源。

还有一种方法是修改web.config,Access-Control-Allow-Origin的值可以是通配符*,比如如下:

1
2
3
4
5
6
7
8
9
10
<? xml  version = "1.0"  encoding = "UTF-8" ?>
< configuration >
< system.webServer >
     < httpProtocol >
      < customHeaders >
        < add  name = "Access-Control-Allow-Origin"  value = "*"  />
      </ customHeaders >
    </ httpProtocol >
   </ system.webServer >
</ configuration >

或者通过代码添加响应标头来实现。

1
2
3
4
<%@ Page Language= "C#"  %>     
<%
Response.AppendHeader( "Access-Control-Allow-Origin" "http://www.myhost2.com:8001" );     %>
<%=DateTime.Now%>

当浏览器通过ajax请求访问其他域名下的资源时,如果那个资源的响应头中包含了Access-Control-Allow-Origin,则可以请求成功,否则就会失败,是否设置了响应头,可以在firebug等调试工具内看到。

无响应头

有响应头

跨域访问的风险

默认情况下,CORS机制不读取cookie值,即跨域访问时没有带上cookie,当需要跨域访问带cookie时,需要设置另一个文件头,Access-Control-Allow-Credentials,值为true。该选项设定了是否允许跨域请求带cookie。当设定为true后,对于XMLHttpRequest还需要设定withCredentials为true,在Jquery中为xhrFields: {withCredentials: true}

一旦允许了带cookie的跨域访问,那么遭到CSRF攻击的概率大大的增加了,比如之前的假设a.html页面内有一段恶意的js,它每隔1分钟去跨域请求用户b页面,并将请求后的数据偷偷的存入自己的数据库内。假设b页面需在要用户登录的情况下,可以请求到很多机密数据,比如信用卡号等,那当用户打开a页面后,在非授意的情况下,获取到b面值的内容,引发泄密。

对之前的演示代码做小的修改:

a页面代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<!DOCTYPE html>
< html  lang = "en"  xmlns = "http://www.w3.org/1999/xhtml" >
< head >
< meta 
charset = "utf-8"  />
< title >Apage</ title >
< script 
type = "text/javascript"  src = "http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.8.0.js" ></ script >
< script >
$(function 
() {
var options = {
type: 'get',
xhrFields: {withCredentials: true},
url: "http://www.myhost1.com/mysite/cors/b.aspx",
success: 
function (result) {
alert(result);
}
};
$("#btn1").click(function () 
{
$.ajax(options);
});
});
</ script >
</ head >
< body >
< input 
type = "button"  id = "btn1"  value = "load page b" 
/>
</ body >
</ html >

b.aspx页面代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<%@ Page Language= "C#"  AutoEventWireup= "true"  CodeBehind= "b.aspx.cs"  %>  
<%  
     Response.AppendHeader( "Access-Control-Allow-Origin" , "
http: //www.myhost2.com:8001
");  
     Response.AppendHeader( "Access-Control-Allow-Credentials" "true" );  
     if  (Session[ "islog" ] !=  null )  
     {  
         if  (Session[ "islog" ] ==  "1" )  
         {  
             Response.Write( "已登录,显示机密信息 " );  
         }  
     }  
     else  
     {  
         Response.Write( "未登录" );  
     }  
     if  (Request[ "login" ] ==  "true" )  
     {  
         Session[ "islog" ] =  "1" ;  
         Session.Timeout = 1;  
         Response.Write( "Login in OK" );  
     }  
%>  
<%=DateTime.Now%>

假设b页面的用户登录了一下,种植了一个session,那么就会有一个sessionid被存储到用户的cookie中去,此时,a页面点击按钮后,会获取b页面显示的内容,根据黑客的行为,可以有更大的破坏力。

演示图:当b页面未登录时,显示未登录。请求中不带cookie。

但是当b页面已经登录,则在a页面中的跨域请求中,带有cookie,会显示已登录的页面。

参考资料:

http://drops.wooyun.org/tips/188

http://en.wikipedia.org/wiki/Cross-origin_resource_sharing  
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS  
https://dev.opera.com/articles/dom-access-control-using-cors/  
http://blog.darkthread.net/post-2014-09-29-cors-options-preflight-and-iis.aspx

http://www.cnblogs.com/idche/p/3190926.html

本文转自cnn23711151CTO博客,原文链接:http://blog.51cto.com/cnn237111/1610917 ,如需转载请自行联系原作者

CORS机制及其风险相关推荐

  1. 跨域问题及CORS机制

    跨域 跨域是指一个资源请求与其不在同一个域(源)的资源,不在同一个域(源)是指两个域的协议.域名或端口不同. 同源策略 出于安全考虑,浏览器制定了同源策略, 限制了某些跨域请求.同源策略是跨域问题产生 ...

  2. http请求中必须具备哪个字段_HTTP访问控制(CORS)

    跨域资源共享(CORS) 是一种机制,它使用额外的 HTTP 头来告诉浏览器 让运行在一个 origin (domain) 上的Web应用被准许访问来自不同源服务器上的指定的资源.当一个资源从与该资源 ...

  3. 跨域 -- cors

    Origin . Host . Referer 1.1 Origin -简单请求 GET HTTP/2 Origin: https://h5test.selfshero.com Referrer Po ...

  4. 漫谈同源策略(SOP)和跨域资源共享(CORS)

    前言提要: ​ 面试的时候被问到了是否了解同源策略,并没有了解过 (虽然朋友洋写了文章,但是我当时也没有仔细琢磨).所以有了这篇文- ​ 据说了解同源策略是十分有必要的,要深入了解XSS/CSRF等w ...

  5. AI繁荣下的隐忧——Google Tensorflow安全风险剖析

    作者:[ Tencent Blade Team ] Cradmin 我们身处一个巨变的时代,各种新技术层出不穷,人工智能作为一个诞生于上世纪50年代的概念,近两年出现井喷式发展,得到各行各业的追捧,这 ...

  6. SAP Spartacus CORS 设置

    Cross-Origin Resource Sharing (CORS) CORS 是 Web 上的一种标准机制,它使来自 Web 应用程序的跨域请求能够到达不同域上的服务器. 只要响应中没有所需的 ...

  7. SpringBoot—CORS跨域问题详解和解决方案

    关注微信公众号:CodingTechWork,一起学习进步. 引言   在前后端开发过程中,遇到过一种错误,类似于报错: Access to XMLHttpRequest at 'http://127 ...

  8. 技术风险防控平台:打造金融交易系统的故障免疫能力

    摘要:以"数字金融新原力(The New Force of Digital Finance)"为主题,蚂蚁金服ATEC城市峰会于2019年1月4日上海如期举办.分论坛上,蚂蚁金服高 ...

  9. Cors跨域(一):深入理解跨域请求概念及其根因

    Talk is cheap. Show me the money. 前言 你好,我是YourBatman. 做Web开发的小伙伴对"跨域"定并不陌生,像狗皮膏药一样粘着几乎每位同学 ...

最新文章

  1. HTML学习笔记之基本介绍
  2. 【 MATLAB 】gallery 中的 uniformdata
  3. 识别哈希算法类型hash-identifier
  4. rust相框加载图片代码_Rust 能取代 Python,更好的实现神经网络?
  5. Win7输入法消失和不能切换的办法了
  6. ABAP实例:如何生成年月的输入帮助
  7. python中import sys_python import sys出错怎么办
  8. android 表情,软键盘冲突解决方案(仿微博等SNS应用)
  9. thinkphp3.2加载第三方函数库
  10. echarts里面的参数解释_SPMSM控制:传统PI速度环参数的整定
  11. 插入的数据不能时时查询到_漫谈 LevelDB 数据结构(一):跳表(Skip List)
  12. 阿里云OCR:(二)银行卡号识别
  13. AMS1117稳压芯片介绍
  14. 一份个人计算机能力研修总结,计算机 个人研修总结
  15. ROS重大功能,无线WISP和桥接
  16. 友盟用户反馈(官方文档学习而来)
  17. ambarella misc
  18. 阿里巴巴巨震,堪比地震
  19. 抖音如何找到博主视频推广?筛选博主要看那些数据
  20. win10无法装载iso文件_Windows 10更新后无法装载iso虚拟光盘

热门文章

  1. 大规模MIMO技术概述
  2. 在IDE中使用Bito - 一个不需要VPN就可以使用的chatgpt
  3. 【区块链】简单理解区块链是什么
  4. kettle简介及下载
  5. DMHS_DM7单向同步
  6. ADSP-21489的开发详解:VDSP+自己编程写代码开发(1-如何来做21489和21479的开发?简单说两句)
  7. 水气泵控制原理,三角波发生电路,LM331M/TR芯片,高速运放芯片
  8. 通过ganache与以太坊Dapp实现交互 —— 简单的例子
  9. MSYS2快速配置C++环境+ZSH
  10. 如何做好扁平化设计:交互篇(2)