「給 API 加上 Access-Control-Allow-Origin 之後就能用了,但這樣安全嗎?」——CORS 並不是「加上就 OK」,關鍵在於把許可的對象收緊。本文講解它的原理和安全的設定方法(不會寫出攻擊步驟)。
先講原理
瀏覽器有一條同源政策:其他來源的 JS 不能擅自讀取其他網站的回應。CORS 就是用來把這條規則的例外只對伺服器明確許可的對象打開的機制。
| 回應標頭 | 含義 |
|---|---|
Access-Control-Allow-Origin | 允許哪個來源讀取回應 |
Access-Control-Allow-Credentials | 是否允許帶 Cookie 等認證資訊的通訊 |
Access-Control-Allow-Methods / -Headers | 允許的 HTTP 方法/標頭 |
關鍵在於,CORS 是屬於「放寬限制」那一側的機制。放寬的方式一旦出錯,本不該被讀取的資料就會被第三方讀到。
哪些設定是危險的
危險的設定(容易犯)
- 把請求的 Origin 原樣反射回去並予以許可
Access-Control-Allow-Origin: *+ 同時允許認證資訊- 把不必要的 API 也大範圍地對其他來源開放
安全的設定
- 白名單(只放可信任的固定來源)
- 其他一律預設拒絕
- 帶認證資訊時不用
*,而指定具體的來源
安全設定的基本原則
採用白名單方式(最重要)
不要不加判斷地反射 Origin
Origin 原樣 echo 到 Access-Control-Allow-Origin。只有與白名單比對一致時才回傳。帶認證資訊時不要用 *
Access-Control-Allow-Origin: * 與 Allow-Credentials: true 同時使用。要指定具體的來源。把開放範圍降到最小
延伸閱讀
FAQ
QCORS 是做什麼用的機制?
瀏覽器有一條「同源政策」:另一個來源(網站)的 JavaScript 不能擅自讀取其他網站的回應。CORS(Cross-Origin Resource Sharing)就是用來把這條規則的例外「只對伺服器明確許可的對象」打開的機制。它透過 Access-Control-Allow-Origin 等回應標頭,宣告允許哪些來源讀取回應。
QCORS 設定錯誤會引發什麼?
如果許可放得太寬,攻擊者網站的 JavaScript 就可能讀取到使用者已登入的 API 回應。典型例子是:把請求的 Origin 原樣反射回去並予以許可,或者把 Access-Control-Allow-Origin 設為 * 的同時還允許認證資訊(Cookie 等)。結果就是個人資訊或權杖可能被交到第三方網站手裡。
Q安全設定的基本原則是什麼?
就是「白名單方式」。只許可事先確定的、可信任的來源,其他一律拒絕(預設拒絕)。不要不加判斷地反射請求裡的 Origin。在帶認證資訊的通訊中,Access-Control-Allow-Origin 不要用 *,而要指定具體的來源。最根本的是,只把確實需要對其他來源公開的端點作為對象。