前端筆記(14)web網(wǎng)頁安全

同源策略

  1. 同源策略是web頁面安全中心最基礎(chǔ)、最核心的安全策略。
  2. 如果兩個(gè)URL的協(xié)議、域名和端口都相同,我們就稱這兩個(gè)URL同源。

同源策略的表現(xiàn)

1. DOM層面

同源策略限制了不同源的JavaScript腳本對(duì)當(dāng)前DOM對(duì)象讀寫的操作。

// a網(wǎng)頁控制臺(tái)輸入
window.open("b.test.com")

// b網(wǎng)頁控制臺(tái)輸入
opener.document.body.style.display = "none"

如果兩個(gè)網(wǎng)頁同源,第二個(gè)b網(wǎng)頁控制臺(tái)可以修改a網(wǎng)頁控制臺(tái)DOM。如果兩個(gè)網(wǎng)頁不同源,b網(wǎng)頁無法獲取到a網(wǎng)頁的document對(duì)象。

2. 數(shù)據(jù)層面

同源策略限制了不同源的站點(diǎn)讀取當(dāng)前站點(diǎn)的Cookie、IndexDB、LocalStorage等數(shù)據(jù)。

// a網(wǎng)頁控制臺(tái)輸入
window.open("b.test.com")
// b網(wǎng)頁控制臺(tái)輸入
opener.localStorage

3. 網(wǎng)絡(luò)層面

跨域問題

安全與便利的權(quán)衡

不同源之間絕對(duì)隔離無疑是最安全的,但是也使得Web項(xiàng)目難以開發(fā)和使用。因此瀏覽器實(shí)現(xiàn)上出讓了同源策源的部分安全性。

1. 頁面中可以引入第三方資源

同源策略需要一個(gè)頁面的所有資源都來自于同一個(gè)源,無疑違背了Web開放的初衷。所以最初的瀏覽器都是支持外部引用資源文件的。但是這也造成了Web頁面被XSS攻擊的風(fēng)險(xiǎn)。

2. 跨域資源共享與跨文檔消息機(jī)制

  • 為了解決跨域問題,引入了跨域資源共享(CORS),使用該機(jī)制可以進(jìn)行跨域訪問控制,從而保證跨域數(shù)據(jù)傳輸?shù)陌踩M(jìn)行,但是這也使得頁面存在被CSRF攻擊的風(fēng)險(xiǎn)。
  • 為了解決不同源的DOM之間進(jìn)行通信,瀏覽器引入了跨文檔消息機(jī)制,可以通過window.postMessage來和不同源的DOM進(jìn)行通信(使用過程中message事件必須要使用origin和source屬性來檢查消息的發(fā)送者的身份,否則存在XSS攻擊的風(fēng)險(xiǎn))
// a網(wǎng)頁控制臺(tái)輸入
window.open("b.test.com")
window.addEventListener("message",event=>{
    console.log(event)
})

// b網(wǎng)頁控制臺(tái)輸入
opener.postMessage("123","http://a.test.com")

跨站腳本攻擊(XSS)

XSS全稱Cross Site Scripting,為了與css樣式區(qū)分開,所以成為XSS。XSS攻擊是指黑客往HTML文件或者DOM中注入惡意腳本,從而在用戶瀏覽網(wǎng)頁時(shí)對(duì)用戶實(shí)施攻擊的一種手段。最開始的時(shí)候,這種攻擊是通過跨站點(diǎn)實(shí)現(xiàn)的,但是發(fā)展到后面,注入惡意腳本的方法越來越多,但是XSS的這個(gè)名字一直保留下來。

XSS的危害

惡意腳本可以做很多事情,下面舉幾個(gè)例子。

  • 竊取Cookie信息,惡意腳本獲取到用戶cookie信息,通過fetch或者XMLHttpRequest加上CORS功能將數(shù)據(jù)發(fā)動(dòng)給惡意服務(wù)器,惡意服務(wù)器拿到cookie以后就可以在其他電腦上模擬用戶的登錄。
  • 監(jiān)聽用戶行為,惡意腳本通過“addEventListener”監(jiān)聽鍵盤事件,獲取用戶輸入的銀行卡、密碼等信息,并將其發(fā)送到惡意服務(wù)器。
  • 通過修改DOM偽造假的登錄窗口,欺騙用戶輸入用戶名與密碼。
  • 在頁面內(nèi)生成浮窗廣告。

