A09: 安全記錄與監控失敗(Security Logging and Monitoring Failures)
漏洞概述
當系統缺乏適當的日誌記錄或安全監控時,攻擊者可以在系統內部進行惡意行為,而管理者卻毫無察覺。例如:
- 未記錄異常行為(如多次登入失敗、權限提升、SQL 注入等)
- 日誌未及時監控(無法即時發現攻擊活動)
- 日誌格式混亂或缺乏必要資訊(無法追蹤攻擊來源)
- 日誌存取權限不當(攻擊者可刪除或修改日誌)
這些問題可能導致攻擊發生後無法追蹤攻擊者, 甚至影響法規遵從(如 GDPR、ISO 27001、PCI-DSS)。
🔍 問題分析
1. 缺乏登入與權限異常監控
如果應用程式未記錄登入嘗試、帳號鎖定等行為,攻擊者可以暴力破解帳號,甚至提升權限,系統卻毫無警覺。
❌ 攻擊方式
- 攻擊者使用暴力破解工具(如 Hydra)嘗試登入大量帳號
- 惡意使用者嘗試 權限提升(如低權限帳號嘗試存取管理員介面)
- 多次失敗登入後仍未鎖定帳號,允許持續攻擊
❌ 示範程式碼(Golang:未記錄登入嘗試)
package main
import (
"fmt"
"net/http"
)
func loginHandler(w http.ResponseWriter, r *http.Request) {
username := r.FormValue("username")
password := r.FormValue("password")
// 這裡缺乏登入日誌記錄
if username == "admin" && password == "123456" {
fmt.Fprintf(w, "登入成功")
} else {
fmt.Fprintf(w, "登入失敗")
}
}
func main() {
http.HandleFunc("/login", loginHandler)
http.ListenAndServe(":8080", nil)
}
❌ 問題:
- 這段程式碼未記錄登入成功或失敗的資訊,管理者無法追蹤異常登入行為。
- 若使用者多次輸入錯誤密碼,應用程式未鎖定帳號,允許暴力破解攻擊。
✅ 修補措施
- 記錄所有登入成功與失敗的日誌
- 啟用多因素驗證(MFA)來增加安全性
- 設置登入失敗次數限制,並記錄異常登入行為
🛠️ 修正後(記錄登入日誌 + 帳號鎖定)
package main
import (
"fmt"
"log"
"net/http"
"sync"
"time"
)
// 追蹤失敗登入次數
var failedLogins = make(map[string]int)
var lock = sync.Mutex{}
func loginHandler(w http.ResponseWriter, r *http.Request) {
username := r.FormValue("username")
password := r.FormValue("password")
lock.Lock()
defer lock.Unlock()
// 如果帳號已鎖定
if failedLogins[username] >= 3 {
log.Printf("帳號 %s 已鎖定,登入失敗", username)
http.Error(w, "帳號已鎖定", http.StatusForbidden)
return
}
if username == "admin" && password == "securepassword" {
log.Printf("使用者 %s 登入成功", username)
fmt.Fprintf(w, "登入成功")
delete(failedLogins, username) // 清除失敗記錄
} else {
log.Printf("使用者 %s 登入失敗", username)
failedLogins[username]++
time.AfterFunc(5*time.Minute, func() { // 5 分鐘後重置
lock.Lock()
delete(failedLogins, username)
lock.Unlock()
})
http.Error(w, "登入失敗", http.StatusUnauthorized)
}
}
func main() {
http.HandleFunc("/login", loginHandler)
log.Println("伺服器啟動於 :8080")
http.ListenAndServe(":8080", nil)
}
🛠️ 修正點:
- 記錄登入行為(成功與失敗)
- 加入帳號鎖定機制(防止暴力破解)
- 限制登入失敗次數並設置解鎖時間
2. 日誌格式混亂,無法分析攻擊行為
若日誌格式不統一,或者缺少關鍵資訊(如 IP、時間戳記、用戶 ID),則難以進行安全分析。
❌ 攻擊方式
- 攻擊者登錄惡意帳號,系統記錄不全,難以追蹤來源
- SQL 注入攻擊後,日誌未顯示攻擊載荷,無法復現攻擊手法
❌ 示範程式碼(不完整的日誌)
log.Println("登入失敗")
❌ 問題:
- 沒有記錄 IP、時間、帳號、嘗試的密碼,日後難以調查
✅ 修補措施
- 統一日誌格式,記錄必要資訊(IP、時間、使用者 ID)
- 將日誌存入 ELK、Splunk 或 SIEM 平台
🛠️ 修正後
log.Printf("[Login Failed] Time: %s | IP: %s | User: %s", time.Now().Format(time.RFC3339), r.RemoteAddr, username)
3. 未即時監控,導致攻擊長時間未被發現
如果應用程式只記錄日誌,但沒有即時監控,攻擊者可以長時間在系統內部活動而不被發現。
❌ 攻擊方式
- 攻擊者長期使用 SQL 注入竊取資料,管理者卻未察覺
- 系統被植入後門(Web Shell),但沒有警報通知
✅ 修補措施
- 使用 SIEM 監控日誌,設定異常行為警報
- 對敏感操作(如資料刪除、權限提升)設置即時警報
- 記錄 API 存取行為,偵測異常請求