在 Web 安全中,服務(wù)端一直扮演著十分重要的角色。然而前端的問(wèn)題也不容小覷,它也會(huì)導(dǎo)致信息泄露等諸如此類的問(wèn)題。在這篇文章中,我們將向讀者介紹如何防范Web前端中的各種漏洞?!救f(wàn)字長(zhǎng)文,請(qǐng)先收藏再閱讀】
首先,我們需要了解安全防御產(chǎn)品已經(jīng)為我們做了哪些工作。其次,我們將探討前端存在哪些漏洞,并提供相應(yīng)的防范思路。
一、安全防御產(chǎn)品
安全防御產(chǎn)品一般有:
傳統(tǒng)互聯(lián)網(wǎng)公司的安全防御體系,類似于一個(gè)空氣凈化模型,每個(gè)層都有不同的產(chǎn)品,包括網(wǎng)絡(luò)層防護(hù)、應(yīng)用層防護(hù)、主機(jī)層防護(hù)、運(yùn)行時(shí)防護(hù)、安全開(kāi)發(fā)防護(hù)和安全運(yùn)營(yíng)防護(hù)。外部攻擊流量經(jīng)過(guò)過(guò)濾后,到達(dá)應(yīng)用系統(tǒng)的流量相對(duì)較為安全。
對(duì)于我們前端而言,最有用的是安全開(kāi)發(fā)防護(hù)層中的白盒和黑盒。白盒掃描是對(duì)我們的源代碼進(jìn)行掃描,在上線時(shí)會(huì)自動(dòng)檢測(cè)問(wèn)題。黑盒掃描則不考慮程序的結(jié)構(gòu)和代碼細(xì)節(jié),對(duì)應(yīng)用程序進(jìn)行漏洞掃描,每天都有定時(shí)任務(wù)掃描公網(wǎng)。
在安全方面,我們與集團(tuán)安全部門(mén)進(jìn)行雙向合作。在集團(tuán)安全防御體系已經(jīng)做了一些工作的基礎(chǔ)上,我們?nèi)绾吾槍?duì)前端可能存在的漏洞進(jìn)行防范,是我們研發(fā)部門(mén)需要思考的問(wèn)題。
二、漏洞防范
1、安全傳輸
首先,務(wù)必使用HTTPS協(xié)議,這可以有效防止局域網(wǎng)內(nèi)的明文抓包。
2、域分離
其次,進(jìn)行域分離。將一些業(yè)務(wù)關(guān)聯(lián)性較小的內(nèi)容轉(zhuǎn)移到不相關(guān)的域中。如果分離域下出現(xiàn)了XSS漏洞,不會(huì)影響業(yè)務(wù)主域,而且分離域下的XSS漏洞也無(wú)法獲得獎(jiǎng)勵(lì)。如果所有內(nèi)容都在主域下,一旦主域出現(xiàn)漏洞,主域下的所有子域都會(huì)受到破壞。
前端領(lǐng)域常見(jiàn)的漏洞有3種:XSS漏洞、CSRF漏洞、界面操作劫持漏洞
3、XSS防御方案
對(duì)于概念,包括名詞定義、攻擊方式、解決方案等估計(jì)大家都看過(guò)不少,但留下印象總是很模糊,要?jiǎng)邮植僮饕环拍芗由钣∠蟛⒛苷嬲斫狻?/p>
1)XSS 模擬攻擊
先動(dòng)手實(shí)現(xiàn)一個(gè) XSS 的攻擊場(chǎng)景,然后再講解 XSS 的防范手段。看這個(gè)代碼:
點(diǎn)擊“write”按鈕后,會(huì)在頁(yè)面插入一個(gè)a鏈接,a鏈接的跳轉(zhuǎn)地址是文本框的內(nèi)容。在這里,通過(guò)innerHTML把一段用戶輸入的數(shù)據(jù)當(dāng)做HTML寫(xiě)入到頁(yè)面中,這就造成了XSS漏洞。嘗試如下輸入:
首先用一個(gè)單引號(hào)閉合掉href的第一個(gè)單引號(hào),然后閉合掉標(biāo)簽,然后插入一個(gè)img標(biāo)簽。頁(yè)面代碼變成了:
腳本被執(zhí)行:
所以你明白了吧,XSS跨站腳本攻擊就是注入一段腳本,并且該腳本能夠被執(zhí)行。其中最常見(jiàn)的XSS Payload就是讀取瀏覽器的Cookie對(duì)象。通過(guò)盜取Cookie,攻擊者可以直接調(diào)用接口,發(fā)起“Cookie劫持”攻擊。
為了防止“Cookie劫持”,集團(tuán)的統(tǒng)一登錄使用了Cookie的“HttpOnly”和“Secure”標(biāo)識(shí)。
HttpOnly標(biāo)識(shí)表示該Cookie僅在HTTP層面?zhèn)鬏?。一旦設(shè)置了HttpOnly標(biāo)志,客戶端腳本就無(wú)法讀寫(xiě)該Cookie,從而有效地防御XSS攻擊獲取Cookie的風(fēng)險(xiǎn)。
Secure標(biāo)識(shí)確保Cookie只在加密的HTTPS連接中傳輸,從而降低了“Cookie劫持”的風(fēng)險(xiǎn)。
因此,建議避免使用localStorage存儲(chǔ)敏感信息,哪怕這些信息進(jìn)行過(guò)加密。因?yàn)閘ocalStorage存儲(chǔ),沒(méi)有針對(duì)XSS攻擊,做任何防御機(jī)制。一旦出現(xiàn)XSS漏洞,那么存儲(chǔ)在localStorage里的數(shù)據(jù)就極易被獲取到。
2)XSS的危害
讓我們簡(jiǎn)單談?wù)刋SS的危害。注入的腳本可能會(huì)進(jìn)行JavaScript函數(shù)劫持,覆蓋我們代碼中原有的函數(shù),修改js原型鏈上的函數(shù),或在原函數(shù)基礎(chǔ)上添加額外行為。例如,將網(wǎng)絡(luò)請(qǐng)求的響應(yīng)發(fā)送到攻擊者的服務(wù)器。
JavaScript函數(shù)劫持是什么?它是在目標(biāo)函數(shù)觸發(fā)之前重寫(xiě)某個(gè)函數(shù)的過(guò)程。例如:
let _write = document.write.bind(document);
document.write = function(x) {
if(typeof(x) == "undefined") { return; }
_write(x);
}
注入的腳本還可能對(duì)用戶進(jìn)行內(nèi)存攻擊。如果知道用戶使用的瀏覽器、操作系統(tǒng),攻擊者就有可以實(shí)施一次精準(zhǔn)的瀏覽器內(nèi)存攻擊。通過(guò)XSS,可以讀取瀏覽器的UserAgent對(duì)象。
alert(navigator.userAgent);
該對(duì)象提供了客戶端的信息,如操作系統(tǒng)版本:Mac OS X 10_15_7,瀏覽器版本:Chrome/114.0.0.0
注入的腳本可能強(qiáng)制彈出廣告頁(yè)面、刷流量,也可能進(jìn)行大量的DDoS攻擊,導(dǎo)致網(wǎng)絡(luò)擁塞。此外,它還可能控制受害者的機(jī)器向其他網(wǎng)站發(fā)起攻擊。
如果信貸產(chǎn)品的網(wǎng)頁(yè)存在XSS漏洞,黑客可以注入一段腳本,調(diào)用查詢借還記錄的接口,并將響應(yīng)結(jié)果發(fā)送到自己的服務(wù)器。然后,利用用戶的借還記錄等信息,對(duì)用戶進(jìn)行電信詐騙。
第三方統(tǒng)計(jì)腳本有機(jī)會(huì)竊取用戶的敏感信息,如瀏覽歷史、真實(shí)IP、地理位置、設(shè)備信息,并將其傳送給攻擊者。此外,我們使用的第三方依賴和npm包也有可能竊取用戶信息。在這方面,集團(tuán)對(duì)代碼進(jìn)行了白盒掃描,已一定程度上規(guī)避問(wèn)題。但最好我們?cè)谶x擇第三方包時(shí),選擇可信賴的包。
3)XSS 防范方法
XSS 防范方法通常有以下幾種:
①慎防第三方內(nèi)容:對(duì)于流行的統(tǒng)計(jì)腳本和第三方依賴,要謹(jǐn)慎使用。
②輸入校驗(yàn)和輸出編碼:進(jìn)行輸入校驗(yàn),包括長(zhǎng)度限制、值類型是否正確以及是否包含特殊字符(如<>)。同時(shí),在輸出時(shí)進(jìn)行相應(yīng)的編碼,根據(jù)輸出的位置選擇適當(dāng)?shù)木幋a方式,如HTML編碼和URL編碼。
③使用HttpOnly屬性:防范XSS攻擊后的"cookie劫持"。
使用Secure屬性,確保Cookie只在加密的HTTPS連接中傳輸,降低"cookie劫持"的風(fēng)險(xiǎn)。
④避免使用localStorage存儲(chǔ)敏感信息。
⑤使用Content-Security-Policy(內(nèi)容安全策略):可以通過(guò)指定只允許加載來(lái)自特定域名的腳本,防范XSS攻擊,例如,可以使用以下配置只允許加載來(lái)自mjt.jd.com域名的腳本
# 只允許加載來(lái)自特定域名的腳本
add_header Content-Security-Policy "script-src mjt.jd.com";
4、CSRF防御方案
CSRF漏洞是借用用戶的權(quán)限做一些事情,注意,是“借用”,而不是“盜取”。XSS漏洞是“盜取”用戶權(quán)限,CSRF漏洞是“借用”用戶權(quán)限。
1)CSRF 模擬攻擊
我們先動(dòng)手實(shí)現(xiàn)一個(gè) CSRF 攻擊場(chǎng)景,然后再介紹 CSRF 的防范手段。我們要模擬以下場(chǎng)景:用戶先登錄了銀行網(wǎng)站,然后黑客網(wǎng)站誘導(dǎo)用戶訪問(wèn)和點(diǎn)擊,從而利用用戶的登錄權(quán)限,讓用戶給黑客自己轉(zhuǎn)賬。我們使用 express 啟動(dòng)一個(gè)服務(wù),模擬 CSRF 攻擊。銀行網(wǎng)站的服務(wù)啟動(dòng)在 3001 端口,并提供以下3個(gè)接口:
app.use('/', indexRouter);
app.use('/auth', authRouter);
app.use('/transfer', transferRouter);
authRouter:
router.get('/', function(req, res, next) {
res.cookie('userId', 'ce032b305a9bc1ce0b0dd2a', { expires: new Date(Date.now() + 900000) })
res.end('ok')
});
/auth 接口在 cookie 中設(shè)置了一個(gè)名為 userId 的 cookie,即給用戶授予登錄權(quán)限。
transferRouter:
router.get('/', function(req, res, next) {
const { query } = req;
const { userId } = req.cookies;
if(userId){
res.send({
status: 'transfer success',
transfer: query.number
})
}else{
res.send({
status: 'error',
transfer: ''
})
}
});
/transfer 接口判斷了 cookie,如果存在 cookie,則轉(zhuǎn)賬成功,否則轉(zhuǎn)賬失敗。
使用 ejs 提供銀行轉(zhuǎn)賬頁(yè)面:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>
<%= title %>
</title>
</head>
<body>
<h2>
轉(zhuǎn)賬
</h2>
<script>
const h2 = document.querySelector('h2');
h2.addEventListener('click', () => {
fetch('/transfer?number=15000&to=Bob').then(res => {
console.log(res.json());
})
})
</script>
</body>
</html>
黑客網(wǎng)站的服務(wù)啟動(dòng)在 3002 端口,并提供一個(gè)與銀行網(wǎng)站外觀相同的頁(yè)面:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><%= title %></title>
</head>
<body>
<div class="wrapper" id="container">
<h2>
轉(zhuǎn)賬
</h2>
<form action="http://bank.com/transfer" method=GET>
<input type="hidden" name="number" value="150000" />
<input type="hidden" name="to" value="Jack" />
</form>
<script>
const h2 = document.querySelector('h2');
h2.addEventListener('click', () => {
submitForm();
})
function submitForm() {
document.forms[0].submit();
}
</script>
</div>
</body>
</html>
由于兩個(gè)網(wǎng)站都是在 localhost 域名下,cookie 是根據(jù)域名而不是端口進(jìn)行區(qū)分的。因此,我們使用 Whistle 進(jìn)行域名映射:
# bank.com 映射到 127.0.0.1:3001
bank.com 127.0.0.1:3001
# hack.com 映射到 127.0.0.1:3002
hack.com 127.0.0.1:3002
現(xiàn)在我們開(kāi)始操作。首先打開(kāi)瀏覽器,訪問(wèn)銀行網(wǎng)站 的 /auth獲得授權(quán):
然后通過(guò)點(diǎn)擊”轉(zhuǎn)賬”按鈕發(fā)送請(qǐng)求,http://bank.com/transfer?number=15000&to=Bob,進(jìn)行轉(zhuǎn)賬操作:
用戶受到郵件或者廣告誘惑進(jìn)入了 黑客網(wǎng)站,黑客網(wǎng)站首頁(yè)有一個(gè)“轉(zhuǎn)賬”按鈕,調(diào)銀行的transfer接口 http://bank.com/transfer?number=150000&to=Jack 這個(gè)請(qǐng)求放在
到了這里,關(guān)于聚焦Web前端安全:最新揭秘漏洞防御方法的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!