Session Fixation
例子:假設(shè)A有一輛汽車,A把汽車賣給了B,但是A并沒有把所有的車鑰匙交給B,還自己藏下了一把。這時(shí)候如果B沒有給車換鎖的話,A仍然是可以用藏下的鑰匙使用汽車的。
這個(gè)沒有換“鎖”而導(dǎo)致的安全問題,就是SessionFixation問題。
在用戶登錄網(wǎng)站的過程中,如果登錄前后用戶的SessionID沒有發(fā)生變化,則會(huì)存在Session Fix-ation問題。
具體攻擊的過程是,用戶X(攻擊者)先獲取到一個(gè)未經(jīng)認(rèn)證的SessionID,然后將這個(gè)SessionID交給用戶Y去認(rèn)證,Y完成認(rèn)證后,服務(wù)器并未更新此SessionID的值,所以X可以直接憑借此SessionID登錄進(jìn)Y的賬戶。
X如何才能讓Y使用這個(gè)SessionID呢?如果SessionID保存在Cookie中,比較難做到這一點(diǎn)。但若是SessionID保存在URL中,則X只需要誘使Y打開這個(gè)URL即可。
解決Session Fixation的正確做法是,在登錄完成后,重寫SessionID。
如果使用sid則需要重置sid的值;如果使用Cookie,則需要增加或改變用于認(rèn)證的Cookie值。值得慶幸的是,在今天使用Cookie才是互聯(lián)網(wǎng)的主流,sid的方式漸漸被淘汰。
session保持攻擊
一般的應(yīng)用都會(huì)給session設(shè)置一個(gè)失效時(shí)間,當(dāng)?shù)竭_(dá)失效時(shí)間后,Session將被銷毀。但有一些系統(tǒng),出于用戶體驗(yàn)的考慮,只要這個(gè)用戶還“活著”,就不會(huì)讓這個(gè)用戶的Session失效。從而攻擊者可以通過不停地發(fā)起訪問請(qǐng)求,讓Session一直“活”下去。攻擊者就能通過此有效Session一直使用用戶的賬戶,成為一個(gè)永久的“后門”。
Cookie是可以完全由客戶端控制的,通過發(fā)送帶有自定義Cookie頭的HTTP包,也能實(shí)現(xiàn)同樣的效果。
在Web開發(fā)中,網(wǎng)站訪問量如果比較大,維護(hù)Session可能會(huì)給網(wǎng)站帶來巨大的負(fù)擔(dān)。因此,有一種做法,就是服務(wù)器端不維護(hù)Session,而把Ses-sion放在Cookie中加密保存。當(dāng)瀏覽器訪問網(wǎng)站時(shí),會(huì)自動(dòng)帶上Cookie,服務(wù)器端只需要解密Cookie即可得到當(dāng)前用戶的Session了。這樣的Session如何使其過期呢?很多應(yīng)用都是利用Cookie的Expire標(biāo)簽來控制Session的失效時(shí)間,這就給了攻擊者可乘之機(jī)。
Cookie的Expire時(shí)間是完全可以由客戶端控制的。篡改這個(gè)時(shí)間,并使之永久有效,就有可能獲得一個(gè)永久有效的Session,而服務(wù)器端是完全無法察覺的。
攻擊者甚至可以為Session Cookie增加一個(gè)Expire時(shí)間,使得原本瀏覽器關(guān)閉就會(huì)失效的Cookie持久化地保存在本地,變成一個(gè)第三方Cookie(third-party cookie)。
如何對(duì)抗這種Session保持攻擊呢?
常見的做法是在一定時(shí)間后,強(qiáng)制銷毀Session。這個(gè)時(shí)間可以是從用戶登錄的時(shí)間算起,設(shè)定一個(gè)閾值,比如3天后就強(qiáng)制Session過期。
但強(qiáng)制銷毀Session可能會(huì)影響到一些正常的用戶,還可以選擇的方法是當(dāng)用戶客戶端發(fā)生變化時(shí),要求用戶重新登錄。比如用戶的IP、UserA-gent等信息發(fā)生了變化,就可以強(qiáng)制銷毀當(dāng)前的Session,并要求用戶重新登錄。
單點(diǎn)登錄sso
單點(diǎn)登錄的英文全稱是Single SignOn,簡(jiǎn)稱SSO。它希望用戶只需要登錄一次,就可以訪問所有的系統(tǒng)。從用戶體驗(yàn)的角度看,SSO無疑讓用戶的使用更加的方便;從安全的角度看,SSO把風(fēng)險(xiǎn)集中在單點(diǎn)上,這樣做是有利有弊的。
SSO的優(yōu)點(diǎn)在于風(fēng)險(xiǎn)集中化,就只需要保護(hù)好這一個(gè)點(diǎn)。
SSO的缺點(diǎn)同樣也很明顯,因?yàn)轱L(fēng)險(xiǎn)集中了,所以單點(diǎn)一旦被攻破的話,后果會(huì)非常嚴(yán)重,影響的范圍將涉及所有使用單點(diǎn)登錄的系統(tǒng)。降低這種風(fēng)險(xiǎn)的辦法是在一些敏感的系統(tǒng)里,再單獨(dú)實(shí)現(xiàn)一些額外的認(rèn)證機(jī)制。
目前互聯(lián)網(wǎng)上最為開放和流行的單點(diǎn)登錄系統(tǒng)是OpenID。
流密碼是常用的一種加密算法,與分組加密算法不同,流密碼的加密是基于異或(XOR)操作進(jìn)行的,每次都只操作一個(gè)字節(jié)。但流密碼加密算法的性能非常好,因此也是非常受開發(fā)者歡迎的一種加密算法。常見的流密碼加密算法有RC4、ORYX、SEAL等。
?Reused Key Attack
在流密碼的使用中,最常見的錯(cuò)誤便是使用同一個(gè)密鑰進(jìn)行多次加/解密。這將使得破解流密碼變得非常簡(jiǎn)單。這種攻擊被稱為“Reused Key At-tack”,在這種攻擊下,攻擊者不需要知道密鑰,即可還原出明文。
在密碼學(xué)中,攻擊者在不知道明文的情況下,通過改變密文,使得明文按其需要的方式發(fā)生改變的攻擊方式,被稱為Bit-flipping Attack。
解決Bit-flipping攻擊的方法是驗(yàn)證密文的完整性,最常見的方法是增加帶有KEY的MAC(消息驗(yàn)證碼,MessageAuthentication Code),通過MAC驗(yàn)證密文是否被篡改。通過哈希算法來實(shí)現(xiàn)的MAC,稱為HMAC。HMAC由于其性能較好,而被廣泛使用。
在密碼學(xué)里有個(gè)基本的原則:密碼系統(tǒng)的安全性應(yīng)該依賴于密鑰的復(fù)雜性,而不應(yīng)該依賴于算法的保密性。
在安全領(lǐng)域里,選擇一個(gè)足夠安全的加密算法不是困難的事情,難的是密鑰管理。在一些實(shí)際的攻擊案例中,直接攻擊加密算法本身的案例很少,而因?yàn)槊荑€沒有妥善管理導(dǎo)致的安全事件卻很多。對(duì)于攻擊者來說,他們不需要正面破解加密算法,如果能夠通過一些方法獲得密鑰,則是件事半功倍的事情。
密鑰管理中最常見的錯(cuò)誤,就是將密鑰硬編碼在代碼里。將加密密鑰、簽名的salt等“key”硬編碼在代碼中,是非常不好的習(xí)慣。
硬編碼的密鑰,在以下幾種情況下可能被泄露。
一是代碼被廣泛傳播。這種泄露途徑常見于一些開源軟件;有的商業(yè)軟件并不開源,但編譯后的二進(jìn)制文件被用戶下載,也可能被逆向工程反編譯后,泄露硬編碼的密鑰。
二是軟件開發(fā)團(tuán)隊(duì)的成員都能查看代碼,從而獲知硬編碼的密鑰。開發(fā)團(tuán)隊(duì)的成員如果流動(dòng)性較大,則可能會(huì)由此泄露代碼。
對(duì)于第一種情況,如果一定要將密鑰硬編碼在代碼中,我們尚可通過Diffie-Hellman交換密鑰體系,生成公私鑰來完成密鑰的分發(fā);而對(duì)于第二種情況,則只能通過改善密鑰管理來保護(hù)密鑰。
對(duì)于Web應(yīng)用來說,常見的做法是將密鑰(包括密碼)保存在配置文件或者數(shù)據(jù)庫中,在使用時(shí)由程序讀出密鑰并加載進(jìn)內(nèi)存。密鑰所在的配置文件或數(shù)據(jù)庫需要嚴(yán)格的控制訪問權(quán)限,同時(shí)也要確保運(yùn)維或DBA中具有訪問權(quán)限的人越少越好。
在應(yīng)用發(fā)布到生產(chǎn)環(huán)境時(shí),需要重新生成新的密鑰或密碼,以免與測(cè)試環(huán)境中使用的密鑰相同。
當(dāng)黑客已經(jīng)入侵之后,密鑰管理系統(tǒng)也難以保證密鑰的安全性。比如攻擊者獲取了一個(gè)web-shell,那么攻擊者也就具備了應(yīng)用程序的一切權(quán)限。由于正常的應(yīng)用程序也需要使用密鑰,因此對(duì)密鑰的控制不可能限制住webshell的“正?!闭?qǐng)求。
密鑰管理的主要目的,還是為了防止密鑰從非正常的渠道泄露。定期更換密鑰也是一種有效的做法。一個(gè)比較安全的密鑰管理系統(tǒng),可以將所有的密鑰(包括一些敏感配置文件)都集中保存在一個(gè)服務(wù)器(集群)上,并通過WebService的方式提供獲取密鑰的API。每個(gè)Web應(yīng)用在需要使用密鑰時(shí),通過帶認(rèn)證信息的API請(qǐng)求密鑰管理系統(tǒng),動(dòng)態(tài)獲取密鑰。Web應(yīng)用不能把密鑰寫入本地文件中,只加載到內(nèi)存,這樣動(dòng)態(tài)獲取密鑰最大程度地保護(hù)了密鑰的私密性。密鑰集中管理,降低了系統(tǒng)對(duì)于密鑰的耦合性,也有利于定期更換密鑰。