4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

PHPのsetcookieは値をパーセントエンコードする

4
Last updated at Posted at 2013-05-01

header()関数を使ってわざわざSet-Cookieヘッダーを書き出すのでなく、それを一発でやってくれるsetcookie()という便利な関数がありますが、これの挙動にはまってしまいました。

ある値をBase64エンコードした値を、cookieに吐き出したいと思っていました。

setcookie.php
<?php

$value = 'some value';
$encoded = base64_encode($value);
setcookie('key', $encoded);
echo $encoded, PHP_EOL;

これは期待した結果になりません。

$ curl -i localhost/setcookie.php
HTTP/1.1 200 OK
Date: Wed, 01 May 2013 14:41:54 GMT
Server: Apache/2.2.22 (Ubuntu)
X-Powered-By: PHP/5.4.9-4ubuntu2
Set-Cookie: key=c29tZSB2YWx1ZQ%3D%3D
Vary: Accept-Encoding
Content-Length: 17
Content-Type: text/html

c29tZSB2YWx1ZQ==

よおく見ると、Set-Cookieヘッダーの最後が==ではなくて%3D%3Dになってる、パーセントエンコードされちゃっています。
パーセントエンコードしないsetrawcookie()関数というのがあるみたいです。

setrawcookie.php
<?php

$value = 'some value';
$encoded = base64_encode($value);
setrawcookie('key', $encoded);
echo $encoded, PHP_EOL;
$ curl -i localhost/setcookie.php
HTTP/1.1 200 OK
Date: Wed, 01 May 2013 14:41:54 GMT
Server: Apache/2.2.22 (Ubuntu)
X-Powered-By: PHP/5.4.9-4ubuntu2
Set-Cookie: key=c29tZSB2YWx1ZQ==
Vary: Accept-Encoding
Content-Length: 17
Content-Type: text/html

c29tZSB2YWx1ZQ==

めでたしめでたし。

しかしなんでこんな仕様なんだろう……HTTPヘッダーインジェクション対策とかですかね。
逆に言うとsetrawcookie()に不用意にユーザー入力の文字列を渡すと、危険なので、そこは充分注意しましょう。

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?