WordPressが発行するCookieにHttpOnly属性が付いていないことを問題にされた場合の対処
うちも自動検査ツールの生成したレポートをメールしてお金もらうだけの簡単なお仕事で儲けたいよ。
世の中にはWebサイトのセキュリティ検査をする有料サービスがあって、そういったサービスを利用すると WordPressが発行する ```wordpress_test_cookie``` という Cookieに HttpOnly属性が付いていないという指摘を受けることがあると風のうわさに聞いた(あくまでこれは伝聞である。繰り返す。伝聞である)。
## コマンドラインからの確認方法
コマンド
```shell
curl -I https://YOUR-WORDPRESS-SITE.com/wp-login.php | grep 'Set-Cookie'
```
結果
```text
< Set-Cookie: wordpress_test_cookie=WP+Cookie+check; path=/; secure
```
確かに ```wordpress_test_cookie``` という Cookieに HttpOnly 属性が付いていないのは事実のようである。
## CookieのHttpOnly属性とは
[HTTP Cookie の使用 - HTTP | MDN](https://developer.mozilla.org/ja/docs/Web/HTTP/Cookies)
この属性が付いた Cookieは、JavaScriptから内容を読み取ることができない。たとえばもし何らかのセキュリティ脆弱性などによりサイトに不正な JavaScriptが仕込まれたとしても、この属性が付いているCookieは盗難を免れうる。なのでこれを付けるのがセキュリティの観点から推奨されるということになる。ただし、Cookieの用途によっては正当な JavaScriptから読み取れないといけない場合も考えられるので、なんでもこれを付けて良いというものではない。また、機微情報を含まないCookieについても付ける意味がない。
## WordPressが当該Cookieに HttpOnlyを付けない理由
[WordPressコア開発メンバーのコメント](https://core.trac.wordpress.org/ticket/52639#comment:7)
<div class="alert alert-warning" role="alert">
> The wordpress_test_cookie is just a test cookie to make sure cookies work. There isn't a security issue from having them accessible over JS.
</div>
日本語訳:
<div class="alert alert-warning" role="alert">
> wordpress_test_cookie はCookieが機能するかどうかテストするためだけのCookieだから JavaScriptからアクセスできてもセキュリティ上の問題はありません。
</div>
```wordpress_test_cookie``` というCookieはいわば動作チェック用のダミーで、その用途上 HttpOnly属性を付けてJavaScriptからのアクセスを回避する理由がないため付けていないということだ。つまり、セキュリティの観点からも**必要ないので付けていない**。
## 脆弱性検査ツールによる指摘の妥当性
WordPressの開発者が上記のように言っている上に、実際に技術的な観点から間違っているとは考えられないので脆弱性検出**ツールによる指摘は的外れ**であると言えるのだが、ツール側はただの自動検査ツールに過ぎず Cookieの個別用途や WordPress開発者の意図まで汲めるわけではないので、ただ機械的に指摘事項として挙げて来てしまっただけということになる。なので別に的外れな指摘をするツールが悪いということでもなく、指摘の意味を読み手がわかるかどうかの問題。
## それでも対策しろと言われた。どうしたら良いか
だろうね。よくあるよ、そういうこと。
検索するとよく PHPの設定で ```session.cookie_httponly``` というフラグを有効にすれば良いという情報が出てくるが、これはPHPが発行するセッションCookieに関しての設定なので WordPressが発行するCookieとは**関係ない**。こと WordPressが発行するCookieに関して言えば**PHPの設定で対処できるという情報はガセネタ**である。
仕方ないので WordPressを改造する必要がある[^1]。
[wp-login.php の 416行目付近](https://github.com/WordPress/WordPress/blob/21bcc7c836a67fa0c7e214bd82119ad50036d148/wp-login.php#L416) にある
```php
setcookie( TEST_COOKIE, 'WP Cookie check', 0, COOKIEPATH, COOKIE_DOMAIN, $secure );
if ( SITECOOKIEPATH !== COOKIEPATH ) {
setcookie( TEST_COOKIE, 'WP Cookie check', 0, SITECOOKIEPATH, COOKIE_DOMAIN, $secure );
}
```
を
```php
setcookie( TEST_COOKIE, 'WP Cookie check', 0, COOKIEPATH, COOKIE_DOMAIN, $secure, true );
if ( SITECOOKIEPATH !== COOKIEPATH ) {
setcookie( TEST_COOKIE, 'WP Cookie check', 0, SITECOOKIEPATH, COOKIE_DOMAIN, $secure, true );
}
```
に修正(```setcookie```関数の最後の引数として```true```を追加)すれば ```wordpress_test_cookie``` に HttpOnly属性が付く。ただし **WordPressをバージョンアップすると wp-login.phpはおそらく上書きされるため、都度この変更を適用することとなる**。
[^1]: [Apacheの設定で無理やり Set-Cookieヘッダを改変する](https://stackoverflow.com/questions/24129201/add-secure-and-httponly-flags-to-every-set-cookie-response-in-apache-httpd)という手段もある。影響範囲を自分でコントロールできる自信があるならこの方法でも良いだろう。
## そうだ、WordPressの方で公式に修正してもらえないかな?
開発者の言ってることよりも自動検査ツールの的外れな指摘を信じるような人のお願いを聞き入れてもらえると思う?