Cookie(複數形態Cookies),中文名稱爲小型文本文件或小甜餅,指某些網站爲了辨別用戶身份而儲存在用戶本地終端(Client Side)上的數據(一般通過加密)。定義於RFC2109。是網景公司的前僱員Lou Montulli在1993年3月的發明。javascript
概念:Cookie是web server下發給瀏覽器的任意的一段文本。在後續的http 請求中,瀏覽器會將cookie帶回給Web Server。html
由於HTTP協議是無狀態的,即服務器不知道用戶上一次作了什麼,這嚴重阻礙了交互式Web應用程序的實現。java
在典型的網上購物場景中,用戶瀏覽了幾個頁面,買了一盒餅乾和兩瓶飲料。最後結賬時,因爲HTTP的無狀態性,不經過額外的手段,服務器並不知道用戶到底買了什麼。 因此Cookie就是用來繞開HTTP的無狀態性的「額外手段」之一。服務器能夠設置或讀取Cookies中包含信息,藉此維護用戶跟服務器會話中的狀態。web
在剛纔的購物場景中,當用戶選購了第一項商品,服務器在向用戶發送網頁的同時,還發送了一段Cookie,記錄着那項商品的信息。當用戶訪問另外一個頁面,瀏覽器會把Cookie發送給服務器,因而服務器知道他以前選購了什麼。用戶繼續選購飲料,服務器就在原來那段Cookie裏追加新的商品信息。結賬時,服務器讀取發送來的Cookie就好了。瀏覽器
每次訪問都像第一次訪問同樣,沒法判斷用戶是否訪問過安全
任何的購買等交互、驗證行爲都必須在一次訪問中完成服務器
無任何記憶,均須要用戶從新點擊或填寫cookie
這個應該很好理解,一個是存在內存,一個存在硬盤。區別就在於Cookie的有效時間。session
內存Cookie:由瀏覽器維護,保存在內存中,瀏覽器關閉後就消失了,其存在時間是短暫的。app
硬盤Cookie:保存在硬盤裏,有一個過時時間,除非用戶手工清理或到了過時時間,硬盤Cookie不會被刪除,其存在時間是長期的。
登陸一個網站時,網站每每會請求用戶輸入用戶名和密碼,而且用戶能夠勾選「下次自動登陸」。若是勾選了,那麼下次訪問同一網站時,用戶會發現沒輸入用戶名和密碼就已經登陸了。這正是由於前一次登陸時,服務器發送了包含登陸憑據(用戶名加密碼的某種加密形式)的Cookie到用戶的硬盤上。第二次登陸時,(若是該Cookie還沒有到期)瀏覽器會發送該Cookie,服務器驗證憑據,因而沒必要輸入用戶名和密碼就讓用戶登陸了。
這個類型的cookie只在會話期間內有效,即當關閉瀏覽器的時候,它會被瀏覽器刪除。設置session cookie的辦法是:在建立cookie不設置Expires便可。
持久型cookie顧名思義就是會長期在用戶會話中生效。當你設置cookie的屬性Max-Age爲1個月的話,那麼在這個月裏每一個相關URL的http請求中都會帶有這個cookie。因此它能夠記錄不少用戶初始化或自定義化的信息,好比何時第一次登陸及弱登陸態等。
安全cookie是在https訪問下的cookie形態,以確保cookie在從客戶端傳遞到Server的過程當中始終加密的。這樣作大大的下降的cookie內容直接暴露在黑客面前及被盜取的機率。
目前主流的瀏覽器已經都支持了httponly cookie。1.IE5+ 2.Firefox 1.0+ 3.Opera 8.0+ 4.Safari/Chrome。在支持httponly的瀏覽器上,設置成httponly的cookie只能在http(https)請求上傳遞。也就是說httponly cookie對客戶端腳本語言(javascript)無效,從而避免了跨站攻擊時JS偷取cookie的狀況。當你使用javascript在設置一樣名字的cookie時,只有原來的httponly值會傳送到服務器。
第一方cookie是cookie種植在瀏覽器地址欄的域名或子域名下的。第三方cookie則是種植在不一樣於瀏覽器地址欄的域名下。例如:用戶訪問a.com時,在ad.google.com設置了個cookie,在訪問b.com的時候,也在ad.google.com設置了一個cookie。這種場景常常出如今google adsense,阿里媽媽之類的廣告服務商。廣告商就能夠採集用戶的一些習慣和訪問歷史。
超級cookie是設置公共域名前綴上的cookie。一般a.b.com的cookie能夠設置在a.b.com和b.com,而不容許設置在.com上,可是很不幸的是歷史上一些老版本的瀏覽器由於對新增後綴過濾不足致使過超級cookie的產生。
以訪問本站(www.kryptosx.info)爲例。
這裏使用Fiddler來進行HTTP抓包,用來分析交互時的Cookie是如何傳遞的。
使用瀏覽器打開www.kryptosx.info,這是一個GET請求。
能夠看出,第一次請求中,並無Cookies的信息,可是返回包中,有Set-Code頭,後面跟着的就是Cookies信息。
從圖中能夠看出,三個都是刪除Cookie的—「=deleted」。Cookies是httponly的。另外,expires設置爲1970年,這個cookie就成了所謂的session-cookie。由於瀏覽器會自動清理掉過時的Cookies。
此次依然是GET請求,可是帶上了Cookie。
GET / HTTP/1.1 Accept: text/html, application/xhtml+xml, */* Accept-Language: zh-Hans-CN,zh-Hans;q=0.8,en-US;q=0.5,en;q=0.3 User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko Accept-Encoding: gzip, deflate Host: www.kryptosx.info DNT: 1 Connection: Keep-Alive Cookie: CNZZDATA1254085044=1980544601-1431063029-%7C1431063029
固然,返回包也帶了Cookie。
從抓包中,能夠看出HTTP交互時傳遞Cookies的方式。固然,我這裏這個Cookie估計是訪問統計的。
Cookies是一個瀏覽器和服務器交互的,並不是依賴於單個網頁。瀏覽器是對經過域來區分的。經過信息的附帶咱們也能夠看得出,它和Post仍是GET並沒有關係。
Cookies能夠被看做是一個憑據,天然會被駭客窺視。只要竊取了它,攻擊者就能冒充你的身份了。
可能某天,你收到一封郵件,它告訴你,你的XXX網帳號有風險,請馬上修改。裏面還有個連接,你發現連接沒錯,確實是XXX網的域名。你可能沒注意,直接點開了。以後,你就發現你的XXX系統中的密碼被改掉了。
這就是一個CSRF攻擊,攻擊者精心設計了一個網址。這個網址就附帶了更改密碼的GET請求。另外你的瀏覽器本地保存着XXX網的Cookies,因此操做是合法的。
CSRF還有別的手段,好比在某個網頁裏嵌入圖片等,這類更爲隱蔽。
CSRF看上去很可怕,但仍是能解決的。固然這種東西不能靠用戶,仍是要網站開發者來搞定。
CSRF利用的是Cookies的特色,由於Cookies是瀏覽器級別的一個信息,同一個瀏覽器登陸相同的網站的不一樣網頁都能訪問相同的Cookies。所以攻擊者的請求對於瀏覽器來講是合法的,服務端沒有作CSRF保護,也認爲這個請求是合法,這樣就被攻擊了。
前面說了,Cookies是一個憑證,可是Cookies是瀏覽器級別的,同個瀏覽器都能用這個憑證,所以黑客也能利用。那咱們能不能弄一個憑證,讓黑客無法利用,不就解決了,接着這個例子,合法的修改密碼操做是會先打開修改密碼頁面,輸完要修改的密碼,而後點擊提交。而黑客是直接提交請求的,並無打開修改密碼頁面這一步。
因此,目前防CSRF攻擊的方法,大多都是在網頁中加入一個Token,即把一個憑證放到頁面裏,這是頁面級別的,黑客無法利用這個憑證,CSRF攻擊也就難以進行了。
也有使用驗證碼的,這個固然更安全,此外,還有防暴力破解的能力,可是用戶體驗不大好。因此通常放在重要操做中,好比改密碼這類:P。
另外,有人說用了Post就安全,Post相對GET而言確實要好點,畢竟僞造Post難度大點。可是千萬別認爲就能躲開CSRF了。JS腳本是能模擬Post請求的。因此該加Token仍是加Token吧。
參考資料:http://www.webryan.net/2011/08/wiki-of-http-cookie/