是個(gè)前端都應(yīng)該了解的web安全知識(shí)(附一些較新的防范方法)
前言
對于很多剛開始工作的前端而言扰楼,web安全似乎是一個(gè)說不清道不明的東西匾旭。關(guān)于web安全梯刚,認(rèn)真學(xué)習(xí)總結(jié)一下哈蝇,其實(shí)就會(huì)發(fā)現(xiàn)它不難棺妓。本文通過面試提問的形式來一一進(jìn)行總結(jié),希望對于各位小伙伴理解web安全有所幫助炮赦。
1.前端有哪些攻擊方式怜跑?
目前常見的web攻擊方式主要分為:XSS攻擊、CSRF攻擊吠勘、點(diǎn)擊劫持性芬。
2.什么是XSS攻擊?XSS攻擊有哪幾種類型剧防?如何防范XSS攻擊植锉?
2.1 什么是XSS攻擊?
XSS(Cross-Site Scripting峭拘,跨站腳本攻擊)是一種代碼注入攻擊俊庇。攻擊者在目標(biāo)網(wǎng)站上注入惡意代碼狮暑,當(dāng)被攻擊者登錄網(wǎng)站時(shí)就會(huì)執(zhí)行這些惡意代碼。這些腳本可以讀取cookie辉饱、session tokens或者其他敏感的網(wǎng)站信息搬男,對用戶進(jìn)行釣魚欺詐,甚至發(fā)起蠕蟲攻擊等鞋囊。
XSS的本質(zhì)是:惡意代碼未經(jīng)過濾止后,與網(wǎng)站正常的代碼混在一起,而瀏覽器是無法辨別哪些腳本是惡意的溜腐,導(dǎo)致惡意腳本被執(zhí)行。由于直接在用戶的終端執(zhí)行瓜喇,惡意代碼能夠直接獲取用戶的信息挺益,利用這些信息冒充用戶向網(wǎng)站發(fā)起攻擊者定義的請求。
舉個(gè)簡單的例子:
click mefunctiondoAttack(){while(true) {? ? ? ? ? ? ? ? alert('u are under attack');? ? ? ? ? ? }? ? ? ? }復(fù)制代碼
這里在a標(biāo)簽里注入一個(gè)腳本乘寒,當(dāng)用戶點(diǎn)擊后望众,瀏覽器會(huì)一直彈窗。在真實(shí)的網(wǎng)站攻擊中伞辛,攻擊者通過注入的這個(gè)腳本烂翰,它可以隨意干壞事,這樣是非常危險(xiǎn)的蚤氏。因?yàn)榍岸四阌肑avaScript進(jìn)行的操作甘耿,它也一樣能,想想是不是覺得很恐怖竿滨?
2.2 XSS攻擊有哪幾種類型佳恬?
根據(jù)攻擊的來源,XSS可以分為存儲(chǔ)型(持久型)于游、反射型(非持久型)毁葱、DOM型三種。
反射型XSS
當(dāng)用戶點(diǎn)擊一個(gè)惡意鏈接贰剥,或者提交一個(gè)表單倾剿,或者進(jìn)入一個(gè)惡意網(wǎng)站時(shí),注入腳本進(jìn)入被攻擊者的網(wǎng)站蚌成。Web服務(wù)器將注入一個(gè)腳本前痘,比如一個(gè)錯(cuò)誤信息、搜索結(jié)果等笑陈,未進(jìn)行過濾直接返回到用戶的瀏覽器上际度。
反射型XSS的攻擊步驟:
攻擊者構(gòu)造出特殊的url,其中包含惡意代碼涵妥。
用戶打開帶有惡意代碼的url時(shí)乖菱,網(wǎng)站服務(wù)端將惡意代碼從url取出坡锡,拼接在HTML中返回給用戶。
用戶瀏覽器接收到響應(yīng)后解析執(zhí)行窒所,混在其中的惡意代碼也被執(zhí)行鹉勒。
惡意代碼竊取用戶數(shù)據(jù)并發(fā)送到攻擊者的網(wǎng)站,或者冒充用戶的行為吵取,調(diào)用目標(biāo)網(wǎng)站接口執(zhí)行攻擊者指定的操作禽额。
反射型 XSS 漏洞常見于通過 URL 傳遞參數(shù)的功能,如網(wǎng)站搜索皮官、跳轉(zhuǎn)等脯倒。由于需要用戶主動(dòng)打開惡意的 URL 才能生效,攻擊者往往會(huì)結(jié)合多種手段誘導(dǎo)用戶點(diǎn)擊捺氢。 注意Chrome 和 Safari 能夠檢測到 url 上的xss攻擊藻丢,將網(wǎng)頁攔截掉,但是其它瀏覽器不行摄乒,如Firefox悠反。 如果不希望被前端拿到cookie,后端可以設(shè)置 httpOnly (不過這不是 XSS攻擊 的解決方案馍佑,只能降低受損范圍)斋否。
DOM型XSS
DOM 型 XSS 攻擊,實(shí)際上就是前端 JavaScript 代碼不夠嚴(yán)謹(jǐn)拭荤,把不可信的內(nèi)容插入到了頁面茵臭。在使用 .innerHTML、.outerHTML穷劈、.appendChild笼恰、document.write()等API時(shí)要特別小心,不要把不可信的數(shù)據(jù)作為 HTML 插到頁面上歇终,盡量使用 .innerText社证、.textContent、.setAttribute() 等评凝。
DOM 型 XSS 的攻擊步驟:
攻擊者構(gòu)造出特殊數(shù)據(jù)追葡,其中包含惡意代碼。
用戶瀏覽器執(zhí)行了惡意代碼奕短。
惡意代碼竊取用戶數(shù)據(jù)并發(fā)送到攻擊者的網(wǎng)站宜肉,或者冒充用戶的行為,調(diào)用目標(biāo)網(wǎng)站接口執(zhí)行攻擊者指定的操作翎碑。
DOM 型 XSS 攻擊中谬返,取出和執(zhí)行惡意代碼由瀏覽器端完成,屬于前端 JavaScript 自身的安全漏洞日杈。
存儲(chǔ)型XSS
惡意腳本永久存儲(chǔ)在目標(biāo)服務(wù)器上遣铝。當(dāng)瀏覽器請求數(shù)據(jù)時(shí)佑刷,腳本從服務(wù)器傳回并執(zhí)行,影響范圍比反射型和DOM型XSS更大酿炸。存儲(chǔ)型XSS攻擊的原因仍然是沒有做好數(shù)據(jù)過濾:前端提交數(shù)據(jù)至服務(wù)端時(shí)瘫絮,沒有做好過濾;服務(wù)端在接受到數(shù)據(jù)時(shí)填硕,在存儲(chǔ)之前麦萤,沒有做過濾;前端從服務(wù)端請求到數(shù)據(jù)扁眯,沒有過濾輸出壮莹。
存儲(chǔ)型 XSS 的攻擊步驟:
攻擊者將惡意代碼提交到目標(biāo)網(wǎng)站的數(shù)據(jù)庫中。
用戶打開目標(biāo)網(wǎng)站時(shí)姻檀,網(wǎng)站服務(wù)端將惡意代碼從數(shù)據(jù)庫取出垛孔,拼接在 HTML 中返回給瀏覽器。
用戶瀏覽器接收到響應(yīng)后解析執(zhí)行施敢,混在其中的惡意代碼也被執(zhí)行。
惡意代碼竊取用戶數(shù)據(jù)并發(fā)送到攻擊者的網(wǎng)站狭莱,或者冒充用戶的行為僵娃,調(diào)用目標(biāo)網(wǎng)站接口執(zhí)行攻擊者指定的操作。
這種攻擊常見于帶有用戶保存數(shù)據(jù)的網(wǎng)站功能腋妙,如論壇發(fā)帖默怨、商品評論、用戶私信等骤素。
2.3 如何防范XSS攻擊匙睹?
2.3.1 防范反射型XSS攻擊
app.get('/welcome',function(req, res){//對查詢參數(shù)進(jìn)行編碼,避免反射型 XSS攻擊res.send(`${encodeURIComponent(req.query.type)}`); });復(fù)制代碼
2.3.2 防范DOM型XSS攻擊
防范 DOM 型 XSS 攻擊的核心就是對輸入內(nèi)容進(jìn)行轉(zhuǎn)義(DOM 中的內(nèi)聯(lián)事件監(jiān)聽器和鏈接跳轉(zhuǎn)都能把字符串作為代碼運(yùn)行济竹,需要對其內(nèi)容進(jìn)行檢查)痕檬。
對于url鏈接(例如圖片的src屬性),那么直接使用 encodeURIComponent 來轉(zhuǎn)義送浊。
非url梦谜,我們可以這樣進(jìn)行編碼:
functionencodeHtml(str){if(!str)return'';returnstr.replace(/"/g,'"')? ? ? ? ? ? .replace(/'/g,''')? ? ? ? ? ? .replace(/</g,'<')? ? ? ? ? ? .replace(/>/g,'>')? ? ? ? ? ? .replace(/&/g,'&');}復(fù)制代碼
2.3.3 防范存儲(chǔ)型XSS攻擊
前端數(shù)據(jù)傳遞給服務(wù)器之前,先轉(zhuǎn)義/過濾(防范不了抓包修改數(shù)據(jù)的情況)
服務(wù)器接收到數(shù)據(jù)袭景,在存儲(chǔ)到數(shù)據(jù)庫之前唁桩,進(jìn)行轉(zhuǎn)義/過濾
前端接收到服務(wù)器傳遞過來的數(shù)據(jù),在展示到頁面前耸棒,先進(jìn)行轉(zhuǎn)義/過濾
2.3.4 CSP方式
CSP的全稱是Content Security Policy荒澡,即內(nèi)容安全策略。
CSP 的主要目標(biāo)是減少和報(bào)告 XSS 攻擊 与殃,XSS 攻擊利用了瀏覽器對于從服務(wù)器所獲取的內(nèi)容的信任单山。惡意腳本在受害者的瀏覽器中得以運(yùn)行碍现,因?yàn)闉g覽器信任其內(nèi)容來源,即使有的時(shí)候這些腳本并非來自于它本該來的地方饥侵。
CSP通過指定有效域——即瀏覽器認(rèn)可的可執(zhí)行腳本的有效來源——使服務(wù)器管理者有能力減少或消除XSS攻擊所依賴的載體鸵赫。一個(gè)CSP兼容的瀏覽器將會(huì)僅執(zhí)行從白名單域獲取到的腳本文件,忽略所有的其他腳本 (包括內(nèi)聯(lián)腳本和HTML的事件處理屬性)躏升。
作為一種終極防護(hù)形式辩棒,始終不允許執(zhí)行腳本的站點(diǎn)可以選擇全面禁止腳本執(zhí)行。
如何使用CSP膨疏?
你可以使用 Content-Security-Policy HTTP頭部 來指定你的策略一睁,像這樣:
Content-Security-Policy: policy
policy參數(shù)是一個(gè)包含了各種描述你的CSP策略指令的字符串。
比如一個(gè)網(wǎng)站管理者想要所有內(nèi)容均來自站點(diǎn)的同一個(gè)源 (不包括其子域名):
Content-Security-Policy: default-src 'self'
詳細(xì)的用法可以參考MDN佃却,內(nèi)容安全策略( CSP )
3. 什么是CSRF攻擊者吁?如何防范?
3.1 什么是CSRF攻擊饲帅?
CSRF(Cross-site request forgery)跨站請求偽造:攻擊者誘導(dǎo)受害者進(jìn)入第三方網(wǎng)站复凳,在第三方網(wǎng)站中,向被攻擊網(wǎng)站發(fā)送跨站請求灶泵。利用受害者在被攻擊網(wǎng)站已經(jīng)獲取的注冊憑證育八,繞過后臺(tái)的用戶驗(yàn)證,達(dá)到冒充用戶對被攻擊的網(wǎng)站執(zhí)行某項(xiàng)操作的目的赦邻。
典型的CSRF攻擊流程:
受害者登錄A站點(diǎn)髓棋,并保留了登錄憑證(Cookie)。
攻擊者誘導(dǎo)受害者訪問了站點(diǎn)B惶洲。
站點(diǎn)B向站點(diǎn)A發(fā)送了一個(gè)請求按声,瀏覽器會(huì)默認(rèn)攜帶站點(diǎn)A的Cookie信息。
站點(diǎn)A接收到請求后恬吕,對請求進(jìn)行驗(yàn)證签则,并確認(rèn)是受害者的憑證,誤以為是無辜的受害者發(fā)送的請求币呵。
站點(diǎn)A以受害者的名義執(zhí)行了站點(diǎn)B的請求怀愧。
攻擊完成,攻擊者在受害者不知情的情況下余赢,冒充受害者完成了攻擊芯义。
3.2 如何防范CSRF攻擊?
3.2.1 主流方式
添加驗(yàn)證碼(體驗(yàn)不好)
判斷請求的來源:檢測Referer(并不安全妻柒,Referer可以被更改)
使用Token(主流)
CSRF攻擊之所以能夠成功扛拨,是因?yàn)榉?wù)器誤把攻擊者發(fā)送的請求當(dāng)成了用戶自己的請求。那么我們可以要求所有的用戶請求都攜帶一個(gè)CSRF攻擊者無法獲取到的Token举塔。服務(wù)器通過校驗(yàn)請求是否攜帶正確的Token绑警,來把正常的請求和攻擊的請求區(qū)分開求泰。跟驗(yàn)證碼類似,只是用戶無感知计盒。
服務(wù)端給用戶生成一個(gè)token渴频,加密后傳遞給用戶
用戶在提交請求時(shí),需要攜帶這個(gè)token
服務(wù)端驗(yàn)證token是否正確
3.2.2 啟用cookies的SameSite屬性
SameSite的屬性值有3個(gè):
strict: Cookie只會(huì)在第一方上下文中發(fā)送北启,不會(huì)與第三方網(wǎng)站發(fā)起的請求一起發(fā)送卜朗。
lex: Cookies允許與頂級一起發(fā)送,并將與第三方網(wǎng)站發(fā)起的GET請求一起發(fā)送咕村。這是瀏覽器中的默認(rèn)值场钉。
none: Cookie將在所有上下文中發(fā)送,即允許跨域發(fā)送懈涛。
注意:以前None是默認(rèn)值逛万,但最近的瀏覽器版本將Lax作為默認(rèn)值,以便對某些類型的跨站點(diǎn)請求偽造(csrf)攻擊具有相當(dāng)強(qiáng)的防御能力批钠。
4. 什么是點(diǎn)擊劫持攻擊宇植?如何防范?
4.1 什么是點(diǎn)擊劫持攻擊埋心?
點(diǎn)擊劫持是指在一個(gè)Web頁面中隱藏了一個(gè)透明的iframe当纱,用外層假頁面誘導(dǎo)用戶點(diǎn)擊,實(shí)際上是在隱藏的frame上觸發(fā)了點(diǎn)擊事件進(jìn)行一些用戶不知情的操作踩窖。
典型的點(diǎn)擊劫持攻擊流程:
攻擊者構(gòu)建了一個(gè)非常有吸引力的網(wǎng)頁
將被攻擊的頁面放置在當(dāng)前頁面的 iframe 中
使用樣式將 iframe 疊加到非常有吸引力內(nèi)容的上方
將iframe設(shè)置為100%透明
你被誘導(dǎo)點(diǎn)擊了網(wǎng)頁內(nèi)容,你以為你點(diǎn)擊的是***晨横,而實(shí)際上洋腮,你成功被攻擊了。
4.2 如何防范點(diǎn)擊劫持手形?
4.2.1 frame busting
if(top.location !==window.location) {? ? top.location =window.location;}復(fù)制代碼
需要注意的是: HTML5中iframe的 sandbox 屬性啥供、IE中iframe的security 屬性等,都可以限制iframe頁面中的JavaScript腳本執(zhí)行库糠,從而可以使得 frame busting 失效伙狐。
4.2.2 X-FRAME-OPTIONS
X-FRAME-OPTIONS是微軟提出的一個(gè)http頭,專門用來防御利用iframe嵌套的點(diǎn)擊劫持攻擊瞬欧。并且在IE8贷屎、Firefox3.6、Chrome4以上的版本均能很好的支持艘虎“χ叮可以設(shè)置為以下值:
DENY: 拒絕任何域加載
SAMEORIGIN: 允許同源域下加載
ALLOW-FROM: 可以定義允許frame加載的頁面地址
5. 總結(jié)
以上談到了3種web攻擊方式,分別是XSS攻擊野建、CSRF攻擊属划、點(diǎn)擊劫持恬叹,并給出了具體的防范方式。當(dāng)然同眯,只有在實(shí)踐中不斷地使用這些技術(shù)绽昼,才能對web安全有更深刻的認(rèn)知。