セッションに関連する INI 設定をセキュアにする

セッション関連のINI設定をセキュアにすることで、 開発者はセッションのセキュリティを改善できます。 重要な INI 設定であっても、推奨される設定がないものがあります。 開発者にはセッションの設定を強固にする責任があります。

  • session.cookie_lifetime=0

    0 には特別な意味があります。 これは、恒久的なストレージにクッキーを保存しないようブラウザに指示します。 よって、ブラウザが終了した場合、セッションIDクッキーはすぐに削除されます。 開発者がこの値を0以外にすると、他のユーザーがセッションIDを使うことを許す可能性があります。 このため、ほとんどのWebアプリケーションは、"0" を使うべきです。

    自動ログイン機能が必須の場合、 開発者は自前のセキュアな自動ログイン機能を実装しなければなりません。 この機能のために、有効期間が長いセッションIDを使ってはいけません。 前のページの関連するセクションで、より多くの情報が見つかるかもしれません。

  • session.use_cookies=On

    session.use_only_cookies=On

    HTTP クッキーはいくつか問題を抱えていますが、 クッキーはセッションIDを管理する手段として好ましい方法であり続けています。 セッションIDの管理に、可能であればクッキーだけを使うようにしましょう。 ほとんどのアプリケーションはセッションIDの管理にクッキーを使うべきです。

    session.use_only_cookies=Off の場合、 セッションモジュールは、たとえセッションIDクッキーが未初期化であっても、 セッションIDが与えられた GET/POST/URL によって設定されたものをセッションIDに使うようになります。

  • session.use_strict_mode=On

    セッションをセキュアにするために session.use_strict_mode を有効にすることは必須ですが、 デフォルトでは無効になっています。

    有効にすることで、セッションモジュールが未初期化のセッションIDを使うことを防げます。 別の言い方をすると、セッションモジュールは、 セッションモジュールが生成した有効なセッションIDだけを受け入れるようになるということです。 この設定は、ユーザーによって与えられたあらゆるセッションIDを拒否します。

    Cookie の仕様によって、 攻撃者はローカルにクッキーのデータベースを設定したり、 JavaScriptインジェクションの脆弱性を突くことで、 削除できないセッションIDクッキーを置くことが可能です。 session.use_strict_mode によって、 攻撃者が初期化したセッションIDが使われるのを防ぐことができます。

    注意:

    攻撃者は自分のデバイスでセッションIDを初期化し、 ターゲットユーザーのセッションIDを設定するかもしれません。 攻撃者は悪用するセッションIDをアクティブな状態に保たなければなりません。 攻撃者はこのシナリオで攻撃を実行するには追加のステップが必要です。 よって、session.use_strict_mode が軽減策として役に立つのです。

  • session.cookie_httponly=On

    セッションクッキーを JavaScript からアクセスさせることを拒否します。 この設定によって、JavaScriptインジェクションによってクッキーを盗むことを防げます。

    セッションIDをCSRFトークンとして使うことも可能ですが、 推奨されません。たとえば、HTMLソースが保存され、他のユーザに送られることがあるからです。 開発者は、セキュリティを向上させるため、セッションIDをWebサイトに出力すべきではありません。 ほとんどのアプリケーションは、httponly 属性をセッションIDクッキーに設定しなければなりません。

    注意:

    CSRF トークンも、セッションIDと同じように定期的に更新すべきです。

  • session.cookie_secure=On

    セッションIDクッキーを、プロトコルがHTTPSの場合にだけアクセスすることを許可します。 website が HTTPS 経由でのみアクセス可能であるなら、この設定を有効にすべきです。

    HTTPS 経由でのみアクセス可能なWebサイト向けに、HSTS も検討すべきです。

  • session.cookie_samesite="Lax" または session.cookie_samesite="Strict"

    PHP 7.3 以降では、セッションIDクッキー向けに "SameSite" 属性が設定できます。 この属性は、CSRF (Cross Site Request Forgery) 攻撃を軽減する手段です。

    Lax と Strict の違いは、 HTTP GETリクエストを使う別の登録可能なドメインへのリクエストに対して、クッキーへのアクセスを許可するかどうかです。 Lax を使っているクッキーは別の登録可能なドメインへのGETリクエストからアクセス可能ですが、 Strict を使っているクッキーはそうではありません。

  • session.gc_maxlifetime=[choose smallest possible]

    session.gc_maxlifetime は期限切れのセッションIDを削除する設定です。 この設定に依存することは推奨しません。 開発者はタイムスタンプを使って、セッションの有効期間を自前で管理すべきです。

    セッションGC(ガベージコレクション)は、 session_gc() を使って行うのが最適です。 session_gc() 関数は、タスクマネージャーを使って実行すべきです。 たとえば、UNIXライクなシステムだと cron が挙げられます。

    GC処理はデフォルトでは確率的に行われます。 この設定は期限切れのセッションが削除されることを保証 しません。 開発者はこの設定に依存することはできませんが、 可能な限り最小の値を指定することを推奨します。 session.gc_probabilitysession.gc_divisor の値を、 適切な頻度で期限切れのセッションが削除されるように調整してください。 自動ログイン機能が必須の場合、開発者は自前のセキュアな自動ログイン機能を実装しなければなりません。 詳細な情報は前のページを参照してください。 自動ログイン機能のために、有効期限が長いセッションIDを絶対に使わないでください。

    注意:

    セッション保存ハンドラモジュールによっては、 期限切れの処理を確率ベースで行うためにこの設定を使わないものもあります。 たとえば memcached, memcache が挙げられます。 詳細については、セッション保存ハンドラのドキュメントを参照してください。

  • session.use_trans_sid=Off

    透過的なセッションID管理を使うことは禁止されていません。 開発者は必要な場合は採用しても構いません。 しかし、透過的なセッションID管理を無効にすると、 セッションIDインジェクションやリークの可能性が排除できるので、 一般的なセッションIDのセキュリティを改善できます。

    注意:

    セッションIDは、ブックマークされたURLや、電子メールに埋め込まれたURLや、 保存されたHTMLソースなどから漏れる可能性があります。

  • session.trans_sid_tags=[limited tags]

    (PHP 7.1.0 >=) 開発者は必要ないのにHTMLタグを書き換えるべきではありません。 デフォルト値でほとんどの場合は十分です。古いPHPバージョンの場合は、 url_rewriter.tags を代わりに使ってください。

  • session.trans_sid_hosts=[limited hosts]

    (PHP 7.1.0 >=) この INI 設定は、 trans sid の書き換えを許可するホストをホワイトリスト形式で定義します。 信頼できないホストを絶対に追加しないでください。 セッションモジュールは、この設定が空の場合、 $_SERVER['HTTP_HOST'] だけを許可します。

  • session.referer_check=[originating URL]

    session.use_trans_sid が有効になっている場合、 この設定はセッションIDインジェクションのリスクを減らします。 website が http://example.com/ の場合、 http://example.com/ を設定してください。 HTTPS ブラウザはリファラヘッダを送信しないことに注意してください。 ブラウザはリファラヘッダを設定によって送信しない可能性もあります。 よって、この設定は信頼できるセキュリティ対策ではありませんが、 この設定を使うことは推奨します。

  • session.cache_limiter=nocache

    HTTP コンテンツを認証済みのセッションに関してはキャッシュしないようにします。 コンテンツがプライベートでない場合だけ、キャッシュを許可します。 そうしない場合、コンテンツが外部に流出する可能性があります。 "private" は、HTTPコンテンツがセキュリティに敏感なデータを含まない場合であれば採用しても構いません。 "private" は、共有されたクライアントによってキャッシュされた、 プライベートなデータを送信する可能性があることに注意してください。 "public" は、HTTPコンテンツがプライベートなデータを一切含んでいない場合にのみ使わなければなりません。

  • session.sid_length="48"

    (PHP 7.1.0 >=) 長いセッションIDであればあるほど、強いセッションIDになります。 開発者はセッションIDの長さを32文字以上にすることを検討すべきです。 session.sid_bits_per_character="5" の場合、 少なくとも 26文字以上が必須です。

  • session.sid_bits_per_character="6"

    (PHP 7.1.0 >=) セッションIDの文字に多くのbitを使うほど、 セッションモジュールが生成するセッションIDは、 長さが同じであっても強くなります。

  • session.hash_function="sha256"

    (PHP 7.1.0 <) より強いハッシュ関数は、より強いセッションIDを生成します。 ハッシュの衝突が起こる可能性は、MD5 ハッシュアルゴリズムを使っても低いですが、 開発者は SHA2 またはそれより強い sha384 や sha512 のようなハッシュアルゴリズムを使うべきです。 開発者は、十分に長い entropy をハッシュ関数を使うときに必ず与えなければなりません。