Secureフラグのない機密Cookieの設定

Secureフラグのない機密Cookieの設定

説明

セッションIDやログイン状態などの機密情報を含むCookieに Secure フラグがないと、暗号化されていないHTTPでも送信される可能性があります。公衆Wi-Fiなどで通信を傍受できる攻撃者が値を盗み、そのセッションCookieでユーザーになりすますおそれがあります。

想定される影響

  • HTTPSで発行したセッションCookieが後からHTTPで送られ、傍受によるセッションの乗っ取りにつながる可能性があります。
  • 盗まれたセッションIDでユーザーになりすまされ、アカウント情報の閲覧、設定変更、決済などを行われるおそれがあります。
  • 権限情報やユーザー識別子など、Cookieに含まれる追加の機密情報も漏えいする可能性があります。

対処方法

  • すべてのセッション・認証Cookieに Secure: true を設定してください。
  • サービス全体でHTTPSを使ってください。HTTPからHTTPSへリダイレクトしても、最初のHTTPリクエストで送られたCookieは保護できません。
  • HttpOnly: true も設定し、JavaScriptによる値の窃取を抑えてください。XSS自体を防ぐ設定ではありません。
  • 可能なら機密ではないCookieにも、既定で Secure を適用してください。
  • Cookieの作成・削除用の共通関数で、必要な保護属性を維持してください。削除時には元のCookieの名前、Domain、Path と一致させてください。

例

変更前

go
package main

import (
    "net/http"
)

// 変更前: Secureフラグなし
func setSessionCookie(w http.ResponseWriter, sessionID string) {
    // ログインセッションCookieにSecureとHttpOnlyを設定していない
    cookie := http.Cookie{
        Name:  "SESSIONID",
        Value: sessionID,
        Path:  "/",
        // Secureの既定値はfalse
        // HttpOnlyの既定値はfalse
    }

    // HTTPリクエストでも送信される可能性がある
    http.SetCookie(w, &cookie)
}

変更後

go
package main

import (
    "net/http"
    "time"
)

// 変更後: SecureとHttpOnlyを明示的に設定
func setSessionCookie(w http.ResponseWriter, sessionID string) {
    cookie := http.Cookie{
        Name:     "SESSIONID",
        Value:    sessionID,
        Path:     "/",
        Secure:   true,          // HTTPS接続だけで送信
        HttpOnly: true,          // JavaScriptから読み取り不可
        SameSite: http.SameSiteLaxMode,
        Expires:  time.Now().Add(30 * time.Minute),
    }

    http.SetCookie(w, &cookie)
}

// 削除時もSecure/HttpOnlyを維持
func deleteSessionCookie(w http.ResponseWriter) {
    cookie := http.Cookie{
        Name:     "SESSIONID",
        Value:    "",
        Path:     "/",
        Secure:   true,
        HttpOnly: true,
        Expires:  time.Unix(0, 0),
        MaxAge:   -1,
    }

    http.SetCookie(w, &cookie)
}

解説:

  • 変更前: setSessionCookie が機密の SESSIONID Cookieを Secure: true なしで作るため、HTTPで送られて傍受される可能性があります。HttpOnly もなく、XSSがあるとJavaScriptから値を読まれるおそれがあります。
  • 変更後: Secure: true でHTTPSだけに送信を限定し、HttpOnly: true でブラウザーのJavaScriptから値を読めなくします。削除例では同じ名前と Path を使い、どちらも Domain を省略しています。元のCookieを削除するにはこの識別範囲の一致が必要です。Secure と HttpOnly は別の保護属性です。

参考資料