HTTP 安全頭速覽

書(shū)接上文——《JS 安全策略》,我們速覽了一些 Web 開(kāi)發(fā)中常見(jiàn)到的安全策略;本文繼續(xù)展開(kāi),講講另一種Web防御策略——HTTP安全標(biāo)頭(Security Header)。

概述

HTTP Headers 是客戶端和服務(wù)器在 HTTP 傳輸過(guò)程中添加的附屬信息抠璃。一個(gè)請(qǐng)求頭由名稱(不區(qū)分大小寫(xiě))后跟一個(gè)冒號(hào):,再跟一個(gè)具體的值(不帶換行符)組成脱惰。常見(jiàn)的 Http 頭有好多種搏嗡,如:

  • auth 類(lèi):Authorization,WWW-Authenticate,Proxy-Authenticate 等等
  • cache 類(lèi):Age采盒,Expires旧乞,Cache-Control 等等
  • 條件請(qǐng)求類(lèi):If-Match,If-Modified-Since 等等

上面這些標(biāo)頭應(yīng)該是耳熟能詳了磅氨;不過(guò)尺栖,對(duì)于安全類(lèi)的 HTTP 頭,我問(wèn)了周邊的小伙伴烦租,很多人都不熟悉延赌;所以,這期就借機(jī)介紹幾個(gè)非常實(shí)用的安全頭叉橱,大家看看自己用過(guò)幾個(gè)挫以。

Trusted Types (可信任類(lèi)型)

我們從之前提過(guò)的可信任類(lèi)型說(shuō)起。Trusted Types 主要用于防御基于 DOM 的跨站點(diǎn)腳本攻擊(DOM-based XSS)窃祝。

DOM-based XSS: 一種將惡意數(shù)據(jù)傳遞給動(dòng)態(tài)語(yǔ)言接收器的攻擊手段屡贺;在 JS 語(yǔ)言中,最常被攻擊的接收器就是: eval().innerHTML 了锌杀。

Trusted Types 就是一種黑名單機(jī)制,限制那些有安全隱患的 Web API 被瀏覽器調(diào)用泻仙。除此之外糕再,主流的瀏覽器廠商現(xiàn)在都提供了一個(gè)特殊的對(duì)象來(lái)代替上述 API,人稱 trustedTypes玉转。

啟用 Trusted Types 的方法很簡(jiǎn)單突想,服務(wù)器返回的 HTTP 消息中帶上如下安全頭即可:

Content-Security-Policy: require-trusted-types-for 'script'

啟用后,如下代碼——修改.innerHTML——就會(huì)直接拋出異常了究抓。

el.innerHTML = "<img src=x onerror=alert(1)>"; // This throws an exception.

至于替代手段猾担,就是利用 trustedTypes 生成的字符串繞開(kāi)檢查罷了。下例中刺下,通過(guò)使用 trustedTypes绑嘹,讓開(kāi)發(fā)人員有意識(shí)地把 inner html 中的 tag 標(biāo)簽——<>——替換為特殊符號(hào)(&lt&gt)以防止 XSS 注入。

const policy = trustedTypes.createPolicy("escapePolicy", {
  createHTML: (str) => {
    return str.replace(/\</g, "&lt;").replace(/>/g, "&gt;");
  },
});

// accepted operation
const escaped = policy.createHTML("<img src=x onerror=alert(1)>");
el.innerHTML = escaped; // '&lt;img src=x onerror=alert(1)&gt;'

Content Security Policy(CSP)

CSP 我們講過(guò)很多次橘茉,我們?cè)倏焖龠^(guò)一遍工腋。CSP 主要用于阻止跨站點(diǎn)腳本執(zhí)行的一種安全策略。通常建議所有的 Web 應(yīng)用都開(kāi)啟 CSP:

  • 如果是服務(wù)端渲染的腳本畅卓,請(qǐng)至少啟用 CSP 的 nonce 機(jī)制
  • 如果是靜態(tài)資源器托管的腳本擅腰,請(qǐng)至少啟用 CSP 的 Integrity 機(jī)制

