CORS跨域资源共享漏洞

Posted 诡墨佯

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CORS跨域资源共享漏洞相关的知识,希望对你有一定的参考价值。

产生原因

同源策略(SOP)限制了应用程序之间的信息共享,并且仅允许在托管应用程序的域内共享。这有效防止了系统机密信息的泄露。但与此同时,也带来了另外的问题。随着Web应用程序和微服务使用的日益增长,出于实用目的往往需要将信息从一个子域传递到另一个子域,或者在不同域之间进行传递(例如将访问令牌和会话标识符,传递给另一个应用程序)。

为了允许跨域通信,开发人员必须使用不同的技术来绕过SOP并传递敏感信息,以至于现今也成为了一个棘手的安全问题。因此,为了在不影响应用程序安全状态的情况下实现信息共享,在html5中引入了跨源资源共享(CORS)。但问题也随之而来,许多人为了方便干脆直接使用默认的配置,或是由于缺乏对此的了解而导致了错误的配置。

CORS跨域资源共享

CORS(Cross-Origin Resource Sharing)跨源资源共享,是HTML5的一个新特性,其思想是使用自定义的HTTP头部让浏览器与服务器进行沟通,它允许浏览器向跨域服务器发出XMLHttpRequest请求,从而克服AJAX只能同源使用的限制。

CORS的基本原理是,第三方网站服务器生成访问控制策略,指定用户浏览器放宽 SOP 的限制,实现与指定的目标网站共享数据
 

CORS跨域漏洞的本质是服务器配置不当,即Access-Control-Allow-Origin取自请求头Origin字段,Access-Control-Allow-Credentials设置为true。导致攻击者可以构造恶意的脚本 , 诱导用户点击获取用户敏感数据
(PS:大部分漏洞的出现都是服务器配置不当。)
这里要注意的是,我们也可以测试下带有Access-Control-Allow-Origin: * 字段的网站是否有CORS漏洞,但是如果是如下组合,则没有漏洞,因为浏览器已经会阻止如下的配置。

1   Access-Control-Allow-Origin: *
2   Access-Control-Allow-Credentials: true
(PS:如果有上面两行,则不存在该漏洞。)
CORS中关键的几个响应头字段如下:

Access-Control-Allow-Origin:指定哪些外域可以访问本域资源;
Access-Control-Allow-Credentials:指定浏览器是否将使用请求发送Cookie。仅当设置为true时,才会发送Cookie;默认是false
Access-Control-Allow-Methods:指定可以使用哪些HTTP请求方法(GET、POST、PUT、DELETE等)来访问资源;
Access-Control-Allow-Headers:指定可以在请求报文中添加的HTTP头字段;
Access-Control-Max-Age:指定超时时间;

手工验证方式


在正常的api请求处,headers加入"origin":"http://xx.xx.xx.xx", 如果接口正常返回了数据且headers里包含

1  access-control-allow-credentials : true
2  access-control-allow-origin : http://xx.xx.xx.xx
就说明这个接口确实存在CORS漏洞

挖掘


使用burpsuite

选择Proxy模块中的Options选项,找到Match and Replace这一栏,勾选Request header 将空替换为Origin:foo.example.org的Enable框。

在Filter by search term 中输入:Access-Control-Allow-Origin: foo.example.org

 

 HTTP history列表中出现符合条件的请求包,点击Ctrl+R,点击GO,如下图,即该处有CORS漏洞。

组合应是这种:

Access-Control-Allow-Origin: foo.example.org
Access-Control-Allow-Credentials: true

注意!如下组合是没有漏洞的。因为浏览器已经会阻止如下配置。

Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true

 其他方法看

【漏洞利用】跨域资源共享(CORS)漏洞详解 - GorillaLee - 博客园 (cnblogs.com)

cors漏洞危害

攻击者构造恶意的html页面,利用链接诱导受害者进行点击,从而获取到受害者的敏感信息

相比之下,CORS较JSONP更为复杂,JSONP只能用于获取资源(即只读,类似于GET请求),而CORS支持所有类型的HTTP请求,功能完善

修复防范

  • 关闭非正式开启的CORS
  • 白名单限制:定义“源”的白名单,避免使用正则表达式,不要配置Access-Control-Allow-Origin为通配符*null,严格效验来自请求数据包中Origin的值
  • 仅允许使用安全协议,避免中间人攻击
  • 彻底的返回Vary: Origin右边,突破攻击者利用浏览器缓存进行攻击
  • 避免将Access-Control-Allow-Credentials标头设置为true 替换值,跨域请求若不存在必要的凭证数据,则根据实际情况将其设置为false
  • 限制跨域请求允许的方法,Access-Control-Allow-Methods替代地减少所涉及的方法,降低风险
  • 限制浏览器缓存期限:建议通过Access-Control-Allow-MethodsAccess-Control-Allow-Headers限制,限制浏览器缓存信息的时间。通过配置Access-Control-Max-Age标头来完成,该头部接收时间数作为输入,该数字是浏览器保存缓存的时间。的值,确保浏览器在短时间内可以更新策略
  • 仅在接收到跨域请求时才配置有关于跨域的头部,并确保跨域请求是合法的源,以减少攻击者恶意利用的可能性。

