跨站腳本是應(yīng)用程序安全開(kāi)源基金會(huì) (OWASP) 前 10 名中第二個(gè)最普遍的問(wèn)題——它存在于大約 2/3 的所有應(yīng)用程序中。雖然自動(dòng)化工具可以發(fā)現(xiàn)其中的一些問(wèn)題,但也有一些旨在檢測(cè)和利用這些漏洞的自動(dòng)化工具。
什么是跨站腳本?
當(dāng)數(shù)據(jù)通過(guò)不受信任的來(lái)源(如 Web 請(qǐng)求)進(jìn)入 Web 應(yīng)用程序并未經(jīng)驗(yàn)證就發(fā)送給用戶時(shí),就會(huì)發(fā)生 XSS 攻擊。
XSS 會(huì)導(dǎo)致腳本在用戶的瀏覽器中執(zhí)行,從而導(dǎo)致會(huì)話被劫持、網(wǎng)站篡改以及將用戶重定向到惡意站點(diǎn)。
從本質(zhì)上講,攻擊者將惡意代碼輸入到用戶輸入的部分中,服務(wù)器希望該部分是數(shù)據(jù)(但實(shí)際上是為了執(zhí)行而設(shè)計(jì)的代碼)。
如果處理不當(dāng),惡意代碼可能會(huì)突破“數(shù)據(jù)平面”并作為正常代碼(“控制平面”)執(zhí)行。
我們可以將大多數(shù) XSS 攻擊分為兩類:存儲(chǔ)的和反射的。第三種不太常見(jiàn),稱為基于 DOM 的 XSS。
當(dāng)數(shù)據(jù)通過(guò)不受信任的來(lái)源進(jìn)入并發(fā)送給用戶(在動(dòng)態(tài)內(nèi)容中)而沒(méi)有檢查惡意內(nèi)容時(shí),就會(huì)發(fā)生任何 XSS 攻擊。惡意內(nèi)容可以是 JavaScript、Flash、HTML 或?yàn)g覽器能夠執(zhí)行的任何其他代碼。
反射型 XSS(影響:中等)
這是最基本的 XSS 類型,其中應(yīng)用程序接收數(shù)據(jù),然后以不安全的方式將這些數(shù)據(jù)包含在對(duì)用戶的響應(yīng)中。
例如,如果攻擊者說(shuō)服用戶單擊此網(wǎng)絡(luò)釣魚(yú)鏈接:
http://legitwebsite.com/message=<script>惡意代碼</script>
如果合法站點(diǎn)不處理數(shù)據(jù)而只是將其返回給用戶,則用戶的瀏覽器將執(zhí)行惡意代碼。
存儲(chǔ)型 XSS(影響:嚴(yán)重)
當(dāng)注入永久存儲(chǔ)在目標(biāo)的服務(wù)器上時(shí),就會(huì)發(fā)生存儲(chǔ)型 XSS,例如論壇或評(píng)論部分、數(shù)據(jù)庫(kù)中的消息等。從本質(zhì)上講,這意味著該漏洞會(huì)影響站點(diǎn)/應(yīng)用程序的每個(gè)訪問(wèn)者。
例如,如果站點(diǎn)允許用戶發(fā)表評(píng)論,然后顯示他們的評(píng)論,則用戶可以輸入以下內(nèi)容:
<p><script>惡意代碼</script></p>
如果站點(diǎn)沒(méi)有適當(dāng)?shù)貦z查用戶輸入,則可能會(huì)導(dǎo)致腳本為看到此消息的任何其他用戶執(zhí)行。
基于DOM的XSS/客戶端XSS(影響:中等)
反射型 XSS 和存儲(chǔ)型 XSS 與基于 DOM 的最大區(qū)別在于攻擊的注入位置。
反射和存儲(chǔ) XSS 是服務(wù)器端問(wèn)題,而基于 DOM 是客戶端(瀏覽器)端問(wèn)題?;?DOM 的 XSS 發(fā)生在 DOM(文檔對(duì)象模型)中,而不是作為 HTML 的一部分。
這種攻擊不是在頁(yè)面中插入惡意代碼,而是允許加載合法頁(yè)面,然后利用用戶輸入向頁(yè)面添加 HTML,執(zhí)行惡意腳本。這利用了客戶端生成的 HTML 數(shù)量不斷增加的優(yōu)勢(shì)。
例如,攻擊者可以通過(guò)社會(huì)工程使受害者點(diǎn)擊惡意鏈接(例如 http://www.legitimatewebsite.com/contact#<script>malicious code</script>)。該網(wǎng)站將收到對(duì)該頁(yè)面的合法請(qǐng)求,但不會(huì)收到惡意片段(因?yàn)闉g覽器不會(huì)向站點(diǎn)的服務(wù)器發(fā)送 # 字符后的任何內(nèi)容)。受害者會(huì)看到合法網(wǎng)站,但受害者的瀏覽器也會(huì)執(zhí)行惡意腳本。
由于這種攻擊的工作方式,服務(wù)器端保護(hù)不會(huì)阻止它,因?yàn)閻阂獯a根本沒(méi)有發(fā)送到服務(wù)器。
相反,防止這種攻擊需要確保 JavaScript 不會(huì)以不安全的方式解釋 URI 片段(統(tǒng)一資源標(biāo)識(shí)符 - URI 標(biāo)識(shí)指定位置的資源,例如 URL)。
XSS 攻擊的緩解措施
有效緩解 XSS 攻擊需要結(jié)合以下措施,當(dāng)您將它們結(jié)合使用時(shí),可以提供強(qiáng)大的 XSS 防御。
避免在指定位置以外的任何地方插入用戶提供的/不受信任的數(shù)據(jù)
這是第一個(gè)也是最重要的規(guī)則。編碼、轉(zhuǎn)義、驗(yàn)證和過(guò)濾輸入極其困難且非常復(fù)雜。
限制某人可以輸入不可信數(shù)據(jù)的位置要容易得多。最安全的假設(shè)是所有不受信任的數(shù)據(jù)都是惡意的。
驗(yàn)證/過(guò)濾輸入
理想情況下,所有輸入都應(yīng)根據(jù)可接受的值列表進(jìn)行驗(yàn)證。
編碼輸出
任何用戶輸入的數(shù)據(jù)都應(yīng)該被編碼以防止它被讀取為活動(dòng)的。這可能需要 CSS、JavaScript、URL 和/或 HTML 編碼。
確保輸出在任何暴露的點(diǎn)都被編碼尤為重要,因?yàn)橄嗤臄?shù)據(jù)可以存儲(chǔ)并顯示在多個(gè)位置。
謹(jǐn)慎選擇框架
使用提供自動(dòng)轉(zhuǎn)義功能的框架(如 Go 模板)或具有針對(duì) XSS 的本機(jī)防御(如 .NET 的請(qǐng)求驗(yàn)證)的框架。
設(shè)置 HttpOnly 標(biāo)志
XSS 攻擊通常使用 JavaScript 來(lái)竊取會(huì)話 cookie(而普通的 Web 應(yīng)用程序很少需要使用 JavaScript 來(lái)訪問(wèn)會(huì)話 cookie)。因此,設(shè)置 HttpOnly 標(biāo)志可以保護(hù)會(huì)話 cookie 免受攻擊者的攻擊,同時(shí)不會(huì)限制正常行為。大多數(shù)瀏覽器都支持設(shè)置這個(gè)標(biāo)志。
使用響應(yīng)頭
與 HttpOnly 標(biāo)志類似,任何不應(yīng)包含 HTML 或 JavaScript 的 HTTP 響應(yīng)都可以利用“Content-Type”和“X-Content-Type-Options”標(biāo)頭來(lái)確保瀏覽器僅以預(yù)期的方式解釋響應(yīng)。
對(duì)開(kāi)發(fā)人員進(jìn)行安全教育
專門針對(duì)開(kāi)發(fā)人員的教育,例如將應(yīng)用程序安全團(tuán)隊(duì)成員與開(kāi)發(fā)人員配對(duì)的“安全冠軍”計(jì)劃,很重要。它們可以幫助開(kāi)發(fā)人員了解安全漏洞(如 XSS)以及如何防止它們。
制定內(nèi)容安全政策
內(nèi)容安全策略 (CSP) 可以幫助您檢測(cè)和緩解 XSS 和其他數(shù)據(jù)注入攻擊。
他們?yōu)槭苄湃蝺?nèi)容的來(lái)源設(shè)置了許可名單,并且只能應(yīng)用于敏感頁(yè)面(如支付頁(yè)面),或者理想情況下,應(yīng)用于整個(gè)網(wǎng)站。如果內(nèi)容是從不應(yīng)加載的頁(yè)面加載的,他們甚至可以提供通知。
它們相當(dāng)容易部署 - 只需將 Content-Security-Policy HTTP 標(biāo)頭添加到網(wǎng)頁(yè)和任何適當(dāng)?shù)闹噶罴纯伞?/p>
該CSP提琴手?jǐn)U展可以幫助您生成一個(gè)基準(zhǔn)CSP。該工具將圍繞瀏覽器提交的報(bào)告構(gòu)建策略,創(chuàng)建可更改的基線策略。
此外,您可以使用由 Troy Hunt 和 Scott Helme 運(yùn)行的Report URI來(lái)獲取有關(guān) CSP 違規(guī)的警報(bào),以便更主動(dòng)地監(jiān)控您的站點(diǎn)。
通常,策略由一系列指令組成,這些指令將描述一種資源或區(qū)域的策略。這些指令之一,子資源完整性檢查,用于確保瀏覽器驗(yàn)證第三方內(nèi)容(來(lái)自 CDN 之類的來(lái)源)是在沒(méi)有被操縱的情況下交付的。
本質(zhì)上,提供的加密哈希必須與加載的文件匹配。如果黑客修改了第三方的內(nèi)容,該站點(diǎn)將不會(huì)加載惡意內(nèi)容。
問(wèn)題是,如果內(nèi)容提供者更新文件或進(jìn)行合法更改,內(nèi)容也不會(huì)加載(因?yàn)楣V狄迅模?/p>
解決此問(wèn)題的主要方法是利用版本化的 JavaScript 資源,例如 chatbot_0.1.23.js,而不是 chatbot.js。這是一般的最佳實(shí)踐,也保證了JS文件發(fā)生變化時(shí)服務(wù)的連續(xù)性。
雖然瀏覽器并不普遍支持此功能,但對(duì)于那些缺少該功能的瀏覽器,使用它不會(huì)破壞站點(diǎn)(它只是不會(huì)利用該技術(shù))。
有關(guān)各種指令的更多詳細(xì)信息,請(qǐng)查看這些 指南。