PHP:Cookieを削除すると値をdeletedに設定

PHPで作られたアプリケーションで、クッキーから情報を取得している箇所があり、そこではあり得ないハズの”deleted“という値が設定されていた。
調べてみると、Cookie削除時のPHPの仕様によるものだった。

アプリ側では、よくあるように次のようにしてCookie を削除していた。

setcookie ( KEY, "", time()-3600, "/" );

このクッキーを削除する際、PHPでは、内部的には値を deleted に設定し、有効期限を365日+1 秒前に設定する

再現手順

クッキーの用途的に、以下のような手順を踏むと “deleted” な値を取得できる。

  1. ログイン
  2. 別タブでログイン後のページを開く
  3. クライアントPCの時刻を1年以上昔に設定
  4. 片方のタブでログアウトを実行
  5. クッキーの値が “deleted” に設定される
  6. ログアウトしていないタブで、ログイン後の画面に遷移

—–

実装の確認
ext/standard/head.c の setCookie 関数の実装から

if (value && value_len == 0) {
  /*
  * MSIE doesn't delete a cookie when you set it to a null value
  * so in order to force cookies to be deleted, even on MSIE, we
  * pick an expiry date 1 year and 1 second in the past
  */
  time_t t = time(NULL) - 31536001; // 注釈 : 31536001 = 60*60*24*365+1
  dt = php_format_date("D, d-M-Y H:i:s T", sizeof("D, d-M-Y H:i:s T")-1, t, 0 TSRMLS_CC);
  snprintf(cookie, len + 100, "Set-Cookie: %s=deleted; expires=%s", name, dt);
  efree(dt);

マニュアルには”Common Pitfalls”としてこの仕様がとりあげられているけど、こんな pitfall をわざわざ用意しなくてもと思ってしまった。

Cookies must be deleted with the same parameters as they were set with. If the value argument is an empty string, or FALSE, and all other arguments match a previous call to setcookie, then the cookie with the specified name will be deleted from the remote client. This is internally achieved by setting value to ‘deleted’ and expiration time to one year in past.

Advertisements
Tagged with: , , , ,
Posted in PHP, web

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Archives

Error: Twitter did not respond. Please wait a few minutes and refresh this page.

%d bloggers like this: