【PHP】Cookieの検証 (保存出来る最大サイズを調べたり、圧縮した文字列をセットしてみたり)をしてみた – 2016年5月

投稿日:

クッキーはソフトなものよりハードな方が好きです。
というわけで、ちょっとだけCookieの検証をしてみたので書いてみます。
PHPです。

何の検証をしたのか

  • cookieにセットする値の長さが4096byte以上(値 >= 4096)だとcookieにセットされない(無視される)
    • もともとセットされていたcookieは上書きされない
  • cookieにセットする値の長さが4096byte以上(値 >= 4096)でも圧縮した結果、4096byteより小さい(値 < 4096)場合、cookieにセットされている
  • cookieのサイズ制限にはcookie名の長さも含まれる(セットする値の長さ + cookie名の長さが対象になる)

を検証しました。
※ 1クッキーの最大サイズ(byte)で一番小さい値が4096byteだったので4096byteを基準にしています (下記、検証にあたって参考にしたサイト参考)
※ cookieにセットする値の長さは、URLエンコード後の長さ(byte数)です

検証にあたって参考にしたサイト

検証してどうだったのか

こんなんでました。 ※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に保存出来なかった

ググったら以下のサイトなどが見つかって(上記でも書いていますが)、

こういう事らしかったんですね。

  • 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文字も許容するな

作成者: shimabox

Web系のプログラマをやっています。 なるべく楽しく生きていきたい。

2件のコメント

  1. 「フォームの項目入力で1000文字も許容するな」
    =>フォームの入力項目をクッキーに入れるのがおかしい。Wikipedia でもフォームに1000文字以上入力するのはザラにある。最後の最後でバカなことをいうな。

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください