Cookieの改竄、改変について確認してみました

PHP

最近、Cookieについて耳にする機会が増えたのですが、そもそもCookieについてあまり詳しくなかったので、Cookieについて調べ、ローカル環境を使って改竄改変等について実験し、インジェクション対策について考えてみました。

Cookieの確認方法

PHPを使ってブラウザに登録されているCookie情報を取得するには次の方法を使用します。

//PHP によるcookie情報の取得
<?php
// クッキー情報を取得
$cookies = $_COOKIE;

// クッキー情報を表示
if (!empty($cookies)) {
    echo "<h1>取得可能なクッキー情報:</h1>";
    echo "<ul>";
    foreach ($cookies as $name => $value) {
        echo "<li><strong>$name:</strong> $value</li>";
    }
    echo "</ul>";
} else {
    echo "<h1>取得可能なクッキー情報はありません。</h1>";
}
?>

次のクッキーチェッカーを作って、ドメイン中のCookieを登録更新できるようにしました。(リンクは一番下に貼ってあります)

ローカル環境での開発者モードによる比較

Edgeブラウザの開発ツールでクッキー情報を表示して並べるとこんな感じになります。

ちゃんとクッキーの一覧が表示されていることが確認できました。

レンタルサーバ上での開発者モードによる比較

クッキーチェッカーを、レンタルサーバにアップロードして実行したところ、次のような出力になりました。

 開発者ツール上ではCookieのKey値に[ENC_]がついていますが、PHP上では[set_cookie]で値が取得できています。
 この他に[_ga]から始まるCookieも複数件表示されていますが、PHPでは取得できていません。

 Cookie名にENC_がついているのは、レンタルサーバ等の共有サーバではよくあることらしく、他のドメインが使用しているCookieを取得できないようにカプセル化しているとのことでした。
 PHPでCookie情報を取得すると、欲しい情報は問題なく取得できているので問題なさそうです。
 _gaから始まるCookieは、GoogleAnalyticsが使っているcookieとのことでした。(自分で登録したのに忘れていました)

他のページでのCookieの使用について

大手サイトではCookieがどのくらい使われているのかと思い、調べてみました。

 Googleの検索画面を開くと、36個のCookieが登録されていました

 Yahooでは27個のCookieが登録されていました

YouTubeを開くと63個のCookieが登録されていました

 有効期限があるので全てのCookieが生きているわけではないと思いますが、大手サイトでは多くのCookieを使って情報を集めいていることがわかりました。

Cookieの改竄改変について

 開発者ツールを使って、Cookieの改竄が可能か実験したところ、簡単に書き換えることができました。
 ローカル環境でクッキーチェッカーと開発者ツールを使って、
   Cookieの値を変更
   Cookieのkeyを変更
   Cookieの追加
したところ、どれも簡単にできました。

複数のCookieを生成した結果
Cookieのkeyは、日本語、記号、英数字が登録可能でした
CookieのValueは、日本語、記号、英数字が登録可能でした
結構なんでも登録できてしまいます。

 ちなみにEdgeブラウザのCookieの保存先は、
   C:\Users\{ユーザ名}\AppData\Local\Microsoft\Edge\User Data\Default\Network\Cookies
となっていますが、ロックがかかっていて直接編集はできませんでした。

最後に思ったこと

 Cookieは、簡単に改竄が可能なパラメータですので、
   Cookieデータの記号エスケープ
   Cookieデータの整合性チェック
を行う必要性があると感じました。
 Cookieの値をブラウザ上のHidden パラメータ等に使用するとインジェクション攻撃を受ける可能性があります。
 例えばPHPであれば次のような方法で、記号をエスケープさせるべきです。

//インジェクションの脆弱性がある
$value = $_COOKIE[$cookie_name];
echo "<input type='hidden' name='cookie_key' value='$value'>";

//インジェクション対策済み
$value = $_COOKIE[$cookie_name];
$print_value = htmlspecialchars($value, ENT_QUOTES, 'UTF-8');
echo "<input type='hidden' name='cookie_key' value='$print_value'>";

CookieチェッカーのURLも載せておくので、興味がある方は確認してみてください
たんすのCookie Check (tansunohazama.sakura.ne.jp)

000064