前端安全問題實(shí)戰(zhàn)

之前公司的安全組掃出了我們官網(wǎng)的幾個安全漏洞。安全問題對很多前端來說都是只聽過,沒見過。這次遇到了真實(shí)對漏洞,可以做個記錄。

存儲型XSS漏洞

XSS,跨站腳本攻擊。存儲型XSS攻擊,即攻擊代碼被當(dāng)成文本(如帖子)提交保存到服務(wù)器,其他用戶打開這段文本的時候,代碼就會在其他用戶的瀏覽器里執(zhí)行。

場景:一個壞人在論壇發(fā)布帖子 內(nèi)容如下:

大家好,第一次在這個論壇發(fā)帖,現(xiàn)在我要植入一段代碼:<img src=x onerror=alert(1)>

如果論壇沒有對帖子的內(nèi)容做轉(zhuǎn)義處理,直接發(fā)布出去。 其他用戶點(diǎn)擊這個帖子,頁面就會插入這個圖片標(biāo)簽。由于圖片的src異常,圖片加載失敗,就會觸發(fā)onerror里的alert。

如果onerror里的內(nèi)容不是一個簡單的alert,而是一段盜取用戶cookies的代碼呢?那么就會對用戶對賬戶造成威脅。

防御措施

對< > / 符號做escape轉(zhuǎn)義即可,escape可以把所有ASCII 之外的所有字符轉(zhuǎn)換為 %xx 或 %uxxxx(x表示十六進(jìn)制的數(shù)字)的轉(zhuǎn)義序列。

延伸:vue 中 v-html 指令的合理使用

用過 vue 的同學(xué)都知道,v-html 的作用是可以把填入 v-html 里的值轉(zhuǎn)化為 html 代碼,所以 v-html可能會成為攻擊者利用的漏洞,如果把用戶提交的內(nèi)容使用 v-html渲染,就可能會把用戶輸入的內(nèi)容變成可執(zhí)行的代碼,形成 XSS 攻擊。

反射型XSS漏洞

反射型漏洞:攻擊者通過特定的方式來誘惑受害者去訪問一個包含惡意代碼的URL。
場景還是壞人在論壇發(fā)帖,壞人在帖子里貼一個URL,其他用戶訪問這個URL,使URL上的代碼在用戶瀏覽器里被執(zhí)行。
可能有人會問,在帖子里附帶鏈接不是正?,F(xiàn)象嗎,用戶點(diǎn)擊第三方鏈接導(dǎo)致被攻擊跟我有什么關(guān)系?
那么,如果用戶點(diǎn)擊的就是官方鏈接而觸發(fā)了XSS攻擊呢?

場景:這個發(fā)生場景現(xiàn)在來看有點(diǎn)古老了,但大部分網(wǎng)站可能仍會使用的跨域策略:JSONP。
簡單描述JSONP的流程:前端使用<script>標(biāo)簽請求后端資源,后端返回的資源會被一個函數(shù)包裹,類似:

callback({
  a: 1,
  b: 2
});

而前端會提前在頁面定義好這個callback函數(shù),例如:

// 請求到達(dá)頁面,觸發(fā) callback 函數(shù),將資源掛到window上
function callback(res) {
  window.res = res;
}

而通常后臺返回的函數(shù)名并不會固定返回callback,因為可能會調(diào)用到頁面其他叫callback的函數(shù),所以,前端在請求的時候,都會在鏈接后帶一個參數(shù),告訴后臺,返回的函數(shù)名應(yīng)該叫什么,例如:

前端請求地址:https://xxxxx/giftjson?jsoncallback=mycallback
后臺返回結(jié)果:

// jsoncallback傳的參數(shù)是什么,返回的函數(shù)名就是什么
mycallback({
  a: 1,
  b: 2
});

可以看到,請求地址上的jsoncallback參數(shù)是什么,后臺返回的函數(shù)名就是什么。看到這句話是不是隱隱感覺到不對勁?如果jsoncallback參數(shù)是一段代碼呢?

假設(shè),壞人發(fā)現(xiàn)了斗魚直播的一個接口有這個漏洞,在斗魚論壇發(fā)帖:

斗魚出了個活動啦,大家點(diǎn)擊這個鏈接可以免費(fèi)抽獎,這個是斗魚官方鏈接大家放心點(diǎn):
https://www.douyu.com/getUserInfo?jsoncallback=<img+src=x+onerror=alert(1)>

其他用戶發(fā)現(xiàn)這個確實(shí)是斗魚的官方鏈接就點(diǎn)了進(jìn)去,結(jié)果就運(yùn)行了jsoncallback里的代碼。

防御措施

個攻擊其實(shí)還需要一點(diǎn)機(jī)緣巧合,比如把返回頭的Content-Type設(shè)置成了application/javascript或者text/html,就會導(dǎo)致字符被當(dāng)作代碼運(yùn)行。所以防止反射型攻擊的方法就是將返回頭的Content-Type設(shè)置為application/json;即可。

CSRF 攻擊

CSRF,跨站點(diǎn)請求偽造。即攻擊者在他自己的網(wǎng)站調(diào)用你的接口,達(dá)到修改你的網(wǎng)站數(shù)據(jù)的目的。

場景:用戶在斗魚論壇設(shè)置了“記住我的登錄狀態(tài)”,于是 douyu.com這個域名下保存了用戶的登錄cookies。攻擊者注意到斗魚修改用戶資料的接口douyu.com/updateUserInfo有CSRF漏洞,于是他偽造了一個斗魚論壇網(wǎng)站,并做了一個表單:

<html>
<body>
    <form id="csrf" action="douyu.com/updateUserInfo" method="POST">
        <input type="hidden" name="gender" value="2" />
        <input type="hidden" name="hometown" value="1234" />
        <input type="hidden" name="birthday" value="2020&#45;06&#45;11" />
        <input type="hidden" name="nick&#95;name" value="1234" />
        <input type="hidden" name="st" value="123" />
        
    </form>
</body>
<script type="text/javascript">
    function autoSubmit() {
        document.getElementById("csrf").submit();
    }
    autoSubmit()
</script>
</html>

這個表單會提交到douyu.com/updateUserInfo接口,由于用戶的瀏覽器保存了登錄的cookies,請求發(fā)送出去的時候,用戶的登錄態(tài)也會帶出去,斗魚驗證登錄態(tài)后,確認(rèn)了是用戶本人操作,允許了本次修改。

我們可以發(fā)現(xiàn),通過CSRF漏洞,攻擊者偽造了用戶的登錄態(tài),使修改用戶資料的操作成功了。如果本次操作不是修改用戶操作,而是轉(zhuǎn)賬等危害用戶資產(chǎn)安全的操作呢?

防御措施

由此可見,涉及資料修改的操作,僅驗證用戶登錄態(tài)是不夠的。還需要其他的驗證手段:

初級防御措施:判斷請求的Referer

請求中的Referer頭用于判斷該請求是在哪個頁面的基礎(chǔ)上發(fā)出去的,比如a.com請求了一張圖片douyu.com/1.jpg,那么圖片的Referer頭就為:Referer: a.com。
上面的攻擊場景中,服務(wù)器可以判斷請求的Referer頭,判斷該請求是否是官方網(wǎng)站douyu.com發(fā)出的,如果不是,則說明是第三方調(diào)用,禁止修改。
但是問題是,請求的請求頭是可以修改的,攻擊者只要將請求的Referer頭手動修改為douyu.com,就繞過了這層防御。

進(jìn)階防御措施:

  1. token校驗
    每個修改資料的請求,都必須攜帶一個token,而這個token只能在官方網(wǎng)站下生成,提交修改操作的時候,校驗這個token是否正確,只有正確才允許修改資料。
    這種驗證又叫做“加鹽”驗證。在表單中混入一個做校驗的表單項,用來給服務(wù)器做安全校驗。

  2. cookies設(shè)置Samesite
    設(shè)置保存登錄態(tài)的 cookies 只能在同一個域名的頁面下才會隨著請求一起發(fā)送。這樣可以保證cookies不會被第三方使用。但是也多了一個束縛是登錄態(tài)不能被其他我們受信任的域名共享。
    比如很多單點(diǎn)登錄的實(shí)現(xiàn)(即如果你在taobao.com登錄了,你訪問tmall.com的時候,會發(fā)現(xiàn)也是登錄著的)就是基于 cookies 共享,可能就會收到影響。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容