Nginx使用“逻辑与”配置origin限制,修复CORS跨域漏洞

目录

1.漏洞报告

  • 漏洞名称: CORS 跨域
  • 漏洞等级: 中危
  • 漏洞证明: Origin从任何域名都可成功访问,未做任何限制。
  • 漏洞危害: 因为同源策略的存在,不同源的客户端脚本不能访问目标站点的资源,如果目标站点并配置不当,没有对请求源的域做严格限制,导致任意源都可以访问时,就能在 CORS 跨域漏洞问题,CORS 漏洞一般用于窃取用户敏感数据,如果用户点击触发了而已页面,就会被盗取数据。
  • 解决建议: 修复方法是合理配置 CORS,判断 Origin 是否合法。具体说就是请求头不要配置 Access-Control-Allow-Origin*null

2.漏洞复现

复现方式为在 Header 中指定 Origin 请求头,看是否可以请求成功。

curl -H 'Origin:http://aaa.bbb' http://10.14.32.138:80

发现确实可以正常请求成功,开始修复。

3.Nginx 修复

3.1 添加请求头

location /myProject/api/ 
    add_header 'Access-Control-Allow-Origin' 'http://10.14.32.138:80' always;
    add_header 'Access-Control-Allow-Credentials' 'false'  always;

    include      proxy_params;
    proxy_pass   http://localhost:8081/;
    access_log   /tmp/httplogs/uat-mobileapi-access.log main;
    error_log    /tmp/httplogs/uat-mobileapi-error.log;

添加完毕,提交复测,发现即使添加了请求头配置,当origin为其他域名时仍能正常访问。

3.2 配置origin限制

进一步通过添加 origin 限制来修复,其他域名访问时,直接返回 403 状态码。

location /myProject/api/ 
    if ($http_origin !~* "(www.test.com|10.14.32.138)" ) 
        return 403;
    

    add_header 'Access-Control-Allow-Origin' 'http://10.14.32.138:80' always;
    add_header 'Access-Control-Allow-Credentials' 'false'  always;

    include      proxy_params;
    proxy_pass   http://localhost:8081/;
    access_log   /tmp/httplogs/uat-mobileapi-access.log main;
    error_log    /tmp/httplogs/uat-mobileapi-error.log;

配置之后,发现虽然跨域请求被限制住了,但是页面上的请求也无法访问了。

排查发现,页面上请求时不会传 Origin 请求头,所以也返回 403 状态码了。

2.3 调整origin限制

需要将 Origin 限制改为 Origin 为空也可以正常访问。

location /myProject/api/ 
    set $allow_cors 0;
    # 判断不为空
    if ($http_origin) 
        set $allow_cors 1;
    
    # 判断不在白名单内
    if ($http_origin !~* "(www.test.com|10.14.32.138)" ) 
        set $allow_cors "$allow_cors1";
    
    # 判断不为空 且 不在白名单内,返回403
    if ($allow_cors = "11") 
        return 403;
    

    add_header 'Access-Control-Allow-Origin' 'http://10.14.32.138:80' always;
    add_header 'Access-Control-Allow-Credentials' 'false'  always;

    include      proxy_params;
    proxy_pass   http://localhost:8081/;
    access_log   /tmp/httplogs/uat-mobileapi-access.log main;
    error_log    /tmp/httplogs/uat-mobileapi-error.log;

配置之后,复测通过,页面也可以正常访问了。

整理完毕,完结撒花~





参考地址:

1.Nginx配置origin限制跨域请求(应对等保),https://blog.csdn.net/qq_20236937/article/details/128640137

2.Nginx:如果头不存在或错误,则拒绝请求,https://www.it1352.com/1679888.html

3.NGINX实现IF语句里的AND,OR多重判断,https://blog.51cto.com/qiangsh/1967549

以上是关于CORS跨域资源共享漏洞的主要内容,如果未能解决你的问题,请参考以下文章

CORS跨域资源共享漏洞初探

跨域资源共享(CORS)-漏洞整理

CORS跨域资源共享漏洞

安全系列之:跨域资源共享CORS

Jsonp&Cors跨域(同源策略跨域劫持漏洞)

Nginx使用“逻辑与”配置origin限制,修复CORS跨域漏洞