Session 是 PHP 有狀態應用的核心機制,但也是攻擊重點。本文系統分析 Session 劫持、固定、注入、檔案存取等攻擊向量,提供完整防禦配置與代碼最佳實踐。
document.cookie 讀取 PHPSESSID; php.ini
session.cookie_httponly = 1 ; 禁止 JS 存取 Cookie
session.cookie_secure = 1 ; 僅 HTTPS 傳輸 (必須全站 HTTPS)
session.use_only_cookies = 1 ; 禁用 URL 傳遞 Session ID
攻擊者預先取得有效 Session ID (如 PHPSESSID=abc123),誘導受害者使用此 ID 登入 (連結含 ?PHPSESSID=abc123),受害者登入後 Session 綁定用戶身分,攻擊者同樣 ID 即獲得權限。
; php.ini
session.use_strict_mode = 1 ; 拒絕未初始化的 Session ID (PHP 5.5+)
register_globals=On 時,$_GET['username'] 可覆蓋 $_SESSION['username']。即使關閉,若代碼邏輯先檢查 $username 再註冊 Session,攻擊者可在註冊前注入。
register_globals = Off$_SESSION['var'],不依賴全域變數$_SESSION['app_user_id']預設 session.save_path = /tmp,所有用戶 Session 檔案同目錄,權限通常 600 但屬於同一用戶 (如 www-data),其他虛擬主機用戶可讀寫:
; php.ini 或 PHP-FPM pool 設定
session.save_path = /var/lib/php/sessions_隔離目錄
; 目錄權限 700,擁有者為該站點執行用戶
session.save_handler = redis、session.save_path = "tcp://127.0.0.1:6379"PHP Session 預設使用 php_serialize (PHP 5.5.4+) 或 php 處理器序列化。若應用有 unserialize() 用戶輸入 (如反序列化 Gadget Chain),攻擊者可構造惡意 Session 資料觸發 RCE。
unserialize() 處理用戶輸入,改用 JSONsession.serialize_handler = php_serialize (更安全); php.ini
session.save_handler = redis ; 推薦 Redis
session.save_path = "tcp://127.0.0.1:6379?auth=password&database=1"
session.name = MYAPPSESSID ; 自定義 Cookie 名稱,避免預設名稱被針對
session.cookie_lifetime = 0 ; 瀏覽器關閉失效
session.cookie_path = / ; 整站有效
session.cookie_domain = .example.com ; 子域共享 (可選)
session.cookie_httponly = 1
session.cookie_secure = 1 ; 僅 HTTPS
session.cookie_samesite = Strict ; 防 CSRF (PHP 7.3+)
session.use_strict_mode = 1
session.use_only_cookies = 1
session.gc_probability = 1
session.gc_divisor = 1000 ; 0.1% 機率 GC
session.gc_maxlifetime = 1440 ; 24 分鐘廢棄
session.serialize_handler = php_serialize
session.sid_length = 32 ; Session ID 長度 (PHP 7.1+)
session.sid_bits_per_character = 5 ; 熵值
| 特性 | 檔案 | Redis |
|---|---|---|
| 共享主機隔離 | 差 | 優 (Key 前綴隔離) |
| 多伺服器叢集 | 需 NFS/共享儲存 | 原生支援 |
| 效能 | 磁碟 I/O 瓶頸 | 記憶體級,微秒延遲 |
| 原子操作 | 難以保證 | 支援 Lua 腳本原子化 |
| TTL 自動過期 | 需 GC 機率清理 | 原生 TTL 精確過期 |
cookie_secure=1 + HSTScookie_httponly=1 + cookie_samesite=Strictsession_regenerate_id(true)use_strict_mode=1 防固定攻擊session_destroy() + 刪除 Cookie