PHP の cookie secure 属性で勘違いしてたはずかしい話。。。


お恥ずかしい話ですが、PHP の cookie secure 属性の取り扱いに関して、大きな勘違いをしていたため、なぜ勘違いしたかと念のため行った検証結果を自戒の意味も込めて記述しておきます。

勘違いした内容

php.ini にsession.cookie_secure = 1を設定すれば、session 用の cookie だけでなく、全cookie に secure 属性が付く!?と思ってました。

なぜ勘違いしたのか?

session.cookie_secure

session.cookie_secure specifies whether cookies should only be sent over secure connections. Defaults to off. This setting was added in PHP 4.0.4. See also session_get_cookie_params() and session_set_cookie_params().

google 翻訳

session.cookie_secureは、クッキーをセキュアな接続を介して送信するかどうかを指定します。 デフォルトではオフになっています。 この設定はPHP 4.0.4で追加されました。 session_get_cookie_params()およびsession_set_cookie_params()も参照してください。

前後ちゃんと読めよ。。。って感じですが、session 関連のみの記述になっていることを認識していませんでした。残念なことに、この文章を読んで、setcookie の $secure のデフォルト値が切り替わると飛躍した理解をしてしまった訳です。。。

検証

まず、通常の secure 属性付与の様子を確認。
cookie として保存された場合を ○、保存されなかった場合を ☓ とします。

設定 httpサイト httpsサイト
setcookie $secure = 0
setcookie $secure = 1

まぁ当然の結果です。

次にphp.ini に session.cookie_secure を設定した場合としなかった場合を確認しました。
cookie の発行は、setcookie('test','hogehoge', time()+36000)とし、setcookie の $secure のデフォルト値が切り替わるか確認。

設定 httpサイト httpsサイト
session.cookie_secure = 0
session.cookie_secure = 1

切り替わるわけ無いですよね^^;

結論

全 cookie の secure 属性付与は、
・ラップする関数を用意するして一括制御する
・web サーバで secure 属性を付与する
あたりで対応する必要があります。
php.ini では対応できません。。。

おまけ 1

今回、調査している時に、私と同じ勘違いをしているサイトをたくさん見かけました^^;WordPress のサイトを SSL 対応にするぜ!ってサイトが多かったので、大量の犠牲者が出ているものと推測されます。南無。。。

おまけ 2

実はもう一つ大きな勘違いをしていました^^;
cookie って secure 属性付けると、http でのアクセスに対しては、cookie を送信しないと思っていたのですが、secure 属性付きの cookie を発行するんですね^^;
発行はされるけど、ブラウザ側で保存しないっていう挙動となります。

マニュアルにもヒントが書いてあるんですが、さらっと読み飛ばしていました。

setcookie secure
クライアントからのセキュアな HTTPS 接続の場合にのみクッキーが送信されるようにします。 TRUE を設定すると、セキュアな接続が存在する場合にのみクッキーを設定します。 サーバー側では、このようにセキュアな接続の場合にのみクッキーを送信するという処理は プログラマの責任で行うことになります (たとえば $_SERVER["HTTPS"] の内容を使用します)。

これも勘違いを早めに気がつけて良かったです。
クッキー怖いw