常見的XSS攻擊方式

1. 存儲(chǔ)型XSS攻擊

存儲(chǔ)型XSS攻擊的幾個(gè)步驟:

  • 黑客利用網(wǎng)站漏洞將惡意腳本提交到網(wǎng)站的數(shù)據(jù)庫中;
  • 用戶向網(wǎng)站請(qǐng)求包含了惡意腳本的網(wǎng)頁,或者ajax請(qǐng)求返回的惡意腳本數(shù)據(jù)被插入到DOM中。


上面的例子中,如果前端網(wǎng)頁直接將后端返回的數(shù)據(jù)顯示在網(wǎng)頁上,所有訪問此文章的用戶都將會(huì)收到攻擊。

2. 反射型XSS攻擊

服務(wù)端將未經(jīng)處理的url參數(shù)直接渲染到頁面上。存在此漏洞的網(wǎng)站黑客可以通過聊天軟件或者郵箱誘導(dǎo)用戶點(diǎn)擊惡意鏈接。

// 正常請(qǐng)求
www.test.com?id=123
// 惡意鏈接
www.test.com?id=<script>alert(123)</script>

3. 基于DOM的XSS攻擊

不涉及Web服務(wù)器的情況下也可以進(jìn)行XSS攻擊。比如通過網(wǎng)絡(luò)劫持修改HTML頁面的內(nèi)容,例如通過路由器或者本地惡意軟件來劫持。

XSS真實(shí)案例

喜馬拉雅XSS漏洞
新浪微博XSS漏洞

如何阻止XSS攻擊

存儲(chǔ)型XSS與反射型XSS攻擊屬于是服務(wù)端的安全漏洞,基于DOM的XSS攻擊屬于前端漏洞。但是無論哪種形式的攻擊共同點(diǎn)都是首先向頁面中插入惡意腳本。

1. 服務(wù)器對(duì)輸入進(jìn)行轉(zhuǎn)碼

