クッキーはソフトなものよりハードな方が好きです。
というわけで、ちょっとだけCookieの検証をしてみたので書いてみます。
PHPです。
何の検証をしたのか
- cookieにセットする値の長さが4096byte以上(値 >= 4096)だとcookieにセットされない(無視される)
- もともとセットされていたcookieは上書きされない
- cookieにセットする値の長さが4096byte以上(値 >= 4096)でも圧縮した結果、4096byteより小さい(値 < 4096)場合、cookieにセットされている
- cookieのサイズ制限にはcookie名の長さも含まれる(セットする値の長さ + cookie名の長さが対象になる)
を検証しました。
※ 1クッキーの最大サイズ(byte)で一番小さい値が4096byteだったので4096byteを基準にしています (下記、検証にあたって参考にしたサイト参考)
※ cookieにセットする値の長さは、URLエンコード後の長さ(byte数)です
検証にあたって参考にしたサイト
- http://www.teria.com/~koseki/memo/cookie/cookie_4k.html
- http://fukaoi.org/2007/06/20/cookie
- http://d.hatena.ne.jp/hosikiti/20130925/1380098776
検証してどうだったのか
こんなんでました。 ※OperaとAndroidは(ry
OS | ブラウザ | 1クッキーの最大サイズ(byte) |
---|---|---|
MAC OS X El Captain | Chrome 50.0.2661.102 (64-bit) | 4096 |
Firefox 46.0.1 | 4097 | |
Safari 9.1 | 4097 | |
Windows7 Professional 32bit | Chrome 50.0.2661.94 m | 4096 |
Firefox 46.0.1 | 4097 | |
IE Edge (既定) | 5117 | |
IE 10 (エミュレーション) | 5117 | |
IE 9 (エミュレーション) | 5117 | |
iOS 9.3.1 | Safari | 4097 |
Chrome 50.0.2661.95 | 4097 ※PCと違う!! |
検証結果は(ほぼ((PCのchromeと、iOSのchromeで最大サイズに違いがあるのはビックリ!!)))期待する結果となりました。
4096byte以上の値をセットする時も、値を圧縮して4096byteより小さくなればセットされる事も確認出来ました。※chromeだけじゃなくて、他のブラウザもそれぞれの閾値で確認しました
どうやって検証したのか
こういうのを作って、ちまちまとやりました。
https://shimabox.net/sample/php_verify_cookie/
- 任意のcookieをセット出来る
- 文字列だけだけど
- デフォルトで4095, 4096, 4097, 5117, 5118byteの文字列を用意
- cookieにセットされている値とセットしたい値(postした値)に差分があれば、差分ありと表示される
- cookie削除の機能は無いので試した後は適当に消してください
- 試していると
Bad Request Your browser sent a request ...
が出たりします
- 試していると
ソースはやっつけで作ったので汚いですが一応
https://github.com/shimabox/sample_php_verify_cookie
何で検証をしたのか
まずこういう事があって、
- とあるフォームがあって、入力文字数を1000文字まで許容する項目があった
- その項目に入力された値は(セッション)cookieに保存して引きずり回す
- だが、1000文字maxまで入力したらcookieに保存出来なかった
ググったら以下のサイトなどが見つかって(上記でも書いていますが)、
- http://www.teria.com/~koseki/memo/cookie/cookie_4k.html
- http://fukaoi.org/2007/06/20/cookie
- http://d.hatena.ne.jp/hosikiti/20130925/1380098776
こういう事らしかったんですね。
- 1つのcookieで保存できる最大サイズは各ブラウザで決まっていて、最小サイズが4095byteらしい(chromeね)
- 不等号で表すと、
サイズ < 4096byte
- 不等号で表すと、
- cookieに保存する値は
- URLエンコードされる(そりゃそうだ)
- cookie名の長さもサイズに含まれる(これは知らなかった。。)
それで、そりゃあ1000文字(日本語含む)は保持できんわなぁ、、となったんだけど、文字列圧縮したらいけるんじゃね?って思いついたのでそれを試してみたのと、そもそもcookieの仕様というか、その辺よく調べたこと無いなぁ、だったら自分もちょっと調べてみようかなぁとなったわけです。(調べたのは最大サイズだけだけど)
でまぁ、調べた結果は上記にある通りです。
文字列圧縮はjson_encodeや、serializeした値をセットする時があれば使えるかもしれません。
(これは試していないし、そもそもそれ必要なの?と思うのでアレですが。。)
最大サイズにはcookieの値(URLエンコード後の長さ) + cookie名の長さも含まれる事も知らなかったし、PCとiOSのchromeで最大サイズが違うのも驚きでした。
調べて良かったです。
※調べ方が間違っていたら教えて下さい
まとめ
- クロスブラウザを意識するなら4095byteを限度と考える
- 1クッキーの話(ドメインあたりの最大サイズはまた別)
- 長い文字列をcookieにセットする時、圧縮すれば結構いける
- そもそもcookieではなくWeb Storageを使ってみる
- 今回のケースで言えば、Session Storage
- フォームの項目入力で1000文字も許容するな
「フォームの項目入力で1000文字も許容するな」
=>フォームの入力項目をクッキーに入れるのがおかしい。Wikipedia でもフォームに1000文字以上入力するのはザラにある。最後の最後でバカなことをいうな。