1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

■ セッションとは

ユーザーの情報をサーバー側で保持し、ページを移動している間にその情報を活用できる仕組みです。

ログイン状態の管理、お問い合わせフォームの状態管理、正しいページからリクエストがされているかを検証する(CSRF対策)など、様々な用途で利用されています。

サーバー側といってもDBに保存するわけではないため、有効期限を設定したり、利用制限を設けるなどして適切に管理する必要があります。

セッションとは、ユーザーがページを移動している間、そのユーザーのアクセス情報をそのユーザーごとに保持したまま移動できる仕組みです。

PHP のセッションは、ユーザーを識別する「セッション ID」と Web サーバーにデータを保存する「セッション変数($_SESSION)」により実現されます。

クッキーはデータをユーザーのブラウザに保存しますが、セッションはデータ(セッション変数)を Web サーバー上に保存し、セッション ID のみをクッキー(セッションクッキー)に保存します。

https://www.webdesignleaves.com/pr/php/php_basic_07.php#google_vignette

■ セッションの仕組み

PHPを例にして、先ほど引用した下記のサイトで動作を確認しながら説明をしていきます。
https://www.webdesignleaves.com/pr/php/php_basic_07.php#google_vignette

ポイントは以下の3つです。

  • セッション ID
  • セッション変数($_SESSION)
  • クッキー(PHPSESSID)

参考サイトの「セッションの流れ」というセクションにあるsession_counter.phpをクリックしてみてください。セッションが管理されているため画面を再読み込みしたり、別のタブで画面を開くたびにカウントアップしていきます。また別のブラウザで開くとカウンターがリセットされるのでブラウザごとに管理されていることがわかりますね。

image.png

ここで開発者ツールの「アプリケーション」タブからCookieを参照すると「PHPSESSID」があることがわかります。これを削除して再読み込みするとカウンターがリセットされます。

image.png

以上から、

  • アクセスするとセッション IDが発行される
  • セッション IDがクッキー(PHPSESSID)としてクライアント側に保存される
  • サーバー側でセッション変数($_SESSION)が利用可能となり、カウントが管理されている
  • PHPSESSIDを削除するとセッションがリセットされる

ことがわかりました。

またこのときクッキー(PHPSESSID)はクライアント側からサーバー側へリクエストのたびに自動的に送信されています。

ということは、適切なセキュリティ対策をしないと悪用され、最悪の場合ログイン状態を乗っ取られてしまったりといった被害が発生する恐れがあります。

■ セッションのセキュリティ

セッションIDが攻撃者に盗まれてしまうと不正なログインやCSRF攻撃につながってしまいます。

そのため以下のような対策を実施する必要があります。

  • 通信時の盗聴対策(CookieがHTTPS通信でのみ送信されるようにする)
    • Secure属性を有効化
  • XSS対策(JavaScriptからCookieを利用できないようにする)
    • HttpOnly属性を有効化
  • CSRF対策
    • SameSite属性を有効化
  • セッションハイジャックや固定攻撃への対策
    • セッションID有効期限を設定して定期的に再発行する

以下は上記の対策を関数にまとめているコード例です。

このコード例は「Cookieの有効期限が未設定でありブラウザを閉じるとセッションがリセットされる」ことが前提であり、ログイン状態など一定期間セッションを保持する場合には利用できません。お問い合わせフォームに対するCSRF対策など一時的にセッションを利用する場合を想定しています

/**
 * セキュアなセッションを開始する関数
 *
 * - CookieにHttpOnly・Secure・SameSite属性を付与
 * - 初回アクセス時にセッションIDを再生成
 * - 30分ごとにセッションIDを再生成し、
 *   セッション固定攻撃やセッションハイジャックのリスクを軽減する
 */
function startSecureSession() {
    // セッションクッキーのパラメータを設定
    session_set_cookie_params([
        'lifetime' => 0, // ブラウザを閉じるまで
        'path' => '/',
        'domain' => '', // 現在のドメインを使用
        'secure' => !empty($_SERVER['HTTPS']), // 本番環境ではSecure=trueを推奨
        'httponly' => true, // XSS対策
        'samesite' => 'Strict' // CSRF対策
    ]);

    // 新しいセッションを開始
    session_start();

    // 初回のみID更新
    if (!isset($_SESSION['initiated'])) {
        session_regenerate_id(true);
        $_SESSION['initiated'] = true;
        $_SESSION['created'] = time();
    }

    // セッションの有効期限チェック(30分で再生成)
    if (time() - $_SESSION['created'] > 1800) {
        session_regenerate_id(true);
        $_SESSION['created'] = time();
    }
}

session_start関数自体はセッションIDを再発行しません。

  • セッションCookieがあればそのまま使う
  • セッションCookieがなければ新たに発行する

session_regenerate_idでセッションIDを定期的に変更することで、セッション固定攻撃やセッションハイジャックのリスクを低減します。これはセッションそのものを30分で破棄する処理ではありません。

■ 終わりに

ここで紹介したセキュリティ対策の例はごく一部であり最低限の対策ですので、以下に参考サイトを掲載しておきます。

1
0
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?