一、X-Frame-Options
這個header主要用來配置哪些網站可以通過frame來加載資源。它主要是用來防止UI redressing 補償樣式攻擊。IE8和firefox 18以后的版本都開始支持ALLOW-FROM。chrome和safari都不支持ALLOW-FROM,但是WebKit已經在研究這個了。
X-Frame-Options 響應頭有三個可選的值:
DENY:頁面不能被嵌入到任何iframe或frame中;
SAMEORIGIN:頁面只能被本站頁面嵌入到iframe或者frame中;
ALLOW-FROM:頁面允許frame或frame加載。
// 正確的設置
DENY – 禁止所有的資源(本地或遠程)試圖通過frame來加載其他也支持X-Frame-Options 的資源。 SAMEORIGIN – 只允許遵守同源策略的資源(和站點同源)通過frame加載那些受保護的資源。 ALLOW-FROM http://www.example.com – 允許指定的資源(必須帶上協議http或者https)通過frame來加載受保護的資源。
這個配置只在IE和firefox下面有效。其他瀏覽器則默認允許任何源的資源(在X-Frame-Options沒設置的情況下)。 // 通常不正確的設置 ALLOW FROM http://example.com – ALLOW和FROM 之間只能通過連字符來連接,空格是錯誤的。
ALLOW-FROM example.com – ALLOW-FROM選項后面必須跟上一個URI而且要有明確的協議(http或者https)
二、X-XSS-Protection
顧名思義,這個響應頭是用來防范XSS的。最早我是在介紹IE8的文章里看到這個,現在主流瀏覽器都支持,並且默認都開啟了XSS保護,用這個header可以關閉它。它有幾種配置:
0:禁用XSS保護;
1:啟用XSS保護;
1; mode=block:啟用XSS保護,並在檢查到XSS攻擊時,停止渲染頁面(例如IE8中,檢查到攻擊時,整個頁面會被一個#替換);
// nginx配置設置
... ... server { ... ... add_header X-XSS-Protection 1; ... ...
HTML前端解決方法:
<meta http-equiv="X-XSS-Protection" content="1; mode=block" />
這個header主要是用來防止瀏覽器中的反射性xss。現在,只有IE,chrome和safari(webkit)支持這個header。
// 正確的設置
0 – 關閉對瀏覽器的xss防護 1 – 開啟xss防護 1; mode=block – 開啟xss防護並通知瀏覽器阻止而不是過濾用戶注入的腳本。 1; report=http://site.com/report – 這個只有chrome和webkit內核的瀏覽器支持,這種模式告訴瀏覽器當發現疑似xss攻擊的時候就將這部分數據post到指定地址。 // 通常不正確的設置
0; mode=block; – 記住當配置為0的時候,即使加了mode=block選項也是沒有效果的。需要指出的是,chrome在發現這種錯誤的配置后還是會開啟xss防護。 1 mode=block; – 數字和選項之間必須是用分號分割,逗號和空格都是錯誤的。但是這種錯誤配置情況下,IE和chrome還是默認會清洗xss攻擊,但是不會阻攔。
如何檢測?
如果過濾器檢測或阻攔了一個反射性xss以后,IE會彈出一個對話框。當設置為1時,chrome會隱藏對反射性xss的輸出。如果是設置為 1; mode=block ,那么chrome會直接將user-agent置為一個空值:, URL 這種形式。
三、X-Content-Type-Options
互聯網上的資源有各種類型,通常瀏覽器會根據響應頭的Content-Type字段來分辨它們的類型。例如:"text/html"代表html文檔,"image/png"是PNG圖片,"text/css"是CSS樣式文檔。然而,有些資源的Content-Type是錯的或者未定義。這時,某些瀏覽器會啟用MIME-sniffing來猜測該資源的類型,解析內容並執行。
例如,我們即使給一個html文檔指定Content-Type為"text/plain",在IE8-中這個文檔依然會被當做html來解析。利用瀏覽器的這個特性,攻擊者甚至可以讓原本應該解析為圖片的請求被解析為JavaScript。
這個header主要用來防止在IE9、chrome和safari中的MIME類型混淆攻擊。firefox目前對此還存在爭議。通常瀏覽器可以通過嗅探內容本身的方法來決定它是什么類型,而不是看響應中的content-type值。通過設置 X-Content-Type-Options:如果content-type和期望的類型匹配,則不需要嗅探,只能從外部加載確定類型的資源。舉個例子,如果加載了一個樣式表,那么資源的MIME類型只能是text/css。
// 正確的設置
nosniff – 這個是唯一正確的設置,必須這樣。 // 通常不正確的設置
‘nosniff’ – 引號是不允許的 : nosniff – 冒號也是錯誤的
如何檢測?
在IE和chrome中打開開發者工具,在控制台中觀察配置了nosniff和沒有配置nosniff的輸出有啥區別。
四、如何避免
通過下面這個響應頭可以禁用瀏覽器的類型猜測行為
打開nginx.conf,文件位置一般在安裝目錄 /usr/local/nginx/conf 里。
然后在http配置代碼塊里某一行添加如下語句即可
add_header X-Frame-Options "SAMEORIGIN"; add_header X-XSS-Protection "1; mode=block"; add_header X-Content-Type-Options "nosniff";
五、Strict-Transport-Security
Strict Transport Security (STS) 是用來配置瀏覽器和服務器之間安全的通信。它主要是用來防止中間人攻擊,因為它強制所有的通信都走TLS。目前IE還不支持 STS頭。需要注意的是,在普通的http請求中配置STS是沒有作用的,因為攻擊者很容易就能更改這些值。為了防止這樣的現象發生,很多瀏覽器內置了一 個配置了STS的站點list。
// 正確的設置 // 注意下面的值必須在https中才有效,如果是在http中配置會沒有效果。
max-age=31536000 – 告訴瀏覽器將域名緩存到STS list里面,時間是一年。 max-age=31536000; includeSubDomains – 告訴瀏覽器將域名緩存到STS list里面並且包含所有的子域名,時間是一年。 max-age=0 – 告訴瀏覽器移除在STS緩存里的域名,或者不保存此域名。 // 通常不正確的設置 // 直接將includeSubDomains設置為 https://www.example.com ,但是用戶依然可以通過 http://example.com 來訪問此站點。如果example.com 並沒有跳轉到 https://example.com 並設置 STS header,那么訪問 http://www.example.com 就會直接被瀏覽器重定向到 https://www.example.com 。
max-age=60 – 這個只設置域名保存時間為60秒。這個時間太短了,可能並不能很好的保護用戶,可以嘗試先通過http來訪問站點,這樣可以縮短傳輸時間。 max-age=31536000 includeSubDomains – max-age 和 includeSubDomains 直接必須用分號分割。這種情況下,即使max-age的值設置的沒有問題,chrome也不會將此站點保存到STS緩存中。 max-age=31536000, includeSubDomains – 同上面情況一樣。 max-age=0 – 盡管這樣在技術上是沒有問題的,但是很多站點可能在處理起來會出差錯,因為0可能意味着永遠不過期。
如何檢測
判斷一個主機是否在你的STS緩存中,chrome可以通過訪問chrome://net-internals/#hsts,首先,通過域名請求選 項來確認此域名是否在你的STS緩存中。然后,通過https訪問這個網站,嘗試再次請求返回的STS頭,來決定是否添加正確。
六、Access-Control-Allow-Origin
Access-Control-Allow-Origin是從Cross Origin Resource Sharing (CORS)中分離出來的。這個header是決定哪些網站可以訪問資源,通過定義一個通配符來決定是單一的網站還是所有網站可以訪問我們的資源。需要注意的是,如果定義了通配符,那么 Access-Control-Allow-Credentials選項就無效了,而且user-agent的cookies不會在請求里發送。
// 正確的設置
* – 通配符允許任何遠程資源來訪問含有Access-Control-Allow-Origin 的內容。 http://www.example.com – 只允許特定站點才能訪問(http://[host], 或者 https://[host]) // 通常不正確的設置
http://example.com, http://web2.example.com – 多個站點是不支持的,只能配置一個站點。
*.example.com – 只允許單一的站點 http://*.example.com – 同上面一樣
如何檢測?很容易就能確定這個header是否被設置的正確,因為如果設置錯誤的話,CORS請求就會接收不到數據。