XSS 和 CSRF

作者: TooooBug
鏈接:http://www.imooc.com/article/18069
來源:慕課網(wǎng)

XSS 全稱 Cross Site Scripting 歧杏,跨站腳本攻擊棚品,因為 CSS 這名字老早就被樣式表拿走了蚜迅,所以只好叫 XSS 了捎泻。

XSS 是什么鬼

XSS 比如我只想在頁面上顯示一個名字:

<span class="name">{{name}}</span>

但是侦鹏,如果我的名字是長這樣的:

星辰<script>alert('SB')</script>

這時候就好玩了:

<span class="name">星辰<script>alert('SB')</script></span>

你看诡曙,頁面中憑空多了一段腳本。

JS可以干嘛略水?用戶登錄用的JS吧价卤,讀取資料用的JS吧,點擊買東西渊涝、消費(fèi)用的JS吧慎璧,查用戶有多少錢用的JS吧,基于 Cookies 也可以讀寫吧跨释。

XSS 怎么防御

一個經(jīng)典的防御方法就是對內(nèi)容進(jìn)行轉(zhuǎn)義和過濾胸私,比如

var escapeHtml = function(str) {
    if(!str) return '';
    str = str.replace(/&/g, '&amp;');
    str = str.replace(/</g, '&lt;');
    str = str.replace(/>/g, '&gt;');
    str = str.replace(/"/g, '&quto;');
    str = str.replace(/'/g, '&#39;');
    // str = str.replace(/ /g, '&#32;');
    return str;
};

var name = escapeHtml(`<script>alert('SB')</script>`);

此時 name 會變成

&lt;script&gt;alert(&#39;SB&#39;)&lt;/script&gt;

這樣就會原樣顯示出來,再也無法耍流氓啦鳖谈。

當(dāng)然岁疼,富文本還要更麻煩一些,因為要保留一部分標(biāo)簽和屬性缆娃,要不然全變純文本了捷绒,就不富了瑰排。這種情況一般通過黑名單進(jìn)行過濾,或者白名單放行疙驾。即只允許一部分指定的標(biāo)簽和屬性凶伙,其它的全部轉(zhuǎn)義掉郭毕。

CSP 大法

前面轉(zhuǎn)義的方法的出發(fā)點它碎,是讓用戶的輸入不要變成程序,輸入的什么就讓它輸出成什么显押。

事實上現(xiàn)代瀏覽器為我們帶來了一個全新的安全策略扳肛,叫作內(nèi)容安全策略,Content Security Policy乘碑,簡稱CSP挖息。CSP的思路跟轉(zhuǎn)義不一樣,它的著手點是兽肤,如果一段代碼變成了程序套腹,我們是否應(yīng)該運(yùn)行它∽收。或者更準(zhǔn)確一點說电禀,它實際上是定義頁面上哪一些內(nèi)容是可被信任的,哪一些內(nèi)容是不被信任的笤休。

因為我們自己的腳本是預(yù)先就知道并放在頁面上的尖飞,所以我們可以設(shè)置好信任關(guān)系,當(dāng)有 XSS 腳本出現(xiàn)時店雅,它并不在我們的信任列表中政基,因此可以阻止它運(yùn)行。

它的具體使用方式是在 HTTP 頭中輸出 CSP 策略:

Content-Security-Policy: <policy-directive>; <policy-directive>

從語法上可以看到闹啦,一個頭可以輸出多個策略沮明,每一個策略由一個指令和指令對應(yīng)的值組成。指令可以理解為指定內(nèi)容類型的窍奋,比如script-src指令用于指定腳本荐健,img-src用于指定圖片。值則主要是來源费变,比如某個指定的URL摧扇,或者self表示同源,或者unsafe-inline表示在頁面上直接出現(xiàn)的腳本等挚歧。

詳細(xì)的指令和值扛稽,可以查看MDN相關(guān)頁面

具體到上面的 XSS 例子滑负,可以使用

Content-Security-Policy: script-src 'self';

這樣除了在同一個域名下的JS文件外在张,其它的腳本都不可以執(zhí)行了用含,自然之前 XSS 的內(nèi)容也就失效啦。簡單粗暴有沒有帮匾?

當(dāng)然啄骇,如果你說,我就是要在頁面中放點內(nèi)聯(lián)的腳本瘟斜,不可以么缸夹?當(dāng)然可以啦,CSP 設(shè)計的時候也考慮了這些情況螺句,還是相當(dāng)靈活的虽惭。你只需要指定一個 nonce 屬性,或者計算一下 hash 值蛇尚,即可芽唇。詳細(xì)的用法看 MDN 哦。

說實話取劫,用 CSP 來處理 XSS 攻擊還是不如轉(zhuǎn)義來得優(yōu)雅匆笤,因為轉(zhuǎn)義可以不影響用戶輸入輸出,不改變內(nèi)容的本質(zhì)谱邪。但是 CSP 提供了足夠簡單而又靈活的方式來防御 XSS 炮捧,可以很好地作為我們前端 XSS 防御的最后一道防線。

CSRF

CSRF 也是個望文生不到義的詞虾标,它的全稱是 Cross Site Request Foggy寓盗,即跨站請求攻擊。雖然也有跨站璧函,但我覺得這個跨站還是相當(dāng)可以理解的傀蚌,它真的是從別的網(wǎng)站發(fā)起一個請求到我們的網(wǎng)站的。

當(dāng)一個用戶登錄我們的網(wǎng)站后蘸吓,在 Cookies 中會存放用戶的身份憑證善炫。在大部分時候,就是一個 SessionId 库继。當(dāng)用戶下次訪問我們的網(wǎng)站的時候箩艺,我們用這個憑證識別出用戶是誰,有沒有登錄態(tài)宪萄。

如果第三方網(wǎng)站的代碼請求了我們的網(wǎng)站艺谆,會發(fā)生什么呢?比如

<img src="http://www.example.com/haha" />

雖然它是一張圖片拜英,但它確實向www.example.com發(fā)了一個請求静汤,如此用戶有登錄態(tài)的話,其實就相當(dāng)于是用戶自己發(fā)了一個請求。如果這個地址是一個發(fā)表文章虫给、發(fā)布微博甚至轉(zhuǎn)賬之類的鏈接藤抡,那用戶就在不知情的情況下進(jìn)行了一些操作。這也是比較嚴(yán)重的安全問題抹估。

當(dāng)然你可能會說缠黍,現(xiàn)在誰還這么弱智,把這么敏感的操作用 GET 耙摺瓷式?沒錯,你可以選擇用 POST 谷暮,但是這絲毫不能阻止 CSRF 攻擊的發(fā)生啊蒿往。

<iframe name="test"></iframe>
<form target="test" method="post" action="http://www.example.com/haha">
    ...
</form>

當(dāng)這個表單提交的時候,我們就發(fā)了一個 POST 請求湿弦。華麗麗的 CSRF 。

CSRF 的常規(guī)防御

CSRF 比較常規(guī)的防御方式是通過判斷來源和加 token腾夯。

判斷來源比較簡單颊埃,主要是判斷referer這個頭,如果不是自己的網(wǎng)站蝶俱,就返回錯誤班利。

加 token 即同樣的隨機(jī) token,在 cookies 中放一份榨呆,在表單中再放一份罗标。這樣第三方網(wǎng)站就無法獲取到這個 token 是什么。

但是這樣做也有一個比較明顯的問題积蜻,就是無法保證站內(nèi)用戶的體驗闯割。雖然你防了站外的攻擊,但是也降低了站內(nèi)用戶的體驗竿拆。具體表現(xiàn)在如果同時打開多個表單宙拉,只有最后一個表單能成功提交。

same-site 的 Cookie

回想 CSRF 之所以能夠攻擊成功丙笋,核心原因就在于用戶的身份是放在 Cookies 中的谢澈,而不管你通過什么方式訪問網(wǎng)站,都會帶上這個網(wǎng)站的 Cookies 御板,從第三方來的訪問自然也不能例外锥忿。

但是,Chrome 在這個問題上給了我們不同的答案怠肋,可以放第三方訪問時不帶 Cookies 敬鬓。也就是說 Cookies 只有本站能用,來自第三方的訪問都不能使用。

具體的使用方式列林,是在打 Cookie 的時候瑞你,加上一個屬性:SameSite,它的值有兩:

  • strict 任何來自第三方的請求都不能使用 Cookies 希痴,包括通過鏈接點進(jìn)來的
  • lex 只有比較敏感的操作不帶 Cookies 者甲,比如表單提交

針對 CSRF ,我們可以將 Cookies 設(shè)置成SameSite: strict的砌创,這樣就可以有效防御 CSRF 了虏缸。不過比較可惜的是,目前只有 Chrome 才支持這一屬性嫩实。希望未來所有瀏覽器都能跟上腳步刽辙。

使用 SameSite 還會面臨一個問題,如果用戶是點擊鏈接進(jìn)來的甲献,那么是不能使用登錄態(tài)的宰缤。一般可以考慮將用戶不敏感的信息不設(shè)置這個屬性,點進(jìn)來仍然可以顯示當(dāng)前用戶是誰晃洒,但是在請求的時候要求一個比較敏感的 SameSite 的 Cookies慨灭。這里需要更多的實踐經(jīng)驗來探索。

小結(jié)

本文重點講了 XSS 和 CSRF 這兩種比較常見的前端安全問題的防御思路球及,尤其是如何使用一些新的規(guī)范氧骤、實現(xiàn)來幫助我們進(jìn)行防御。希望后面瀏覽器對這些安全相關(guān)防御辦法的普及率能再高一些吃引,讓前端工程師能花更少的時間寫出更安全的代碼筹陵。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市镊尺,隨后出現(xiàn)的幾起案子朦佩,更是在濱河造成了極大的恐慌,老刑警劉巖鹅心,帶你破解...
    沈念sama閱讀 219,490評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件吕粗,死亡現(xiàn)場離奇詭異,居然都是意外死亡旭愧,警方通過查閱死者的電腦和手機(jī)颅筋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來输枯,“玉大人议泵,你說我怎么就攤上這事√蚁ǎ” “怎么了先口?”我有些...
    開封第一講書人閱讀 165,830評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我碉京,道長厢汹,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,957評論 1 295
  • 正文 為了忘掉前任谐宙,我火速辦了婚禮烫葬,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘凡蜻。我一直安慰自己搭综,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,974評論 6 393
  • 文/花漫 我一把揭開白布划栓。 她就那樣靜靜地躺著兑巾,像睡著了一般。 火紅的嫁衣襯著肌膚如雪忠荞。 梳的紋絲不亂的頭發(fā)上蒋歌,一...
    開封第一講書人閱讀 51,754評論 1 307
  • 那天,我揣著相機(jī)與錄音钻洒,去河邊找鬼奋姿。 笑死,一個胖子當(dāng)著我的面吹牛素标,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播萍悴,決...
    沈念sama閱讀 40,464評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼头遭,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了癣诱?” 一聲冷哼從身側(cè)響起计维,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎撕予,沒想到半個月后鲫惶,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,847評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡实抡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,995評論 3 338
  • 正文 我和宋清朗相戀三年欠母,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片吆寨。...
    茶點故事閱讀 40,137評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡赏淌,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出啄清,到底是詐尸還是另有隱情六水,我是刑警寧澤,帶...
    沈念sama閱讀 35,819評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站掷贾,受9級特大地震影響睛榄,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜想帅,卻給世界環(huán)境...
    茶點故事閱讀 41,482評論 3 331
  • 文/蒙蒙 一场靴、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧博脑,春花似錦憎乙、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至疗杉,卻和暖如春阵谚,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背烟具。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評論 1 272
  • 我被黑心中介騙來泰國打工梢什, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人朝聋。 一個月前我還...
    沈念sama閱讀 48,409評論 3 373
  • 正文 我出身青樓嗡午,卻偏偏與公主長得像,于是被迫代替她去往敵國和親冀痕。 傳聞我的和親對象是個殘疾皇子荔睹,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,086評論 2 355

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

  • CSRF(Cross-site request forgery,跨站請求偽造)言蛇,是通過偽造請求僻他,冒充用戶在站內(nèi)進(jìn)行...
    07120665a058閱讀 3,008評論 1 6
  • XSS是什么?它的全名是:Cross-site scripting腊尚,為了和CSS層疊樣式表區(qū)分所以取名XSS吨拗。是一...
    圓心角閱讀 511評論 2 0
  • XSS篇: XSS,(cross site scripting),跨站腳本注入婿斥,指攻擊者利用一些技巧向頁面注入腳本...
    TheoLin閱讀 2,352評論 0 2
  • xss(cross site script)劝篷,跨站腳本攻擊,簡稱本應(yīng)該是css,但是為了避免和css層疊樣式表沖突...
    Quilljou閱讀 583評論 0 0
  • XSS XSS: Cross-Site Scripting 原理概述: 簡單來說 正常用戶 A 提交正常內(nèi)容,顯...
    DeeJay_Y閱讀 271評論 0 0