http https 混在サイトでの Cookie Secure 属性の扱い方
問題提起
https 通信環境下で Cookie に Secure 属性つけていますか?
Secure 属性とは?
http と https と各通信で相互の行き来がある場合などに
https の通信でのみ使うべき Cookie の値が
http の通信に流出するおそれがあります。
それを防ぐ為に Cookie に secure 属性を付けて
https 通信でのみ扱えるようにするという対策があります。
実例
PHP の場合を扱おうと思ったので
お世話になってる メルカリさんを参照します。
Chrome の Developer Tool で Secure 項目 確認すると
チェックがついているのがわかります。
PHPSESSID は php.ini の session.name で設定されている
session_id の名前です。
1 | $ php -i | grep php.ini |
常時 https 通信だったら
- secure 属性を常に設定するようにします。
session_id 発行例
session_set_cookie_params 関数を用いて設定
1 | $secure = true; |
- HttpOnly を true とすると クライアントサイド Javascript からの Cookie 取得不可となり XSS 対策の一環となります。
1 | $secure = true; |
http https 混在していたら
この場合に遭遇しました。
よくショッピングサイトなどでは以下 http https が混在するケースが
見受けられます。
- 商品一覧ページ …. http
- 決済情報入力ページ … https
こういった場合の Cookie Secure 属性の扱い方を検討してみました。
対策 1
- http 用 (PHPSESSID):secure 属性なし と https 用 (例: SPHPSESSID): secure 属性あり で 2 つ cookie を発行する
対策 2
- PHPSESSID は http https 共通の secure 属性なし cookie を発行する
- https 通信時に secure 属性付き token を発行し発行した token をチェック。
不整合が起きた場合は、session_id を書き換え、session の内容を破棄する。
上記 対策 1 では http,https 用の session_id の紐付けの管理がしにくい為
対策 2 について実装しました。
対策 2 実装例
- session_id が発行されていない場合(初回アクセス時)、secure 属性なしの session_id (PHPSESSID) 発行
- https 通信時は session に token がない場合、secure 属性付き token cookie を発行。 session にも token を保存
- session と cookie にある token 情報を突き合わせて一致しない場合、 session_id を変更し session 内部を破棄
あえてわかりやすく冗長な書き方してます。
domain, path, secure 等は 環境ごとに define するなりしてください。
1 | $domain = 'www.example.jp'; |
これで http で発行される session_id は secure 属性がなくとも
https 通信下での情報流出防止策をとりました。
以上です。
http https 混在サイトでの Cookie Secure 属性の扱い方
https://kenzo0107.github.io/2016/08/09/2016-08-10-http-https-mixed/