每一次訪問都會在瀏覽器生成Cookie
,那麼Cookie
的存在對於用戶來講是好仍是壞呢?說實話,這玩意的存在確實會帶來一系列的問題,有趣的是幾乎每一個站點都難以離開Cookie
,因爲Cookie
的使用因其貌似簡單,而很容易被人輕視。最近在開發過程當中,審視應用中的Cookie
代碼,幾乎只須要很小的代價就能夠得到巨大的安全收益。所以寫下這份筆記加深記憶。nginx
在實際的應用場景中,Cookie
被用來作得最多的一件事是保持身份認證的服務端狀態。這種保持多是基於會話Session
的,也有多是持久性的。然而無論哪種,身份認證Cookie
中包含的服務端票據Ticket
一旦泄露,那麼服務端將很難區分帶有此票據的用戶請求是來自於真實的用戶,或者是來自惡意的***者。web
在實際案例中,形成Cookie
泄露最多的途徑,是經過跨站腳本(如 XSS, Cross Site Script)漏洞。者能夠經過一小段JavaScript
代碼,偷竊到表明用戶身份的重要的Cookie
標識。因爲跨站腳本漏洞是如此的廣泛(不要覺得簡單的HTML Encode
就能夠避免被跨站,跨站是一門很深的學問,以致於在業界衍生出一個專用的名詞:跨站師),幾乎每個網站都沒法避免,因此這種方式是實際中被廣泛使用的一種手段。瀏覽器
事實上避免出現這種問題的首要祕訣就是盡全部的可能,給你的Cookie
加上HttpOnly
的標籤。HttpOnly
的具體使用不在本文的討論範圍內。安全
第一次訪問網站的時候,瀏覽器發出請求,服務器響應請求後,會將Cookie
放入到響應請求中,在瀏覽器第二次發請求的時候,會把Cookie
帶過去,服務端會辨別用戶身份,固然服務器也能夠修改Cookie
內容.服務器
建立Cookie
的時候,會給Cookie
指定一個值:Expire
,它就是指定Cookie
的有效期,也就是Cookie
的生命週期,超出設置的這個生命週期,Cookie
就會被清除。若是給這個值Expire
設置爲0
或者負值,那麼這樣的設置就是在關閉瀏覽器時,就會清除Cookie
,這種方式更加安全。cookie
一般狀況下,咱們的web
應用服務都會經過nginx
進行發佈,這個時候,咱們能夠經過在nginx
上面進行配置文件的修改來改變cookie
的有效期,因爲筆者最近在基於openresty
對nginx
進行功能開發。正好趁此機會展開對Cookie
有效期的狀態測試.session
上文在Cookie
的生命週期中提到爲了有效期的安全性,咱們能夠爲Cookie
設置合理的有效期。如爲0
或者負值,那麼其效果是怎樣的呢?不妨看一下dom
利用Openresty
的resty.cookie
進行修改。該庫是用來對OpenResty
的HTTP cookie
操做。能夠用來爲Nginx
解析HTTP Cookie header
,並返回Cookie
中的每一個字段。好比設置name
,value
,httponly
等屬性ide
這裏將expires
設置爲有效期是一天(24h)
即當前系統時間(ngx.time())
加24hpost
local cookie = resty_cookie:new() local ok, err = cookie:set({ key = "middle_session", value = session, path = "/", secure = false, httponly = true, expires = ngx.cookie_time(ngx.time() + 60 * 60 * 24), domain = ngx.host, })
效果
在這裏能夠看到咱們cookie
的有效時間爲5月13號的14點04分,說明咱們的修改配置是有效的,能夠經過該參數進行Cookie
修改,只要到達這個時間點,該Cookie
便會失效,此時用戶須要從新登陸。
這裏將expires
設置爲有效期是-1,這裏能夠觀察到cookie使用的時間的是1970年,也就是UNIX紀元的元時間
local cookie = resty_cookie:new() local ok, err = cookie:set({ key = "middle_session", value = session, path = "/", secure = false, httponly = true, expires = ngx.cookie_time(-1), domain = ngx.host, })
從下圖中能夠看到Cookie
有效期是1970年1月1號,這個時間點毫無懸念的已通過時了,固然了,在生產環境中這麼配置。是要被關進小黑屋探討人生價值的,用戶遇到這樣的Cookie
配置是不管如何都沒法登錄成功的
由於ngx.cookie_time
會返回一個格式化的字符串,能夠用做Cookie
過時時間,咱們本身手動指定過時時間。經過這個方法能夠測試上文說到的Cookie
自動清除的效果
local cookie = resty_cookie:new() local ok, err = cookie:set({ key = "middle_session", value = session, path = "/", secure = false, httponly = true, expires = -1, domain = ngx.host, })
local cookie = resty_cookie:new() local ok, err = cookie:set({ key = "middle_session", value = session, path = "/", secure = false, httponly = true, expires = 0, domain = ngx.host, })
這裏配置-1
,0
在現實意義上跟配置元時間是同樣的,不過好處在於,不用關小黑屋啦。Cookie
只在當前頁面上有效,一旦關閉瀏覽器,這個Cookie
就會被瀏覽器清除,此時不用再考慮安全性問題。
參考文檔:
- Cookie 安全漫談 https://www.infoq.cn/article/cookie-security
- 把cookie聊清楚 http://www.javashuo.com/article/p-raxrpqhx-gk.html
- 淺談cookie安全 https://zhuanlan.zhihu.com/p/58666986