編譯自:blog.sqreen.io/reflected-x…
原作者:JB 發表時間:2018-03-08
譯者:西樓聽雨
什麼是反射式跨站指令碼攻擊(reflected XSS)?
首先,我們來了解下什麼是"跨站指令碼攻擊(XSS)":它是通過向網站注入惡意程式碼實現的,當某個使用者訪問受感染的頁面時,指令碼就會在其瀏覽器中執行,這時,攻擊者就可以竊取使用者的私有資訊,例如,cookie、賬戶資訊;也可以以受害者的身份執行一些惡意操作。
反射式跨站指令碼攻擊(也叫做非儲存式跨站指令碼攻擊 (non-persistent XSS))是一種特殊的跨站指令碼攻擊,這種攻擊,是將惡意指令碼從一個網站反彈出來,通常是通過URL的query傳遞的,只需要使用者點選一個連結就可達到。
和儲存式跨站指令碼攻擊(stored XSS)相比,非儲存式跨站指令碼攻擊只需要將惡意程式碼新增到連結上,然後欺騙、誘導使用者點選即可。
為什麼需要對反射式 XSS 留意?
因為,雖然反射式 XSS 對於攻擊者來說力度較弱,但它相對於儲存式 XSS 卻更常見,也更容易實現,它只需要使用者點選惡意連結即可達到,因此非常容易在郵件,論壇中部署;而且只要攻擊者成功部署,他們仍然可以執行任意的 javascript。這就等於把所有可程式設計式地觸發的操作全部給了攻擊者。例如,可以把比特幣使用者的比特幣與任意使用者進行交易。
另外,攻擊者也可以藉助在瀏覽器中執行惡意程式碼的機會,來進一步利用基於瀏覽器、作業系統、瀏覽器外掛的漏洞,以此獲取使用者電腦的操控權——通常會把其變為殭屍網路中的一員。
而且由於反射式 XSS 通常是通過採用社會學工程學來誘導使用者點選惡意連結,例如,製作一個假冒的登陸頁面,這種性質,使得它從使用者的角度看,不管是HTTPS,URL,甚至是密碼管理器都會把其視為正常情況並自動填寫表單。
如何消除 XSS 漏洞?
XSS 漏洞通常是由於在渲染模板中缺少對使用者提供的資料進行轉義所致的,例如使用者在輸入框控制元件中的輸入。下面是一個簡單的例子,它是一個典型的 Runy on Rails 模板,裡面有來自不同地方的由使用者提供的資料。(其他語言中的引擎也是一個道理)
<div>
<h1>Blog post: <%= @post.title %></h1> (1)
<br />
<a href=“<%= @post.url %>”>Click here to see the full story</a> (2)
<script>
record_post_view(@post.id); (3)
</script>
<div id=“footer” <%= @post.footer_attr %>>© 2018</div> (4)
</div>
複製程式碼
在這個例子中有四個資料點,他們需要進行不同型別的轉義。
這四個點都有發生 XSS 的可能,下面這張表格是注入 alert(0) 的方式及措施。
變數 | 注入程式碼 | Rails 的轉義函式 |
---|---|---|
@post.title | script>alert(0);</script | ERB::Util.html_escape |
@post.url | “ onblur=javascript:alert(0) “ or “> | ERB::Util.html_escape |
@post.id | 123); alert(0); | 無對應函式 – 確保 @post.id 為整數即可 |
@post.footer_attr | onblur=javascript:alert(0) | 無對應函式 – 確保使用者不注入任何屬性即可 |
所以對資料進行轉義才是關鍵所在。這要求開發者在模板中插入資料時記得對資料進行轉義。
如何實時地阻止 XSS?
老舊的方式——網路防火牆
標準 "Web應用防火牆”(WAF)及“下一代 Web 應用防火牆”的工作原理都一樣,都是通過探測——觀察網路資料——來阻止攻擊者。他們的工作任務就是:嘗試對入站的HTTP請求進行匹配。
但是 WAF 存在幾個問題:首先你得把你的所有流量進行重定向,從隱私和延遲角度看,這並不友好;然後如果在已有的 XSS 指紋庫(signature database)中無法找到匹配的資訊,它就會被漏掉。它也永遠無法做到涵蓋最新的指紋,也很容易被繞過;而且誤報的情況過多,使得它無論是在保護模式還是監視模式下使用起來都很痛苦。
所以像這種從應用外部來阻止攻擊的方式其實並沒有什麼意義。就像是,你在對一個請求的任何技術細節都無法掌握到的情況下,你會通過一個外部的“探測器”來對其中某一個特定的部分做效能監控嗎?
正確的方式——從應用內部檢測攻擊
和其他 Web 應用中的漏洞一樣,很難找到一種比在應用本身內部進行觀察更可靠的方式來阻止這樣一種攻擊。
上一個例子中,@post.title
變數並沒有被轉義,所以如果這個變數從 URL 進行了反射,這時就會出現反射式 XSS:
<h1>Blog post: <%= raw @post.title %></h1>複製程式碼
為了檢測到這樣一個未進行轉義的資料,你需要在模板引擎中掛入一個鉤子,對來自客戶端的,如,URL引數、HTTP請求頭,以及請求體進行檢測,這樣你才能精準地發現反射式 XSS,而且不會有像上面提到的誤報的情況。
其實這正是 Sqreen 的工作原理,因為我們處於應用之內,我們可以檢測到未轉義的資料。
當 Sqreen 檢測到在模板中有未轉義的部分使用了來自使用者提供的引數時,你可以決定對其進行哪些處理,比如:
——阻止請求
——(在執行時)對可執行的那部分程式碼進行轉義
——把呼叫棧資訊傳送給開發人員
——POST 到 webhook
——傳送通知到 slack 或者 Pagerduty
這就是 Sqreen 如何保護應用程式免受反射式 XSS 攻擊的方式。
如果你有使用 Vue.js 並且對如何在 Vue 中防禦 XSS 感興趣,你可以看下我們之前的文章。