今天webryan給team做了一個關于HTTP cookie的分享,從各個方面給大家介紹一下大家耳熟能詳的Cookie。主要是翻了維基百科的很多內容,因為維基百科的邏輯實在是很清晰:),ppt就不分享了,把原始的草稿貼出來給大家。歡迎批評指正。
HTTP Cookie:
Cookie通常也叫做網站cookie,瀏覽器cookie或者http cookie,是保存在用戶瀏覽器端的,并在發出http請求時會默認攜帶的一段文本片段。它可以用來做用戶認證,服務器校驗等通過文本數據可以處理的問題。
Cookie不是軟件,所以它不能被攜帶病毒,不能執行惡意腳本,不能在用戶主機上安裝惡意軟件。但它們可以被間諜軟件用來跟蹤用戶的瀏覽行為。所以近年來,已經有是歐洲和美國的一些律師以保護用戶隱私之名對cookie的種植宣戰了。更嚴重的是,黑客可以通過偷取Cookie獲取受害者的帳號控制權。
1.Cookie的歷史
a.概念的產生:
Cookie原名是”magic cookie”,是用來描述程序接受并原樣發出的一組數據。(這里可以拿生活中的情況舉例:比如說當我們在商場試穿衣服的時候,在試衣間門口店員會給你一個號碼牌表示你試穿衣服的件數。當你出來的時候,店員會檢查下拿著這個牌子和對應的衣服。)這個概念是一直就存在于計算機領域的.直到1994年,網景公司前雇員Lou Moutulli將magic cookie的概念引入到web,賦予了web記憶。
賣個關子。請大家設想一下,沒有cookie的互聯網將是一副什么的場景。
1.每次訪問都像第一次訪問一樣,無法判斷用戶是否訪問過
2.任何的購買等交互、驗證行為都必須在一次訪問中完成
3.無任何記憶,均需要用戶重新點擊或填寫
大家說的很好,在1994年6月的某天,24歲的,網景公司第九位工程師,moutulli,坐在鍵盤前,遇到和大家描述的一模一樣的困難,他憑借著他高超的編程技能和思想設計出了一個五頁紙的方案來解決這些棘手的問題,這個五頁紙后來也就演變成了最初版本的Netscape Cookie規范。五頁紙的核心觀點就是在用戶的電腦上存放一個小的文件來記錄用戶對網站的訪問情況。moutulli將其簡稱為cookie. 同年10月,Netscape瀏覽器就率先支持了Cookies,并在netscape官網上做了檢查統計用戶是否訪問過的功能。次年10月,微軟的IE2也開始支持Cookie。當然,微軟是要交“保護費”了,因為moutulli在1995年申請了專利,并在1998年獲得專利授權。整體來說,Cookie的引入對于互聯網來說,這是一個劃時代的轉折點,它將零散的訪問,無狀態的請求變得有序并富有記憶,給互聯網增添了更有趣味性的玩法。
b.隱私風險
1.1995年Q1,當時Cookie沒有受到廣泛的關注。但cookie不在用戶知曉的情況下可以默認種植引來人們的擔心。
2.1996年2月,金融時報(ft中文網就是翻譯此雜志)發布關于cookie的文章對公眾進行了認知的普及,并引起了媒體的廣泛關注和討論,尤其是在潛在的隱私風險上。
3.1996年-1997年,Cookie在美國聯邦貿易委員會聽證會持續討論。
c.規范的發展:
1.1994年,Montulli,聯合John Giannandrea寫了Netscape cookie規范。
2.1995年4月,在www-talk郵件組第一次開始討論正式統一的Cookie規范,并在IETF(Internet Engineering Task Force,互聯網工程任務組,主要目標是協調制定互聯網標準,幾乎所有重要的網絡底層協議都是有IETF制定,EG:TCP,IP,HTTP and so on,可以毫不夸張的說,沒有IETF就沒有今天的互聯網,今年是IETF成立25周年,老外有很多文章專門回顧總結其光輝成就。IETF是由網民自發組織,自我管理的,任何人都和可以參加的,完全民主平等的,無投票機制的,充分體現了自由、開放、合作、共享的精神)里成立了特別工作小組。兩種HTTP Cookie的方案被提議。
3.1996年2月,IETF認定第三方Cookie存在重大隱私風險。
4.1997年2月,IETF最終發布了Cookie規范,RFC 2109,其中指出不允許設置第三方cookie或者不能默認支持第三方cookie
5.2000年10月,RFC 2965發布,主要是由于廣告在RFC 2109發布時已經廣泛使用第三方Cookie,所以關于第三方cookie部分是沒有被Netscape和IE所跟隨。
6.2011年4月,RFC 6265發布。現實版使用的Cookie規范終于誕生了。
2.Cookie的類別
a.Session Cookie
這個類型的cookie只在會話期間內有效,即當關閉瀏覽器的時候,它會被瀏覽器刪除。設置session cookie的辦法是:在創建cookie不設置Expires即可。
b.Persistent Cookie
持久型cookie顧名思義就是會長期在用戶會話中生效。當你設置cookie的屬性Max-Age為1個月的話,那么在這個月里每個相關URL的http請求中都會帶有這個cookie。所以它可以記錄很多用戶初始化或自定義化的信息,比如什么時候第一次登錄及弱登錄態等。
c.Secure cookie
安全cookie是在https訪問下的cookie形態,以確保cookie在從客戶端傳遞到Server的過程中始終加密的。這樣做大大的降低的cookie內容直接暴露在黑客面前及被盜取的概率。
d.HttpOnly 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值會傳送到服務器。
e.3rd-party cookie
第一方cookie是cookie種植在瀏覽器地址欄的域名或子域名下的。第三方cookie則是種植在不同于瀏覽器地址欄的域名下。例如:用戶訪問a.com時,在ad.google.com設置了個cookie,在訪問b.com的時候,也在ad.google.com設置了一個cookie。這種場景經常出現在google adsense,阿里媽媽之類的廣告服務商。廣告商就可以采集用戶的一些習慣和訪問歷史。
f.Super Cookie
超級cookie是設置公共域名前綴上的cookie。通常a.b.com的cookie可以設置在a.b.com和b.com,而不允許設置在.com上,但是很不幸的是歷史上一些老版本的瀏覽器因為對新增后綴過濾不足導致過超級cookie的產生。
e.Zombie Cookie
僵尸cookie是指那些刪不掉的,刪掉會自動重建的cookie。僵尸cookie是依賴于其他的本地存儲方法,例如flash的share object,html5的local storages等,當用戶刪除cookie后,自動從其他本地存儲里讀取出cookie的備份,并重新種植。
3.Cookie用途
a.會話管理
1.記錄用戶的登錄狀態是cookie最常用的用途。通常web服務器會在用戶登錄成功后下發一個簽名來標記session的有效性,這樣免去了用戶多次認證和登錄網站。
2.記錄用戶的訪問狀態,例如導航啊,用戶的注冊流程啊。
b.個性化信息
1.Cookie也經常用來記憶用戶相關的信息,以方便用戶在使用和自己相關的站點服務。例如:ptlogin會記憶上一次登錄的用戶的QQ號碼,這樣在下次登錄的時候會默認填寫好這個QQ號碼。
2.Cookie也被用來記憶用戶自定義的一些功能。用戶在設置自定義特征的時候,僅僅是保存在用戶的瀏覽器中,在下一次訪問的時候服務器會根據用戶本地的cookie來表現用戶的設置。例如google將搜索設置(使用語言、每頁的條數,以及打開搜索結果的方式等等)保存在一個COOKIE里。
c.記錄用戶的行為
最典型的是公司的TCSS系統。它使用Cookie來記錄用戶的點擊流和某個產品或商業行為的操作率和流失率。當然功能可以通過IP或http header中的referrer實現,但是Cookie更精準一些。
4. Cookie的實現
Cookie是web server下發給瀏覽器的任意的一段文本,在后續的http 請求中,瀏覽器會將cookie帶回給Web Server。同時在瀏覽器允許腳本執行的情況下,Cookie是可以被JavaScript等腳本設置的。
a. 如何種植Cookie
http方式:以訪問http://www.webryan.net/index.php為例
Step1.客戶端發起http請求到Server
GET /index.php HTTP/1.1
Host: www.webryan.net
(這里是省去了User-Agent,Accept等字段)
Step2. 服務器返回http response,其中可以包含Cookie設置
HTTP/1.1 200 OK
Content-type: text/html
Set-Cookie: name=value
Set-Cookie: name2=value2; Expires=Wed, 09 Jun 2021 10:18:14 GMT
(content of page)
Step3. 后續訪問webryan.net的相關頁面
GET /spec.html HTTP/1.1
Host: www.webryan.net
Cookie: name=value; name2=value2
Accept: */*
需要修改cookie的值的話,只需要Set-Cookie: name=newvalue即可,瀏覽器會用新的值將舊的替換掉。
腳本方式種植 Cookie:
JavaScript或類似的寄宿在瀏覽器中的腳本語言也可以設置Cookie。在JavaScript里,可以通過document.cookie對象實現。例如:
document.cookie = “key=newvalue”;
b. Cookie屬性
除了name=value對以外,我們還可以設置Cookie其他屬性以支持更豐富的Cookie需求,這些屬性通常是瀏覽器用來判斷如何對待cookie,何時刪除、屏蔽或者如何發送name-value對給Server。也就是說無論我們設置了某個cookie的多少屬性,這些Cookie屬性是不會被瀏覽器發送回給Server的。
a) Domain and Path
作用:定義Cookie的生效作用域,只有當域名和路徑同時滿足的時候,瀏覽器才會將Cookie發送給Server。如果沒有設置Domain和Path的話,他們會被默認為當前請求頁面對應值。 舉例如下:
提問下:第一個和第三個Cookie有啥不一樣??
結論:瀏覽器優先匹配domain,而對于Path字段則是以匹配的方式進行判斷。
對于 1.http://docs.foo.com/accounts/index.html
2.http://docs.foo.com/accountstest.html
1.會帶上Cookie1,2,3; 2會帶上1,2
b) Expires and Max-Age
作用:設置瀏覽器何時刪除Cookie
Expires的規定格式是:“Wdy, DD-Mon-YYYY HH:MM:SS GMT”。
相對于Expires的精準的時間設置,在RFC 2965中規范提供了一個替代方案:Max-Age:seconds,來設置cookie在設置后多長秒后失效。
Set-Cookie: lu=Rg3vHJZnehYLjVg7qi3bZjzg; expires=Tue, 15-Jan-2013 21:47:38 GMT; path=/; domain=.foo.com; httponly
Set-Cookie: made_write_conn=1295214458; path=/; domain=.foo.com
Set-Cookie: reg_fb_gate=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; path=/; domain=.foo.com; httponly
第一個Cookie: 過期時間是2013年1月15日的精確時間;
第二個:沒有設置過期時間,為Session cookie.
第三個:刪除Cookie
C) Secure and HttpOnly
作用:設置Cookie的安全屬性
特質:Secure和HttpOnly都是沒有value字段的。
Secure字段告訴瀏覽器在https通道時,對Cookie進行安全加密,這樣即時有黑客監聽也無法獲取cookie內容。
HttpOnly字段告訴瀏覽器,只有在HTTP協議下使用,對瀏覽器的腳本不可見,所以跨站腳本攻擊時也不會被竊取。 從前面例子可以看到Google和Facebook都在使用HttpOnly的Cookie。
5. 瀏覽器相關
a) Cookie規范規定瀏覽器最少支持300個cookie,每個cookie 4kb;每個域名最少20個cookie。
b) 瀏覽器都支持刪除和禁用cookie
c) 在瀏覽器地址欄輸入:javascript:alert(document.cookie)可以看到所有cookie
d) 默認情況下,IE瀏覽器僅支持設置有P3P “CP” (Compact Policy) 標記的第三方Cookie.
測試方法:
javascript:for(var i=0;i<100;i++){document.cookie=’cookiename’+i+’=1aaa;’}document.cookie=’test=asdf;';alert(document.cookie)
測試結論:ie8:每個域名50個,firefox:每個域名150個;chrome:每個域名170個;ie6、ie7:20個
測試方法:
javascript:var arr=[],i=5112;while(i){i–;arr.push(‘i’)}document.cookie=’test=’+arr.join(”)+';';alert($.cookie.get(‘test’).length)
測試結論:
ie8:5112+5 = 5117
但最多10個大字段。字段內容多了的話,導致服務器無法響應。
6.Cookie竊取及會話劫持(hijacking)
相對很多Session驗證方法的缺點和不足,大多數網站都是把Cookie當作用戶的唯一標識。在這種情況下,黑客以可以通過竊取用戶的cookie來模擬用戶的請求行為,但對于服務器來說是無法辨別到底是來自用戶還是黑客的。
下面給出Cookie作為用戶標識的風險和安全隱患:
a. 網絡監聽
在網絡上傳輸的數據都是會被監聽獲取的,尤其是在公共的、非加密的網絡環境(free wifi)。這些數據也包括常規的http(非https加密通道)所有session,當然也就包括了HTTP 會話里的Cookie。當黑客拿到明文的cookie之后就可以模擬用戶操作,比如改密碼、消費等行為。
解決這個問題的最根本方法是采取https協議,通過SSL通道對內容及cookie進行加密。此外還有一些二次保護的方法可以作為過渡和折中。
b. DNS cache異常及其他
通過DNS cache或者DNS服務商的一些漏洞問題(www.baidu.com),黑客可以通過將www.baidu.com的子域名hack.www.baidu.com指向到黑客自己的IP。這樣黑客就可以通過方式http://hack.www.baidu.com/a.png圖片到公共環境,從而可以獲取到baidu.com下的所有cookie,包括設置了HttpOnly屬性的Cookie。
解決辦法:1.減少dns無效配置 2.ISP服務商加強自我安全管理。3.通過HTTPS請求對請求進行加密和授權,這樣黑客很難從憑證管理中心獲得認證,那么用戶在操作的時候會收到明顯的提示。
c. 跨站腳本XSS—竊取Cookie
由于JavaScript等腳本語言可以讀取頁面文檔內的Cookie值,同時又可以向任意服務器發出任意的請求。綜合起來,黑客可以通過腳本將當前文檔下的cookie據為己有。如果黑客使用的地址是https://attacker.com/stole.cgi,那么Secure Cookie也將以明文的方式發送個attacker.com.
跨站腳本是web安全永久不變的話題。Web開發者有責任去過濾掉惡意代碼。同時,HttpOnly Cookies不可以被客戶端腳本讀取,這就大大降低了Cookie被盜取的風險。
d. 跨站腳本XSS—hijacking
當黑客可以在www.test.com上插入一段JS腳本的話,那么沒有禁用JS的用戶很輕易的會收到hijacking攻擊。黑客利用用戶的瀏覽器來發出HTTP請求到test.com本身,所以與用戶相關的所有cookie都會存在(包括HttpOnly和Secure Cookie)。例如:人人網發生的分享蠕蟲。
對于這種攻擊,除了避免跨站腳本漏洞以外,可以采取驗證碼的方式進行一定程度上的規避。
e. 跨站腳本XSS—代理請求
老版本的瀏覽器允許用戶使用XMLHttpRequest發出代理請求,黑客可以通過設置代理將本地的cookie全量的發給代理服務器,再從代理服務器轉發給原始服務器。當然這是很快被禁止了。
f. 跨站請求偽造—CSRF
CSRF主要是黑客將偽造的請求URL放到一個圖片或者其他靜態資源里,這種成本極低,且傳播性和形象力非常大。
舉例:Qzone的簽名的修改地址是:http://qzone.qq.com/cgi-bin/modify?nick=123
那么黑客將其并放到流量很大的論壇或者博客里。那么很多人就在不知情的情況下就執行了某些操作。
7. Cookie的缺點和不足
a) 被討論最多的就是隱私問題
b) Cookie引入的各種安全問題
c) 與REST軟件架構相背離。
d) 狀態不一致,后退導致cookie不會重置。
c) 過多使用到是HTTP請求流量浪費
8.Cookie的取代方案
a) window.name
當前所有瀏覽器都能通過DOM結構中的window.name存儲2-32MB的數據。同時window.name是跨域名,但是只能是在當前tab里使用,每個tab初始化后都是有個空的window.name。Window.name是可以傳遞對象的,所以我們通過將數據保存在json里進行傳遞和存儲。
由于window.name不通過網絡傳送,所以不會存在被竊取的風險。同時所以從某種角度通過window.name進行用戶行為分析更為合理,同時又不會像cookie一樣引來http流量消耗
b.)Internet Explorer userData storage (starting IE9, userData is no longer supported)
支持:IE5-IE8
使用:
或者,通過腳本來設置:
object.style.behavior = “url(‘#default#userData’)”
object.addBehavior (“#default#userData”)
數據:
在XP下,一般位于C:\Documents and Settings\用戶名\UserData,有些時候會在C:\Documents and Settings\用戶名\Application Data\Microsoft\Internet Explorer\UserData。
在Vista下,位于C:\Users\用戶名\AppData\Roaming\Microsoft\Internet Explorer\UserData
屬性:expires 設置或者獲取 userData behavior 保存數據的失效日期,不設置則為永久。
var store = document.documentElement;
store.addBehavior(‘#default#userdata’);
var STORE_NAME = ‘my_userdata’;
store.save(STORE_NAME);
store.setAttribute(‘a’, 123);
store.save(STORE_NAME);
store.load(STORE_NAME);
store.getAttribute(‘a’);
store.removeAttribute(‘a’);
store.save(STORE_NAME);
c)HTML5特性
? HTML5 Session Storage
? HTML5 Local Storage
? HTML5 Global Storage
? HTML5 Database Storage via SQLite
? Storing cookies in RGB values of auto-generated, force-cached PNGs using HTML5 Canvas tag to read pixels (cookies) back out
? Local Shared Objects (Flash Cookies)
? Silverlight Isolated Storage
d)Flash Shared Object
存在Flash的用戶目錄
依賴于flash的安裝
使用數據量大100k,超過的需要用戶允許
簡單操作
var so:SharedObject = SharedObject.getLocal(key);
so.data.value = value;//return so.data.value
其他相關
RFC2109:
1.聲明新增了Set-Cookie和Cookie兩個HTTP頭
2.延續使用HTTP/1.1的attribute-value對
3.Server可以在任意HTTP Header中設置cookie
4.Server可以設置多個Set-Cookie頭
嚴格之處:
1.User Agent設置domain必須滿足以.開頭,且y.x.qq.com不能設置到.qq.com上
2.User Agent給服務器的是完整的Cookie
3.Netscape支持 Expires,協議支持max-age:
域名限制:
1.rfc要求
* at least 300 cookies
* at least 4096 bytes per cookie (as measured by the characters
that comprise the cookie non-terminal in the syntax description
of the Set-Cookie2 header, and as received in the Set-Cookie2
header)
* at least 20 cookies per unique host or domain name
轉載 : http://www.webryan.net/2011/08/wiki-of-http-cookie/