X-Content-Type-Options

部分瀏覽器(如 IE < 8.0)會(huì)出現(xiàn)一種加 MIME 混淆的情況。舉個(gè)通俗的例子翁潘,某些圖片會(huì)包含一些合法的 HTML 標(biāo)記(大家懂的)趁冈,當(dāng)那些瀏覽器加載這類(lèi)圖片時(shí)會(huì)執(zhí)行里面的 HTML 腳本,引發(fā)所謂的基于 MIME 的腳本攻擊拜马。

但是渗勘,如果服務(wù)器響應(yīng)標(biāo)頭里加上 X-Content-Type-Options: nosniff沐绒,這種攻擊就可以避免了。因?yàn)榇藭r(shí)的瀏覽器將強(qiáng)制要求加載的資源帶上 MINE 類(lèi)型描述——Content-Type呀邢,不然拋出異常洒沦,比如 IE 的異常如下:

SEC7112: Script from http://xxx.com was blocked due to mime type mismatch script.asp

而對(duì)于帶有 MIME 類(lèi)型的圖片資源(如image/jpeg),瀏覽器將視作靜態(tài)資源价淌,就不會(huì)繼續(xù)執(zhí)行里面的腳本了申眼。

X-Frame-Options

X-Frame-Options 顧名思義蝉衣,和 iframe 嵌入相關(guān)的安全頭了。部分網(wǎng)站可能會(huì)將你的網(wǎng)頁(yè)當(dāng)作 iframe 嵌入濒翻,然后劫持你的用戶操作有送;一些不明真相的用戶會(huì)被劫持的反饋引向不安全的網(wǎng)站,或是泄露敏感信息雀摘。這就是經(jīng)典的 Spectre-type attacks(幽靈漏洞攻擊)阵赠。

假如你不打算別人嵌入你的網(wǎng)站肌稻,那就帶一個(gè)安全頭 X-Frame-Options: DENY,它的<frame>枷邪、<iframe>齿风、<embed><object> 就對(duì)你失效了救斑。

HTTP Strict Transport Security (HSTS)

HSTS這個(gè)頭也很容易理解:強(qiáng)制使用 HTTPS 傳輸。HTTP 是不加密的連接脸候,容易被網(wǎng)絡(luò)竊聽(tīng)者截取运沦,開(kāi)啟Strict-Transport-Security 頭后携添,瀏覽器將不再加載 HTTP 相關(guān)的資源的,取而代之的是HTTPS資源羞秤。

Strict-Transport-Security: max-age=31536000

Cross-Origin(跨域)

