【41】WEB安全學習----CORS跨域安全
CORS
CORS需要瀏覽器和伺服器同時支援,目前,IE瀏覽器不能低於IE10。對於開發者來說,CORS通訊與同源的AJAX通訊沒有差別,程式碼完全一樣。瀏覽器一旦發現AJAX請求跨源,就會自動新增一些附加的頭資訊,有時還會多出一次附加的請求,但使用者不會有感覺。
因此,實現CORS通訊的關鍵是伺服器。只要伺服器實現了CORS介面,就可以跨源通訊。瀏覽器將CORS請求分成兩類:
- 簡單請求:發出CORS簡單請求,只需要在頭資訊之中增加一個Origin欄位,瀏覽器再對返回頭加以判斷以檢查請求的合法性,在檢查失敗時,瀏覽器將會阻止指令碼對返回內容的訪問。
- 非簡單跨域請求:會在正式通訊之前,增加一次HTTP查詢請求(OPTIONS方法),稱為"預檢"請求,來加以判斷,如果預檢失敗,實際請求將被丟棄。
只要同時滿足以下兩大條件,就屬於簡單請求。
- 請求方法是以下三種方法之一:
HEAD
GET
POST
2)HTTP的頭資訊不超出以下幾種欄位:
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type:只限於三個值application/x-www-form-urlencoded、multipart/form-data、text/plain
伺服器配置項解釋
Access-Control-Allow-Origin:
該欄位必填。它的值要麼是請求時Origin欄位的具體值,要麼是一個*,表示接受任意域名的請求。
Access-Control-Allow-Methods:
該欄位必填。它的值是逗號分隔的一個具體的字串或者*,表明伺服器支援的所有跨域請求的方法。注意,返回的是所有支援的方法,而不單是瀏覽器請求的那個方法。這是為了避免多次"預檢"請求。
Access-Control-Expose-Headers:
該欄位可選。CORS請求時,XMLHttpRequest物件的getResponseHeader()方法只能拿到6個基本欄位:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。如果想拿到其他欄位,就必須在Access-Control-Expose-Headers裡面指定。
Access-Control-Allow-Credentials:
該欄位可選。它的值是一個布林值,表示是否允許傳送Cookie.預設情況下,不發生Cookie,即:false。對伺服器有特殊要求的請求,比如請求方法是PUT或DELETE,或者Content-Type欄位的型別是application/json,這個值只能設為true。如果伺服器不要瀏覽器傳送Cookie,刪除該欄位即可。
Access-Control-Max-Age:
該欄位可選,用來指定本次預檢請求的有效期,單位為秒。在有效期間,不用發出另一條預檢請求。
客戶端配置項
Origin:
指定的源
Access-Control-Request-Method:
請求的方法,例如PUT, DELETE等等
Access-Control-Request-Headers:
自定義的頭部,所有用setRequestHeader方法設定的頭部都將會以逗號隔開的形式包含在這個頭中
CORS安全隱患
最大的隱患就在於某些偷懶的程式設計師會將Access-Control-Allow-Origin設定為"*"從而使得這個CORS模型基本失效。