安全相關的Http響應頭

一、前言

近期在翻閱 laravel文檔 時,發現官方推薦的nginx配置中有如下幾條設置:

add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options "nosniff";

雖然之前也有留意到,但是並沒有理會過它們,於是這次查閱了一下,並順手整理了這篇文章。

二、常見的安全相關HTTP響應頭介紹

X-Frame-Options

X-Frame-Options 是爲了減少點擊劫持(Clickjacking)而引入的一個響應頭。Chrome4+、Firefox3.6.9+、IE8+均支持,詳細的瀏覽器支持情況看這裏

使用方式如下:

x-frame-options: SAMEORIGIN

這個響應頭支持三種配置:

  • DENY:不允許被任何頁面嵌入;
  • SAMEORIGIN:不允許被本域以外的頁面嵌入;
  • ALLOW-FROM uri:不允許被指定的域名以外的頁面嵌入(Chrome現階段不支持);

原文鏈接

如果某頁面被不被允許的頁面以<iframe><frame>的形式嵌入,IE會顯示類似於“此內容無法在框架中顯示”的提示信息,ChromeFirefox都會在控制檯打印信息。由於嵌入的頁面不會加載,這就減少了點擊劫持的發生。

X-XSS-Protection

顧名思義,這個響應頭是用來防範XSS的,它有幾種配置:

