cookie - Lauviah0622/Lavi-Note GitHub Wiki
Cookie 限制大小: 最多只能帶
Set-Cookie
由 server 端發送 response 設定的 header,設定的 cookie 會在 client 端發送 request 自動放在 cookie
這個 header 帶上
使用格式:
<cookie-name>=<cookie-value>
cookie name 不能用下面的 character
( ) < > @ , ; : \ " / [ ] ? = { }.
cookie-value 中不能用以下 character:
- 空白
- 雙引號
"
- comma
,
- semicolon
;
- backslash
\
MDN 有提到欸,大部分的框架都會把 cookie value URL-encode 過,但其實沒有在 RFC 的 spec 上,雖然的確會符合要求沒錯。
多個 Set-Cookie
header 是可行的,但是每個 Set-Cookie
只能有一對 key value 值,但能夠有多個屬性
Set-Cookie: name=jojo; car=porche; Max-age=10
// car 會被忽略,只剩 name=jojo
Attribute
lifetime 類型
可以設定 cookie 等多久會被瀏覽器刪除,這並不只是沒辦法回傳 cookie 的值而已。而是整個 cookie 刪除,所以如果設定 Max-age=10
,即使想要在 client 把 cookie print 出來也沒辦法。
Expires
設定過期時間,格式為 UTCString
,可以用Date.toUTCString()
來設定
Max-Age
設定過多久過期, 數字為 s
,不是 ms
。如果是 <= 0
就把就馬上過期
如果沒有設定這兩個屬性,cookie 被視為 session cookie。有設定的話,則視為 Permanent Cookie
- session cookie 的表示在 session 關閉之後就會被清除,下次打開 cookie 就不見,除非又被 set-cookie。
- Permanent cookies 代表下次打開的時候 cookie 還是會被保留,並且在發出 request 的時候同時被送出
Session cookies are deleted when the current session ends. The browser defines when the "current session" ends, and some browsers use session restoring when restarting, which can cause session cookies to last indefinitely long.
from https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#define_the_lifetime_of_a_cookie
終於瞭解這段的意思了,session cookie 的過期部分,是由 browser 實作怎麼樣現在的 cookie 會過期。有些 browser 會在重啟的時候回復 session 儲存狀態,那原本應該被清除的 session cookie 又被回復了,就和沒有關閉瀏覽器過一樣
If your site authenticates users, it should regenerate and resend session cookies, even ones that already exist, whenever the user authenticates
from https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#define_the_lifetime_of_a_cookie
這段有點不確定,即使已登入的用戶利用之前儲存的 session-id 再次登入,這樣的情況下還是要再傳一個新的 session-id 給她,來避免 session fixation 攻擊
如果這兩個 attr 都被設定,那這 Max-age
優先
在 express 裡面,如果使用 res.cookie()
來設定
Access 類型:
Secure
:
- cookie 只能在 HTTPs 裡面傳輸,除了 localhost (?: 這裡要試看看)
- 避免中間人攻擊,加密之後就算拿到東西也看不懂,
不過這只能避免中間人攻擊,還是可以在 client 端的 server 存取
http 的 client 不能設定 secure,在 firefox 這個 cookie 會被忽略,方便開發者使用
HttpOnly
:
- 不能用
Document.cookie
這個 API 操作 cookie(?: 這個也試試看) - 為的是避免 XSS 的攻擊
我猜避免 XSS 的原因是,避免有人用 XSS 拿到 cookie 這樣,甚至是說對 cookie 做 sql injection,不過這個要 store base cookie 才有可能吧
where cookie sent
原本的 cookie 似乎只對 domain,而且要全部一樣才可以發,例如
cookie.com/a
X hot.cookie.com/a
X hot.cookie.com
O cookie.com/b
port 不太知道,protocol 的話應該是沒分別?除了掛 Secure 一定要 https (?: 查 cookie 的 origin policy)
在 devtool 還是可以把 HttpOnly 關掉,這樣你還是可以用 devtool 操作 API,可能會覺得這樣不是就不安全了嗎?但是本來這個東西就是防 third party 的 JS 的,並不是拿來防開發人員的。
cookie 發送相關類型
Domain
Path
Samesite
在未設定的情況下
Domain
(?: 查 cookie 的 origin policy)
如果沒有設定,預設就是只能在目前的 url 的 domain 下,不包含 subdomain。
如果設定了 Domain
,這個 domain 以下的都可以。換句話說可以讓限制更寬鬆。
例如
cookie.com/a
Domain=cookie.com
O hot.cookie.com/a
O hot.cookie.com
O cookie.com/b
就會兩個 subdomain 也可以用
- value 最開頭的點會被忽略,例如
.sample.com
就會變成sample.com
- 無法設定多個 domain
(?::那 subdomain 可以設定 parent domain 的 Domain
??)
?:: 有聽說 subdomain 可以覆蓋 domain 的 cookie,這是做得到的嗎?
如何做到 subdomain 覆蓋 parentDomain 的 cookie:
如果 domain 設定 /
subdomain 就可以存取 parent domain 的 cookie,然後可以用 documnent 修改或幹嘛幹嘛的
Path
限制只有哪個 path 底下的網頁才送 cookie
cookie.com/a
加上 Path=/a
X hot.cookie.com/a
X hot.cookie.com
O cookie.com/a
O cookie.com/a/b
X cookie.com/b
X cookie.com
Samesite
限制說在第三方 cookie 的狀況 (在 a.com 裡面,要發 request 給 b.com)下,要怎麼執行行為
-
SameSite=Strict
:只有 完全同樣的 site 才可以發出 cookie -
SameSite=Lax(default)
:
只有- 完全同樣的 site 網站
- 連到的網站和 request 的 domain 一樣的時候,才會發 cookie,因為如果 link 過來沒辦法登入的話很奇怪,我點到一個連結然後連到的 FB 是沒有登入的,尤其是在 search engine 的時候。
-
SameSite=None
:完全不管
例如:
我在一個購物網站買東西,然我要點 FB 登入,這時候設定 Lax 的話,在 redirect 時發送的 request,就會送出 cookie,這樣 FB 就可以拿到 cookie。但是如果是 strict,就沒辦法
沒有 samesite,會自動幫你設定 Default:Lax
要設定 None,同事要有 Secure,不然一樣是 Lax
目的:避免 CSRF attack
?: 這些屬性是一個 setCookie 套用一個 set-cookie,還是說一次套用整個 setCookie,因為 setCookie 可以設定多個不是嗎? ?: 這些 set-cookie 在 client 接收的時候會變成什麼樣的形式? cookie 在 server 端接收的時候又是什麼樣的形式 ?:為什麼設定 samesite token 就可以避免 CSRF attack,避免了在第三方送 cookie 為什麼可以避免 安全性問題?
cookie prefix
cookie 的這個方式沒辦法知道 cookie 是誰設定的: 不知道是當初 server 自己設定的,還是 client 有改過
如果有 domain attr 那 subdomain 就可以存取 parent domain 的 cookie
加在哪裡?
__Host-
As the application server checks for a specific cookie name only when determining if the user is authenticated or a CSRF token is correct, this effectively acts as a defense measure against session fixation.
這句不太懂?
Document.cookie
可以用這個 API 來讀取 & 設定 cookie
只能讀取沒有 HttpOnly
的 API
不能設定有 HttpOnly
的 API
安全性
要理解一件事情:cookie 完全有可能會被更改。
Depending on the application, it may be desirable to use an opaque identifier, which is looked up by the server or to investigate alternative authentication/confidentiality mechanisms such as JSON Web Tokens. 根據 APP,可能會需要設定不透明的辨識方式,例如從 server 查找資料,或者是說用 JWT 等的其他機制
cookie 上的對應機制:
httpOnly: 這很明顯,就是在 https 上面才可用 比較敏感的資料
- 短的 lifetime(
Expire
orMax-age
) - 設定 Samesite: Strict
?: 為什麼還是要用 cookie,如果是使用在 Auth 方面,總覺得在 client 端設定 localstorage 的儲存 JWT 還有檢查,還有設定說 server 端的 lifetime 應該就可以解決 auth 的需要了不是嗎
追蹤和隱私
第三方 cookie 是啥?
如果你的 domain 跟 你發出去的 request 的 domain 是一樣的 => 第一方 cookie
ex: 你在 cookie.com 要做登入,然後發出 request 給 cookie.com 這個 domain 做驗證
反之如果不一樣 就是第三方 cookie
ex 你在 cookie.com 做瀏覽,然後網頁發出 request 給 cake.com 做不知道幹嘛,這個就叫做第三方 cookie
一直忽略這點,以為說 cookie 只有拿 JS 什麼才會被設定,完全不是。任何的 request 收回來的 response 都會設定 cookie 例如 image 也會設定,然後最明顯就是廣告。
廣告追蹤怎麼用第三方 cookie 來追蹤你的行為的?
A third-party server can build up a profile of a user's browsing history and habits based on cookies sent to it by the same browser when accessing multiple sites.
這個是怎麼做到的?
第三方 cookie 會用在?
第三方 cookie 相關法律
- The General Data Privacy Regulation (GDPR) in the European Union
- The ePrivacy Directive in the EU
- The California Consumer Privacy Act
要做到以下行為
- 提醒用戶網站有用 cookie
- 允許用戶不接收全部 or 大部分 cookie
- 允許用戶不接受 cookie 但還是可以用網站的大部分功能
其他
Zombie Cookie
- server 不放 set-cookie 的 header,但是把資料存在 cookie 以外的地方
- client 端的網站透過 JS 建立 cookie ,
- 然後即使沒有 set-cookie 的 header,還是被建立 cookie了,而且你的資料也還是被送出去
這種 cookie 很難完全刪除,每次建就要每次刪,而且也不符合 RFC 的規範