前言php
平時不多關注安全這塊的技術,曾經也買過一本《Web前端黑客技術揭祕》但至今還沒翻過,尷尬。今天的早讀文章由騰訊優測@小吉帶來的分享。html
正文從這開始~前端
最近深刻了解了一下XSS攻擊。之前總浮淺的認爲XSS防護僅僅只是輸入過濾可能形成的XSS而已。然而這池子水深的很吶。java
XSS的類型node
整體來講,XSS分三類,存儲型XSS、反射型XSS、DOM-XSS。react
存儲型XSSjquery
數據庫中存有的存在XSS攻擊的數據,返回給客戶端。若數據未通過任何轉義。被瀏覽器渲染。就可能致使XSS攻擊;數據庫
反射型XSSjson
將用戶輸入的存在XSS攻擊的數據,發送給後臺,後臺並未對數據進行存儲,也未通過任何過濾,直接返回給客戶端。被瀏覽器渲染。就可能致使XSS攻擊;後端
DOM-XSS
純粹發生在客戶端的XSS攻擊,好比:http://www.some.site/page.html?default=French
頁面代碼:
該XSS攻擊實現條件:
用戶點擊了以下鏈接:
http://www.some.site/page.html?default=<script>alert(document.cookie)</script>
後臺對URL參數未作任何過濾處理,返回給客戶端,前端直接從url上獲取參數。
打開網址的瀏覽器是低版本瀏覽器,常見ie8如下
知足以上三者,就會致使URL上的js代碼執行:alert(document.cookie),可是攻擊者能夠利用這個,作你沒法想象的事情。在現代瀏覽器中,已經作了xss過濾,一旦檢測到xss,會提示報錯以下:
以上即是學術上的劃分的XSS攻擊類型,二、3類型其實都是反射型的攻擊。瞭解了這些,意識到XSS攻擊無處不在啊。那麼如何對XSS進行防護?從輸入到輸出都須要過濾、轉義。
XSS防護—輸入輸出的過濾和數據轉義
輸入
客戶端求情參數:包括用戶輸入,url參數、post參數。
在產品形態上,針對不一樣輸入類型,對輸入作變量類型限制。
如,http://xss.qq.com?default=12,Default值強制限制爲整形。
咱們的後臺是node,使用joi對於輸入作類型限制:
字符串類型的數據,須要針對<、>、/、’、」、&五個字符進行實體化轉義。
輸出
即便在客戶端對用戶的輸入作了過濾、轉義,攻擊者同樣可能,經過截包,轉發等手段,修改你的請求包體。最終仍是要在數據輸出的時候作數據轉義。
好啦,到數據轉義啦,不就是對<>,'&"這些字符作實體化轉義嗎?若是你認爲這麼簡單,NO NO NO…由於瀏覽器解析中html和js編碼不同,以及上下文場景多樣,因此對於後臺輸出的變量,不一樣的上下文中渲染後端變量,轉碼不同。
下面的HTML片斷顯示瞭如何安全地在多種不一樣的上下文中渲染不可信數據。
狀況一
數據類型:String
上下文:HTML Body
示例代碼:<span>UNTRUSTED DATA</span>
防護措施:HTML Entity編碼
狀況二
數據類型:String
上下文:安全HTML變量
示例代碼:<input type="text" name="fname" value="UNTRUSTED DATA">
防護措施
1. HTML Attribute編碼
2. 只把不可信數據放在安全白名單內的變量上(白名單在下文列出)
3. 嚴格地校驗不安全變量,如background、id和name
狀況三
數據類型:String
上下文:GET參數
示例代碼:<a href="/site/search?value=UNTRUSTED DATA">clickme</a>
防護措施:URL編碼
狀況四
數據類型:String
上下文:使用在src或href變量上的不可信URLs
示例代碼:
<a href="UNTRUSTED URL">clickme</a>
<iframe src="UNTRUSTED URL" />
防護措施:
1. 對輸入進行規範化
2. URL校驗
3. URL安全性認證
4. 只容許使用http和https協議(避免使用JavaScript協議去打開一個新窗口)
5. HTML Attribute編碼
狀況五
數據類型:String
上下文:CSS值
示例代碼:<div style="width: UNTRUSTED DATA;">Selection</div>
防護措施:
1. 使用CSS編碼
2. 使用CSS Hex編碼
3. 良好的CSS設計
狀況六
數據類型:String
上下文:JavaScript變量
示例代碼:
<script>var currentValue='UNTRUSTED DATA';</script>
<script>someFunction('UNTRUSTED DATA');</script>
防護措施:
1. 確保全部變量值都被引號括起來
2. 使用JavaScript Hex編碼
3. 使用JavaScript Unicode編碼
4. 避免使用「反斜槓轉譯」(\"、\'或者\)
狀況七
數據類型:HTML
上下文:HTML Body
示例代碼:<div>UNTRUSTED HTML</div>
防護措施:
[HTML校驗 (JSoup, AntiSamy, HTML Sanitizer)]
(https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet#RULE_.236_-_Use_an_HTML_Policy_engine_to_validate_or_clean_user-driven_HTML_in_an_outbound_way)
狀況八
數據類型:String
上下文:DOM XSS
示例代碼:<script>document.write("UNTRUSTED INPUT: " + document.location.hash);<script/>
防護措施:
基於DOM操做的XSS漏洞防護措施
全部輸出的數據轉義都應該遵照上表的規則,而針對同步數據和異步數據,有較大的使用區別作了區分:
同步數據
React頁面主動屏蔽掉XSS,非react則須要對不可信任數據,要進行輸出轉義。
對於html白名單需求,可使用SanitizeHelper模塊提供了一個方法集合來處理非預期的HTML元素。
不一樣的使用方式,編碼方式不一樣,java現成的工具能夠用——ESAPI,不一樣位置如何轉義可參照ESAPI文檔,好比屬性值轉義:
String safe = ESAPI.encoder().encodeForHTMLAttribute(
request.getParameter( "input" ) );
異步、後臺直出給js使用的json數據
對於不可信任的json數據。由於json數據可能用到不一樣的地方,因此轉義能夠放在前端js去轉義。
參與運算的動態變量,最好轉化爲對應類型後再運算。如number型.
若是是字符串操做,保證字符串被引號包裹。
不能使用eval ,new fuction,settimeout執行動態字符串,由於這個字符串極可能就是一個xss代碼,若是沒法避免,那麼也要轉義以後再參與運算。
輸出到頁面上的數據必須使用相應方法轉義,前端能夠考慮尋找js插件處理。目前jquery-encoder,可用於前端json轉義。使用方式與ESAPI相似,在須要渲染的時候進行轉義。
前端XSS防護方案大體如上,整理了這麼多幹貨內容,做爲小前端的我,表示要吸取好幾天。
最後,再跟你們分享個實際工做中的案例吧
除了上面的XSS攻擊,分享一個讓你意想不到的安全漏洞。
在優測項目,早期研發環境中,咱們的測試人員提出了以下的安全漏洞:
以下登陸頁面咱們爲了用戶能在登陸以後訪問到以前瀏覽的頁面,因此在url加入了一個service參數,可是未對它作任何校驗,可能會被釣魚網站利用。
該攻擊實現條件:
用戶點擊了以下鏈接:
https://cas.utest.qq.com/qqlogin?service=http%3A%2F%2Fpianzi.com;
後端未對service參數作校驗,這個鏈接能夠正常跳轉到上圖的頁面;
用戶輸入賬號登陸後,跳轉到http://pianzi.com;
這是個釣魚網站,經過網站風格欺騙,對用戶進行引導性操做;
用戶輸入一些有用的信息;
在不知不覺之間,用戶泄漏了本身的信息。
好深的套路啊~~研發哥哥趕忙尋找解決辦法,最終確認方案爲:對登陸後跳轉地址採用白名單機制。
對於這個老生長談的XSS攻擊,WEB開發者,只是瞭解其一,前端出身的孩子,對這方面瞭解甚少,跟我同樣幾乎沒這方面意識的同窗怕是也有很多。
做爲懶人一枚,作什麼都想找一個一勞永逸的辦法,可是對於XSS攻擊,無處不在,沒有一個很好的全局處理方案。前端小朋友多瞭解瞭解常規的XSS攻擊,在碼代碼的時候有這個防攻擊意識,也是極好的。
前端安全還有許多瞭解的方面,如何預防csrf攻擊,啓用現代瀏覽器安全防護等等,都須要去了解。
最後,若是你是前端開發,騰訊優測H5測試絕對是你的開發好助手,提高開發效率那是槓槓滴!有機會你們能夠玩玩。