Cookie劫持的對應
近期系統碰到一個漏洞,攻擊者可以透過攻擊者冒充其他登入的使用者
在使用 Cookie 紀錄登入狀態的 ASP.NET MVC 系統中,
若攻擊者能成功竊取使用者的認證 Cookie(例如 Session ID 或身份憑證),
只要將該 Cookie 複製到自己的瀏覽器中,即可冒用該用戶,繞過伺服器的身份驗證。
透過以下兩個方法做防禦
1. DB 綁定來源資訊(IP、User-Agent等)
// 在登入成功後
user.LoginIP = Request.UserHostAddress;
db.SaveChanges();
在用戶登入後,記錄來源 IP 或 User-Agent,之後每次請求都驗證
2. 請求時的監控
此步驟為關鍵安全機制之一:
-
驗證使用者登入狀態
每當有請求進入時,系統會在Application_AcquireRequestState事件中檢查使用者是否已登入(IsAuthenticated == true)。 -
IP 驗證邏輯
若使用者已登入,系統會比對:-
當前請求的 IP(
Request.UserHostAddress) -
使用者登入時儲存的原始 IP(由資料庫取得)
若兩者不一致,視為潛在異常行為,系統會強制導向登出(
/Account/Logout)。 -
-
避免登出遞迴陷阱
由於Application_AcquireRequestState會在每次請求前執行,若沒有排除登入、登出、驗證等網址,將導致如下無限循環:-
使用者發送請求 → 偵測到 IP 不一致 → 導向
/Account/Logout -
/Account/Logout也觸發AcquireRequestState→ 再次驗證失敗 → 再次導向/Account/Logout… -
造成實際登出流程永遠無法執行
為避免此情況,需排除以下路徑的檢查:
-
/account/login -
/account/logout -
/account/verify
-
protected void Application_AcquireRequestState(object sender, EventArgs e)
{
var ctx = HttpContext.Current;
var path = ctx.Request.Path.ToLower();
if (ctx.User.Identity.IsAuthenticated &&
!path.Contains("account/logout") &&
!path.Contains("account/login") &&
!path.Contains("account/verify"))
{
// 取得當前 IP
var currentIP = ctx.Request.UserHostAddress;
var originalIP = UserRepository.GetUserById(ctx.User.Identity.Name);
// 驗證 IP
if (originalIP != null && originalIP != currentIP)
{
// IP 不一致,強制登出
ctx.Response.Redirect("/Account/Logout");
}
}
}