前端安全知識以及防范

基礎(chǔ)

XSS就是讓瀏覽器執(zhí)行想插入的js垄琐。那么如何發(fā)現(xiàn)這些漏洞呢?只要有輸入和輸出的地方都伴隨著漏洞的產(chǎn)生惯悠,下面介紹基礎(chǔ)的XSS漏洞分析洲胖。
XSS攻擊并非一個<sc+ript+>al+ert('xs+s漏洞')</script>(這里請看源碼)語句就可以檢測。

<script>alert('xss漏洞')</script>
  • XSS初級測試(反射型XSS):
    反射型XSS需要欺騙用戶點擊才能觸發(fā)XSS代碼蛛芥。

  • 輸入框是否過濾<>’”/等字符提鸟,輸入框中輸入這些字符后提交军援,查看網(wǎng)頁源碼中這四個字符有沒有被過濾仅淑;

  • 在輸入框或者url的參數(shù)中輸入<img onerror=alert(1) src=1>后,如果出現(xiàn)界面錯誤胸哥,那就提BUG吧涯竟;

  • 使用eval()函數(shù),該函數(shù)執(zhí)行js代碼空厌,輸入框輸入或者url參數(shù)等于eval("alert('Hello world')”)庐船,是否能夠執(zhí)行。

  • XSS中級測試:

  • 寬字節(jié)注入漏洞嘲更,GB系列這些編碼格式只有兩個字節(jié)筐钟,引起的安全問題是吃一個ASCII字符的現(xiàn)象像一個<input type=“text” value=“”> 的語句,我們要做的是閉合雙引號(%22)赋朦,但是如果value輸入%22的話就會被轉(zhuǎn)義為%5C%22篓冲,如果輸入%C0%22 /><script>alert(1)</script>的話李破,過濾器發(fā)現(xiàn)%22加入轉(zhuǎn)義(%5C),然而%C0吃掉了%5C壹将,這樣就閉合了前面的雙引號嗤攻。

  • 存儲型XSS,和前面的反射型XSS不同诽俯,是將XSS代碼提交服務(wù)器中并存儲下來妇菱,其他人在訪問能拿到該字段的頁面就會觸發(fā)XSS代碼執(zhí)行。我找到了一個烏云上淘寶寶貝詳情的存儲型XSS暴区。

  • 測試建議:

  • 必須對所以交互的輸入字符闯团、http請求頭部變量、cookie變量等檢測字符和html關(guān)鍵字段仙粱;

  • 前端或者客戶端做了過濾還不夠偷俭,服務(wù)端也要進行過濾;

  • 為了防止存儲型XSS產(chǎn)生缰盏,對存入數(shù)據(jù)庫的字段不光要在輸入字符時進行過濾和檢測涌萤,還要在數(shù)據(jù)庫字段輸出到頁面時進行過濾和檢測;

  • 網(wǎng)上已有的XSS代碼:XSS代碼口猜;

  • 烏云上很多XSS漏洞的真實例子负溪,大家測試之余可以去搜來看看,烏云網(wǎng)站济炎。

深入

XSS攻擊的本質(zhì)是執(zhí)行代碼川抡,根據(jù)代碼在頁面中的執(zhí)行環(huán)境可分為3種:

1.存儲型XSS
用戶訪問正常的URL,觸發(fā)代碼執(zhí)行须尚。
大部分情況是由于過濾不完全或未轉(zhuǎn)碼崖堤,直接渲染到頁面中,導(dǎo)致代碼執(zhí)行耐床。

2.DOM型XSS
用戶訪問正常的URL密幔,觸發(fā)代碼執(zhí)行。
前端人員經(jīng)常把數(shù)據(jù)埋在Dom節(jié)點中撩轰,然后通過JS代碼獲取內(nèi)容胯甩,渲染,然后插入到頁面中堪嫂,導(dǎo)致代碼被執(zhí)行偎箫。

3.反射型XSS
用戶訪問經(jīng)過特殊構(gòu)造的URL,觸發(fā)代碼執(zhí)行.
常通過垃圾郵件傳播皆串,郵件內(nèi)容大多是具有誘惑性的內(nèi)容淹办,引誘點擊。QQ被盜后恶复,空間說說等經(jīng)常出現(xiàn)不明鏈接等等怜森。

存儲型XSS漏洞根據(jù)代碼執(zhí)行位置不同齐遵,又可分為:

1.HTML存儲型

發(fā)表文章,填寫資料塔插,留言等數(shù)據(jù)提交到后臺梗摇,過濾不全,在用戶訪問頁面的時候想许,惡意內(nèi)容渲染到頁面中伶授,導(dǎo)致攻擊。

2.CSS存儲型
常見于淘寶店鋪裝修流纹,網(wǎng)頁換膚糜烹,背景圖等,這些地方都需要用戶提交CSS樣式漱凝,甚至引入外部JS疮蹦,如果對輸入沒有做嚴格的校驗,直接渲染到頁面茸炒,極易產(chǎn)生安全隱患

淘寶商品詳情頁的評論記錄愕乎,交易記錄都曾被非法篡改。

攻擊的方式多種多樣壁公,CSS支持unicode感论,很多漏洞直接采用編碼的方式繞過安全漏洞。

<div style="width:expression(if(!window.x){alert(1);window.x=1})"></div>
<link rel=stylesheet href=data:,*%7bx:expression(if(!window.x)%7balert(1);window.x=1%7d)%7d />
<div style="width:expression(if(!window.x){alert(1);window.x=1})"></div>
<table background="javascript:alert(/xss/)"></table>'

3.JS存儲型

這種比較少見紊册,有時候會前端會使用eval,jQuery.globalEval,前者在代碼中比較常見比肄,1688這邊,去年安全部集中處理過一批這些漏洞囊陡。

用戶一般難以直接輸入JS代碼芳绩,但有時候,前端開發(fā)人員會要求將數(shù)據(jù)直接轉(zhuǎn)成JS代碼撞反,放入到頁面中妥色,方便獲取,如果內(nèi)容未經(jīng)過安全處理痢畜,攻擊者就會嘗試中斷正常的代碼邏輯垛膝,插入攻擊代碼。

Dom型XSS攻擊

'''
前端開發(fā)者丁稀,經(jīng)常將數(shù)據(jù)存放在Dom節(jié)點,在某個時候倚聚,獲取節(jié)點的數(shù)據(jù)线衫,然后插入到頁面中,插入到頁面時惑折,常使用jQuery('body').html('<script>alert(3)</script>') 操作授账,導(dǎo)致代碼被執(zhí)行枯跑。

反射型XSS攻擊

用戶訪問經(jīng)過特殊構(gòu)造的URL,URL參數(shù)中會攜帶攻擊代碼白热。

現(xiàn)在我們假設(shè)一種攻擊場景:私信

  1. 攻擊者A敛助,利用私信功能向用戶B發(fā)送私信,私信內(nèi)容存在攻擊代碼(JS)
  2. 用戶瀏覽私信屋确,瀏覽的過程中纳击,JS代碼在同域名下,毫無顧忌地執(zhí)行攻臀,相當于開發(fā)方自己的代碼
  3. 用戶B成為受害者
  4. 攻擊代碼可以將受害者B的其它私信提交到自己的內(nèi)容收集平臺
  5. 攻擊代碼自動與好友發(fā)送私信焕数,私信內(nèi)容與上述一樣。從而產(chǎn)生新的受害者刨啸。堡赔。。设联。
  6. 如此循環(huán)

可以看到善已,用戶B的私密消息,完全被暴露离例。
很多網(wǎng)站產(chǎn)品會讓用戶填寫個人資料雕拼,身份證,姓名等等粘招,一旦發(fā)生此類攻擊啥寇,用戶的信息也就被泄露了。
目前網(wǎng)站依賴token做CSRF校驗洒扎,其有效的前提是不存在XSS漏洞辑甜,token不會泄露。

防御

在編寫代碼的時候袍冷,盡量站在攻擊者角度去編寫代碼磷醋。

其實記住兩點就行:

  1. 不要信任用戶輸入的任何數(shù)據(jù)

  2. 輸入、輸出過濾

作為防御方胡诗,我們盡量夠做的其實很有限邓线,不同的場景,可能有不同的漏洞產(chǎn)生煌恢,提高自身的安全意識骇陈,編寫安全代碼是我們目前能夠做的。

舉個小例子瑰抵,判斷一個URL是否是1688域名你雌,在前端提交的時候會做判斷,后臺也會做判斷二汛。
正則可能如下:
/http://.*.1688.com/i
大家可以思考一下這個正則有問題嗎? 前端可能寫對了婿崭,后臺開發(fā)人員呢拨拓?
在攻擊發(fā)生時,往往是多個類型XSS互相利用氓栈,最后產(chǎn)生較大的安全問題渣磷。還有就是新技術(shù)的應(yīng)用,比如NodeJs,在安全方面的處理還是不夠授瘦,這種在線上也存在相同的問題醋界。目前也有新的CSP策略,在高級瀏覽器(IE10,)中可以起到一定的安全防御作用奥务,但是就當前環(huán)境來說物独,低版本瀏覽器,我們還沒法放棄氯葬。
一些例子
2011年挡篓,新浪微博XSS蠕蟲事件:攻擊者利用廣場的一個反射性XSS URL,自動發(fā)送微博帚称、私信官研,私信內(nèi)容又帶有該XSS URL,導(dǎo)致病毒式傳播闯睹。
09年twitter也發(fā)生過類似事件戏羽。
烏云平臺也有很多此類例子,可以搜索關(guān)鍵詞XSS

  1. 安全平臺自己也有漏洞 ,rank 10,http://wooyun.org/bugs/wooyun-2010-059832
  2. 阿里云賬號泄露 楼吃,rank 20, http://wooyun.org/bugs/wooyun-2010-054102
  3. 騰訊微博 http://www.wooyun.org/bugs/wooyun-2010-020167
  4. 百度貼吧 http://www.wooyun.org/bugs/wooyun-2010-053221 太多了始花。。孩锡。酷宵。。躬窜。
    有時候浇垦,漏洞的危害性可能不是很大,但是極易引起用戶反彈荣挨,公關(guān)問題男韧,。

實踐 -- show me the code

前端XSS

前端XSS往往由于前端層面用innerHTML或者$('#id').html('...')方法時默垄,沒有對用戶輸入的內(nèi)容和正常的HTML代碼進行隔離此虑,從而讓黑客可以輕松獲取JS執(zhí)行權(quán)限。

那么厕倍,標準的前端邏輯應(yīng)該怎么寫寡壮?

$('#id').html('![](test.jpg)');

如果我們使用的是模板,例如handbar讹弯,由于handbar默認會進行轉(zhuǎn)義况既,因此默認即是安全的:


理論上,我們建議能使用模板的場景盡量使用模板组民,能為我們節(jié)省大量的代碼量棒仍,并且同時也能保證我們代碼不會出現(xiàn)XSS漏洞。
對于使用underscore的同學(xué)臭胜,請留意下默認的是不轉(zhuǎn)義的莫其,例如:
hello: <%= name %>
如果需要轉(zhuǎn)義,請務(wù)必使用:
hello: <%- name %>
注:我們對underscore進行了改造耸三,將這兩個標識進行了翻轉(zhuǎn)乱陡,經(jīng)過改造后,也符合了默認轉(zhuǎn)義的原則仪壮。

成果

在這之外憨颠,我們還有什么手段解決前端XSS問題呢?

jQuery目前已經(jīng)無孔不入积锅,幾乎找不著沒有使用jQuery的業(yè)務(wù)場景爽彤。

我們的方案是在外部對jQuery進行了hack,將所有html代碼進行安全過濾缚陷,以實現(xiàn)前端防火墻的功能适篙。

過濾邏輯如下:將所有js代碼過濾為無效代碼, 例如:

'''
<img src="" onerror="alert(1)"> <script>alert(1)</script>
'''

會替換為:

'''
<img src="" onerror0="alert(1)"> <script0>alert(1)</script>
'''

經(jīng)過此過濾,XSS就再也無法猖狂了箫爷!

并且嚷节,此方案還有1個優(yōu)點,由于此方案是全站底層進行防火部署虎锚,因此過濾算法可以隨時進行優(yōu)化升級硫痰,以解決今后出現(xiàn)新的XSS漏洞。

不過翁都,此方案并非沒有缺陷碍论。由于此方案屏蔽了所有的JS代碼,因此對于舊邏輯中所有HTML和JS混合的場景都需要進行改造柄慰。

但是鳍悠,根據(jù)實際部署過程來看,這種混合場景占比非常非常少坐搔。

我如何部署藏研?

security.js

'''js
(function (win) {
var security = {}; // 初始事件正則
var objOnEvents = {};
var reAllEvents; // init all events
var doc = document;
var arrDoms = [window, doc.createElement("form")];
try {
arrDoms.push(doc.createElement("img"));
arrDoms.push(doc.createElement("iframe"));
arrDoms.push(doc.createElement("object"));
arrDoms.push(doc.createElement("embed"));
arrDoms.push(doc.createElement("audio"));
} catch (e) {
}
var dom;
var key;
for (var i = 0, c = arrDoms.length; i < c; i++) {
dom = arrDoms[i];
for (key in dom) {
if (/^on/.test(key)) {
objOnEvents[key.substring(2)] = 1;
}
}
}
var arrAllEvents = [];
for (key in objOnEvents) {
arrAllEvents.push(key);
}
if (arrAllEvents.length > 0) {
reAllEvents = new RegExp('(['"\\s\\/]on(?:' + arrAllEvents.join('|') + '))\\s*=', 'ig'); } else { reAllEvents = /(['"\s/]on(\w+))\s=/ig;
} // HTML轉(zhuǎn)義
security.encodeHTML = function (str) {
return String(str).replace(/&/g, '&').replace(/"/g, '"').replace(/'/g, ''').replace(//g, '').replace(/</g, '<').replace(/>/g, '>');
}; // 過濾html中可能引發(fā)XSS的代碼
security.htmlFilter = function (str, args) {
var reBadTags = /<(script|link|frame)([^\w])/ig;
var reBadAttrs = /['"\s\/](srcdoc)\s*=/ig; var reBadSrc = /[\'"\s/]src\s
=\s['"]?\s(javascript:|data\s:\stext/html)/ig;
str = String(str); // 過濾script & link...
str = str.replace(reBadTags, '<$10$2'); // 過濾on事件
str = str.replace(reAllEvents, '$10='); // 過濾srcdoc屬性
str = str.replace(reBadAttrs, ' $10='); // 過濾危險src: javascript: data:
str = str.replace(reBadSrc, ' src0="');
return str;
}; // hack jQuery
security.hookJquery = function ($) {
if ($ && !$.fn.rawHtml) { // 1. html->rawHtml
$.fn.rawHtml = $.fn.html;
$.fn.html = function (value) {
var args = Array.prototype.slice.call(arguments);
if (typeof value === 'string' && $.htmlFilter) {
args[0] = security.htmlFilter(value, arguments);
}
return $.fn.rawHtml.apply(this, args);
};
}
};
win.security = security;
})(window);
'''

test.html

''' html
<div id="test"></div>
<script type="text/javascript" src="js/jquery-1.10.2.js"></script>
<script type="text/javascript" src="security.js"></script>
<script type="text/javascript">
security.hookJquery($); $.htmlFilter = true; $('#test').html('<img src="" onerror="alert(1)">')
</script>

框架底層可以直接將jQuery進行hook,但是具體過濾邏輯是否開啟取決于$.htmlFilter是否打開概行。

在部署過程中蠢挡,請務(wù)必要保證業(yè)務(wù)代碼全部改造為純HTML的情況下才能開啟開關(guān),否則會造成線上故障

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市业踏,隨后出現(xiàn)的幾起案子禽炬,更是在濱河造成了極大的恐慌,老刑警劉巖勤家,帶你破解...
    沈念sama閱讀 221,198評論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件腹尖,死亡現(xiàn)場離奇詭異,居然都是意外死亡伐脖,警方通過查閱死者的電腦和手機热幔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評論 3 398
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來讼庇,“玉大人绎巨,你說我怎么就攤上這事∪渥模” “怎么了场勤?”我有些...
    開封第一講書人閱讀 167,643評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長介汹。 經(jīng)常有香客問我却嗡,道長,這世上最難降的妖魔是什么嘹承? 我笑而不...
    開封第一講書人閱讀 59,495評論 1 296
  • 正文 為了忘掉前任窗价,我火速辦了婚禮,結(jié)果婚禮上叹卷,老公的妹妹穿的比我還像新娘撼港。我一直安慰自己,他們只是感情好骤竹,可當我...
    茶點故事閱讀 68,502評論 6 397
  • 文/花漫 我一把揭開白布帝牡。 她就那樣靜靜地躺著,像睡著了一般蒙揣。 火紅的嫁衣襯著肌膚如雪靶溜。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,156評論 1 308
  • 那天懒震,我揣著相機與錄音罩息,去河邊找鬼。 笑死个扰,一個胖子當著我的面吹牛瓷炮,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播递宅,決...
    沈念sama閱讀 40,743評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼娘香,長吁一口氣:“原來是場噩夢啊……” “哼苍狰!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起烘绽,我...
    開封第一講書人閱讀 39,659評論 0 276
  • 序言:老撾萬榮一對情侶失蹤淋昭,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后诀姚,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體响牛,經(jīng)...
    沈念sama閱讀 46,200評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡玷禽,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,282評論 3 340
  • 正文 我和宋清朗相戀三年赫段,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片矢赁。...
    茶點故事閱讀 40,424評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡糯笙,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出撩银,到底是詐尸還是另有隱情给涕,我是刑警寧澤,帶...
    沈念sama閱讀 36,107評論 5 349
  • 正文 年R本政府宣布额获,位于F島的核電站够庙,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏抄邀。R本人自食惡果不足惜耘眨,卻給世界環(huán)境...
    茶點故事閱讀 41,789評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望境肾。 院中可真熱鬧剔难,春花似錦、人聲如沸奥喻。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽环鲤。三九已至纯趋,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間冷离,已是汗流浹背吵冒。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留酒朵,地道東北人桦锄。 一個月前我還...
    沈念sama閱讀 48,798評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像蔫耽,于是被迫代替她去往敵國和親结耀。 傳聞我的和親對象是個殘疾皇子留夜,可洞房花燭夜當晚...
    茶點故事閱讀 45,435評論 2 359

推薦閱讀更多精彩內(nèi)容