0:禁用XSS保護;
1:啓用XSS保護;
1; mode=block:啓用XSS保護,並在檢查到XSS攻擊時,停止渲染頁面(例如IE8中,檢查到攻擊時,整個頁面會被一個#替換);

瀏覽器提供的XSS保護機制並不完美,但是開啓後仍然可以提升攻擊難度,如果沒有特殊需要,建議開啓它。

X-Content-Type-Options

互聯網上的資源有各種類型,通常瀏覽器會根據響應頭的 Content-Type 字段來分辨它們的類型。
例如:text/html 代表html文檔,image/png是PNG圖片,text/css是CSS樣式文檔。

然而,有些資源的 Content-Type 是錯的或者未定義。這時,某些瀏覽器會啓用 MIME-sniffing 來猜測該資源的類型,解析內容並執行。
例如,我們即使給一個html文檔指定Content-Typetext/plain,在IE8-中這個文檔依然會被當做html來解析。利用瀏覽器的這個特性,攻擊者甚至可以讓原本應該解析爲圖片的請求被解析爲JavaScript。

通過下面這個響應頭可以禁用瀏覽器的類型猜測行爲:

X-Content-Type-Options: nosniff

這個響應頭的值只能是 nosniff,可用於IE8+和Chrome。另外,它還被Chrome用於擴展下載,見這裏

Strict-Transport-Security

HTTP Strict Transport Security,簡稱爲 HSTS 。它允許一個HTTPS網站,要求瀏覽器總是通過HTTPS來訪問它。
現階段,除了Chrome瀏覽器,Firefox4+,以及Firefox的NoScript擴展都支持這個響應頭。

我們知道HTTPS相對於HTTP有更好的安全性,而很多HTTPS網站,也可以通過HTTP來訪問。開發人員的失誤或者用戶主動輸入地址,都有可能導致用戶以HTTP訪問網站,降低了安全性。一般,我們會通過Web Server發送301/302重定向來解決這個問題。
現在有了HSTS,可以讓瀏覽器幫你做這個跳轉,省一次HTTP請求。另外,瀏覽器本地替換可以保證只會發送HTTPS請求,避免被劫持。

要使用HSTS,只需要在你的HTTPS網站響應頭中,加入下面這行:

strict-transport-security: max-age=16070400; includeSubDomains

includeSubDomains 是可選的,用來指定是否作用於子域名。支持HSTS的瀏覽器遇到這個響應頭,會把當前網站加入HSTS列表,然後在max-age指定的秒數內,當前網站所有請求都會被重定向爲https。即使用戶主動輸入http://或者不輸入協議部分,都將重定向到https://地址。

Chrome內置了一個HSTS列表,默認包含Google、Paypal、Twitter、Linode等等服務。我們也可以在Chrome輸入chrome://net-internals/#hsts,進入HSTS管理界面。在這個頁面,你可以增加/刪除/查詢HSTS記錄。例如,你想一直以https訪問某網址,通過“add Domain”加上去就好了。
查看Chrome內置的全部HSTS列表,或者想把自己的網站加入這個列表,請點這裏

X-Content-Security-Policy

Content Security Policy,簡稱 CSP。顧名思義,這個規範與內容安全有關,主要是用來定義頁面可以加載哪些資源,減少 XSS 的發生。

要使用 CSP,只需要服務端輸出類似這樣的響應頭就行了:

Content-Security-Policy: default-src 'self'

default-src 是 CSP 指令,多個指令之間用英文分號分割;‘self’ 是指令值,多個指令值用英文空格分割。目前,有這些 CSP 指令:

指令 指令值示例 說明
default-src ‘self’ cnd.a.com 定義針對所有類型(js、image、css、web font,ajax 請求,iframe,多媒體等)資源的默認加載策略,某類型資源如果沒有單獨定義策略,就使用默認的。
script-src ‘self’ js.a.com 定義針對 JavaScript 的加載策略。
style-src ‘self’ css.a.com 定義針對樣式的加載策略。
img-src ‘self’ img.a.com 定義針對圖片的加載策略。
connect-src ‘self’ 針對 Ajax、WebSocket 等請求的加載策略。不允許的情況下,瀏覽器會模擬一個狀態爲 400 的響應。
font-src font.a.com 針對 WebFont 的加載策略。
object-src ‘self’ 針對 <object><embed><applet> 等標籤引入的 flash 等插件的加載策略。
media-src media.a.com 針對 <audio><video> 等標籤引入的 HTML 多媒體的加載策略。
frame-src ‘self’ 針對 frame 的加載策略。
sandbox allow-forms 對請求的資源啓用 sandbox(類似於 iframe 的 sandbox 屬性)。
report-uri /report-uri 告訴瀏覽器如果請求的資源不被策略允許時,往哪個地址提交日誌信息。 特別的:如果想讓瀏覽器只彙報日誌,不阻止任何內容,可以改用 Content-Security-Policy-Report-Only 頭。

從上面的介紹可以看到,CSP 協議可以控制的內容非常多。而且如果不特別指定 unsafe-inline 時,頁面上所有 inline 樣式和腳本都不會執行;不特別指定 unsafe-eval,頁面上不允許使用 new FunctionsetTimeouteval 等方式執行動態代碼。在限制了頁面資源來源之後,被 XSS 的風險確實小不少。

當然,僅僅依靠 CSP 來防範 XSS 是遠遠不夠的,不支持全部瀏覽器是它的硬傷。不過,鑑於低廉的開發成本,加上也沒什麼壞處。

三、頭部互聯網公司安全http頭的使用情況

最後,我們來看看幾個實際案例:

Google+,使用了這幾個本文提到的響應頭:

x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
x-xss-protection: 1; mode=block

Twitter使用了這些:

strict-transport-security: max-age=631138519
x-frame-options: SAMEORIGIN
x-xss-protection: 1; mode=block

Facebook則使用了這些(配置了詳細的CSP,關閉了XSS保護):

strict-transport-security: max-age=60
x-content-type-options: nosniff
x-frame-options: DENY
x-xss-protection: 0
content-security-policy: default-src *;script-src https://*.facebook.com http://*.facebook.com https://*.fbcdn.net http://*.fbcdn.net *.facebook.net *.google-analytics.com *.virtualearth.net *.google.com 127.0.0.1:* *.spotilocal.com:* chrome-extension://lifbcibllhkdhoafpjfnlhfpfgnpldfl 'unsafe-inline' 'unsafe-eval' https://*.akamaihd.net http://*.akamaihd.net;style-src * 'unsafe-inline';connect-src https://*.facebook.com http://*.facebook.com https://*.fbcdn.net http://*.fbcdn.net *.facebook.net *.spotilocal.com:* https://*.akamaihd.net ws://*.facebook.com:* http://*.akamaihd.net https://fb.scanandcleanlocal.com:*;

淘寶、京東、微博等都開啓了 strict-transport-security

strict-transport-security: max-age=31536000

四、結語

我們大致瞭解這些header頭的作用和使用方式後,可以在平時嘗試增加這些設置,而不只限於web server的默認配置,就laravel而言,官方既然推薦使用了,那首先要弄明白,至於是否啓用,再依照實際情況判斷。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章