// 轉(zhuǎn)碼前
<script>alert('XSS攻擊')</script>
// 轉(zhuǎn)碼后
&lt;script&gt;alert(&#39;XSS攻擊&#39;)&lt;/script&gt;

轉(zhuǎn)碼后的內(nèi)容即使插入到頁面中也不會(huì)執(zhí)行。
有些站點(diǎn)會(huì)對(duì)<script>關(guān)鍵字進(jìn)行過濾,但是這樣并不完全安全,例如利用less可以執(zhí)行JavaScript的漏洞進(jìn)行攻擊。

<!DOCTYPE html>
<html lang="en">
  <style type=text/less>a{a:`alert(123)`}</style>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/less.js/2.7.1/less.min.js" ></script>
</html>

2. 使用CSP策略

csp策略可以通過配置"content-security-policy"響應(yīng)頭有效的防范XSS攻擊。CSP策略有如下幾個(gè)功能:

  • 限制加載其他域的資源;
  • 禁止像第三方域提交數(shù)據(jù);
  • 禁止執(zhí)行內(nèi)聯(lián)腳本和未授權(quán)的腳本;
  • 上報(bào)機(jī)制,幫助站點(diǎn)盡快發(fā)現(xiàn)有哪些XSS攻擊。

雖然CSP可以有效的防御XSS攻擊,但是由于限制較多所以實(shí)際使用的web網(wǎng)頁并不多??梢詤⒖糶ithub、知乎。

3. 使用HttpOnly屬性

由于很多XSS攻擊都是用來盜用Cookie的,因此還可以通過HttpOnly屬性標(biāo)記重要的cookie,是得其只能在HTTP請(qǐng)求過程中訪問,無法通過javaScript腳本讀取。

跨站請(qǐng)求偽造(CSRF)

CSRF全稱是Cross-site request forgery。CSRF攻擊是指黑客利用了用戶的登錄狀態(tài),并通過第三方的站點(diǎn)做一些壞事。

常見的CSRF攻擊方式

1. 自動(dòng)發(fā)起Get請(qǐng)求

<!DOCTYPE html>
<html>
  <body>
    <h1>惡意站點(diǎn)</h1>
    <img src="https://www.test.com?user=hacker&number=100">
  </body>
</html>

黑客將請(qǐng)求接口隱藏在img標(biāo)簽內(nèi),當(dāng)頁面被加載時(shí)就會(huì)自動(dòng)發(fā)起img的資源請(qǐng)求,如果服務(wù)器沒有做過濾判斷的話,服務(wù)器就會(huì)認(rèn)為該請(qǐng)求是一個(gè)轉(zhuǎn)賬請(qǐng)求。

2. 自動(dòng)發(fā)起POST請(qǐng)求

<!DOCTYPE html>
<html>
<body>
  <h1>惡意網(wǎng)站</h1>
  <form id='hacker-form' action="https://www.test.com" method=POST>
    <input type="hidden" name="user" value="hacker" />
    <input type="hidden" name="number" value="100" />
  </form>
  <script> document.getElementById('hacker-form').submit(); </script>
</body>
</html>

3. 引誘用戶點(diǎn)擊鏈接


<div>
  <a  taget="_blank">
    點(diǎn)擊下載
  </a>
</div>

與XSS不同,CSRF攻擊不需要將惡意代碼注入到用戶的頁面,僅僅是利用服務(wù)器的漏洞和用戶的登錄狀態(tài)來實(shí)施攻擊。發(fā)起CSRF攻擊有三個(gè)必要的條件:

  • 目標(biāo)站點(diǎn)一定要有CSRF漏洞;
  • 用戶登陸過目標(biāo)站點(diǎn),并且在瀏覽器上保持有站點(diǎn)的登錄狀態(tài);
  • 用戶打開一個(gè)第三方站點(diǎn),可以是黑客的惡意站點(diǎn),也可以是一些論壇。

CSRF真實(shí)案例

百度CSRF蠕蟲攻擊

如何防止CSRF攻擊

1. 利用好Cookie的SameSite屬性

想要進(jìn)行CSRF攻擊就必須要有用戶的登錄狀態(tài),大部分網(wǎng)站中Cookie都是瀏覽器與服務(wù)器之間維護(hù)登錄狀態(tài)的一個(gè)關(guān)鍵數(shù)據(jù)。并且大多數(shù)CSRF攻擊是需要從第三方站點(diǎn)發(fā)起,如果我們從第三方站點(diǎn)發(fā)送請(qǐng)求時(shí)禁止關(guān)鍵Cookie的發(fā)送,就可以有效降低CSRF攻擊的風(fēng)險(xiǎn)。
Cookie中的SameSite屬性正是為了解決這個(gè)問題。SameSite有個(gè)值:

  • Strict: 完全禁止第三方Cookie。
  • Lax: 相對(duì)寬松。在跨站點(diǎn)(頂級(jí)域名+二級(jí)域名相同的為同一站點(diǎn))的情況下第三方站點(diǎn)的<a>標(biāo)簽鏈接、Get方式的表單提交、預(yù)加載會(huì)攜帶Cookie。Post表單、ajax請(qǐng)求、img、iframe等都不會(huì)攜帶Cookie。
  • None: 任何情況下都會(huì)攜帶Cookie。

兼容性問題:

  • 大多數(shù)主流瀏覽器的最新版本中,默認(rèn)值都為L(zhǎng)ax。如果想要設(shè)置為None則必須要Secure一起使用,也就是說只能在https請(qǐng)求中使用None。

  • 最新的safari瀏覽器中,默認(rèn)值為Strict,并且不支持None,設(shè)置為None時(shí)會(huì)被當(dāng)成默認(rèn)值處理。

  • 具體瀏覽器兼容版本查看 MDN SameSite Cookie

2. 驗(yàn)證請(qǐng)求來源

由于CSRF攻擊大多來自于第三方站點(diǎn),所以我們可以通過判斷請(qǐng)求是否來自于第三方站點(diǎn)來過濾請(qǐng)求。

  • Referer:Referer請(qǐng)求頭字段記錄了HTTP請(qǐng)求的來源地址。但是有些場(chǎng)景為了安全考慮不適合把原站點(diǎn)的詳細(xì)路徑暴露給服務(wù)器,所以瀏覽器提供了設(shè)置關(guān)閉Referer值的上傳。
  • Origin:由于驗(yàn)證Referer屬性并不可靠,所以又制定了Origin屬性,Origin屬性只包括域名信息,沒有具體的URL路徑。

可以在使用CORS(跨站資源共享)時(shí)設(shè)置Access-Control-Allow-Origin響應(yīng)頭來指示可以共享給哪些域。

3. CSRF Token

CSRF Token的實(shí)現(xiàn)方法有很多,目的都是為了驗(yàn)證請(qǐng)求是否是來自第三方。
介紹幾種常見的方式

  • 響應(yīng)頁面時(shí)將token渲染到頁面上,表單提交的時(shí)候通過隱藏域提交到服務(wù)端;
  • 將token設(shè)置在Cookie中,在提交請(qǐng)求時(shí)將提交Cookie,并通過header或者body帶上Cookie中的token,服務(wù)端進(jìn)行對(duì)比校驗(yàn);
  • 信任帶有特定header的請(qǐng)求。(比較容易被繞過)

XST攻擊

XST全程是Cross-Site Tracing。雖然cookies設(shè)置為httpOnly以后被XSS攻擊也無法輕易盜用cookie,但是針對(duì)支持TRACE請(qǐng)求的服務(wù)器,客戶端可以通過發(fā)送TRACE請(qǐng)求獲取到完整的頭信息。通過這種方式也是可以拿到設(shè)置為httpOnly的Cookie。
可以通過禁止trace,track等危險(xiǎn)請(qǐng)求類型來防范被攻擊。
現(xiàn)代瀏覽器已經(jīng)禁止了trace、track梁總請(qǐng)求,會(huì)拋出異常。

HPP攻擊

Http Parameter Pollution(HPP),即 HTTP 參數(shù)污染攻擊。在 HTTP 協(xié)議中是允許同樣名稱的參數(shù)出現(xiàn)多次,而由于應(yīng)用的實(shí)現(xiàn)不規(guī)范,攻擊者通過傳播參數(shù)的時(shí)候傳輸 key 相同而 value 不同的參數(shù),從而達(dá)到繞過某些防護(hù)的后果。HPP 可能導(dǎo)致的安全威脅有:

  • 繞過防護(hù)和參數(shù)校驗(yàn)。
  • 產(chǎn)生邏輯漏洞和報(bào)錯(cuò),影響應(yīng)用代碼執(zhí)行。
    可以通過針對(duì)相同key的請(qǐng)求時(shí),強(qiáng)制使用第一個(gè)或者最后一個(gè)來避免hpp攻擊。

HPP真實(shí)案例

twitter HPP漏洞
百度RASP HPP漏洞

SSRF攻擊

通過 Server-Side Request Forgery(SSRF)攻擊,攻擊者可以發(fā)起網(wǎng)絡(luò)請(qǐng)求訪問或者操作內(nèi)部網(wǎng)絡(luò)的資源。
一般來說,SSRF 安全漏洞常見于開發(fā)者在服務(wù)端直接請(qǐng)求客戶端傳遞進(jìn)來的 URL 資源,一旦攻擊者傳入一些內(nèi)部的 URL 即可發(fā)起 SSRF 攻擊。

通常我們會(huì)基于內(nèi)網(wǎng) IP 黑名單的形式來防范 SSRF 攻擊,通過對(duì)解析域名后得到的 IP 做過濾,禁止訪問內(nèi)部 IP 地址來達(dá)到防范 SSRF 攻擊的目的。

SSRF真實(shí)案例

利用SSRF漏洞獲取AWS密碼憑據(jù)

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

相關(guān)閱讀更多精彩內(nèi)容

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