還有一些常見(jiàn)的安全機(jī)制與跨域相關(guān)瘾蛋,我們快速過(guò)一下:

  • Cross-Origin Resource Policy (CORP)

    瀏覽器的默認(rèn)機(jī)制是同源策略矫限,即不能加載跨域資源。但是取董,有些情況下我們想改變這種默認(rèn)機(jī)制甲葬,這時(shí)就可以啟用 CORP 了懈贺。CORP 只接受三個(gè)值:same-originsame-sitecross-origin梭灿,顧名思義同源(默認(rèn))堡妒、同站點(diǎn)皮迟,以及接受跨域資源三種策略伏尼。

    Cross-Origin-Resource-Policy: same-origin
    
  • Cross-Origin Resource Sharing (CORS)

    上面提到瀏覽器同源策略,開(kāi)啟同源后爆阶,我們可以通過(guò)添加白名單的形式應(yīng)對(duì)一些特殊站點(diǎn)辨图,這就是著名的 CORS 了。你只要把信任的網(wǎng)站加到安全頭上吱韭,指定的跨域資源就允許加載了:

    Access-Control-Allow-Origin: https://example.com
    Access-Control-Allow-Credentials: true
    
  • Cross-Origin Embedder Policy (COEP)

    COEP(跨源嵌入程序政策)通常與 CORP 和 CORS 結(jié)合使用理盆,讓嵌入你站點(diǎn)的資源(script 或 worker)也只能加載在 CORP 或是 CORS 配置后的跨域資源鸳吸。啟用方式如下:

    Cross-Origin-Embedder-Policy: require-corp
    

    COEP 的好處是開(kāi)啟跨域隔離,你可以通過(guò) if( self.crossOriginIsolated ) {...} 來(lái)判斷坎拐。隔離成功后哼勇,就可以使用瀏覽器默認(rèn)禁止了的 SharedArrayBuffer呕乎、performance.measureUserAgentSpecificMemory()等一些 JS Self-Profiling API 了猬仁。

  • Cross-Origin Opener Policy (COOP)

    COOP 主要應(yīng)對(duì)的是用戶隱私策略湿刽,一些網(wǎng)站通過(guò) window.open() 或是 target="_blank" 的形式在瀏覽器新標(biāo)簽內(nèi)打開(kāi)其他網(wǎng)站;但是這種操作會(huì)被對(duì)方網(wǎng)站獲取到溯源信息渴庆,造成用戶隱私泄露或發(fā)起其他有害攻擊襟雷。為了避免這種意外仁烹,我們通產(chǎn)會(huì)價(jià)格 COOP 頭,防止用戶隱私泄露:

    Cross-Origin-Opener-Policy: same-origin-allow-popups
    

小結(jié)

本文列出了一些保護(hù)站點(diǎn)安全的 HTTP 標(biāo)頭叙赚。大家回去后也可以自我審查一下項(xiàng)目里有沒(méi)有使用到這些頭;如果沒(méi)有的話胧砰,要盡快開(kāi)啟尉间。這些都是久經(jīng)考驗(yàn)的策略哲嘲,開(kāi)啟后百利無(wú)一弊的眠副。

文章同步發(fā)布于an-Onion 的 Github竣稽。碼字不易,歡迎點(diǎn)贊娃弓。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末台丛,一起剝皮案震驚了整個(gè)濱河市挽霉,隨后出現(xiàn)的幾起案子变汪,更是在濱河造成了極大的恐慌疫衩,老刑警劉巖闷煤,帶你破解...
    沈念sama閱讀 217,277評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鲤拿,死亡現(xiàn)場(chǎng)離奇詭異近顷,居然都是意外死亡窒升,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)譬挚,“玉大人酪呻,你說(shuō)我怎么就攤上這事玩荠∫腆” “怎么了屉凯?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,624評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)眼溶。 經(jīng)常有香客問(wèn)我悠砚,道長(zhǎng),這世上最難降的妖魔是什么堂飞? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,356評(píng)論 1 293
  • 正文 為了忘掉前任灌旧,我火速辦了婚禮,結(jié)果婚禮上绰筛,老公的妹妹穿的比我還像新娘枢泰。我一直安慰自己,他們只是感情好铝噩,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布衡蚂。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪玻募。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,292評(píng)論 1 301
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼拇泣。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播谚中,決...
    沈念sama閱讀 40,135評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 38,992評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤锅劝,失蹤者是張志新(化名)和其女友劉穎玻粪,沒(méi)想到半個(gè)月后结窘,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,429評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評(píng)論 3 334
  • 正文 我和宋清朗相戀三年芭商,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了簸州。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,785評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡责静,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出塑荒,到底是詐尸還是另有隱情本谜,我是刑警寧澤陌知,帶...
    沈念sama閱讀 35,492評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響疗锐,放射性物質(zhì)發(fā)生泄漏雇卷。R本人自食惡果不足惜膘融,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望春畔。 院中可真熱鬧律姨,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,723評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)舰攒。三九已至鹦聪,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蒂秘,已是汗流浹背泽本。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,858評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留姻僧,地道東北人规丽。 一個(gè)月前我還...
    沈念sama閱讀 47,891評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像撇贺,于是被迫代替她去往敵國(guó)和親赌莺。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容