已知問題
本頁列出 v1.0.0 原始碼中已確認、會讓行為與設計不符的缺陷,以及在修正前可採取的因應方式。
會影響安全或可用性
| 問題 | 位置 | 影響 | 因應 |
|---|---|---|---|
| Redis 在評分階段失敗時 nil pointer panic | instance.go:156 |
dynamicScore 回傳 nil, err,Check 只記錄錯誤後讀取 score.IsBlock |
Gin 使用 gin.Recovery();net/http 會中斷該連線 |
| 用戶端 IP 直接信任代理標頭 | device.go getClientIP |
偽造 X-Forwarded-For 等標頭即可繞過速率限制、Block、Deny,或冒用 Allow 名單 IP |
由前端代理覆寫或清除標頭,見 用戶端 IP 解析 |
BlockTimeMin/BlockTimeMax 為 0 時封鎖永久生效 |
block.go Add |
未設定時封鎖紀錄永不過期 | 兩者都設為正值 |
設計上存在但不會執行的功能
| 功能 | 位置 | 原因 |
|---|---|---|
HighRiskCountry 高風險國家加分 |
geo.go:248 |
歷史紀錄解析時把國家碼存進 Country,比對卻用永遠為空的 CountryCode |
分數過高自動 Block.Add |
score.go:196 |
條件是 > 100,但 calcScore 已把總分上限壓在 100 |
封鎖中持續請求達 BlockToBan 轉 Deny |
instance.go:141 |
前一步 device.Is.Block 已回 403,判斷式不會執行 |
too_frequent_requests |
score.go:546 |
需要 16 個間隔,列表最多只保留 10 個;ScoreFrequencyRequest 也沒有預設值 |
ScoreNormal |
type.go |
欄位存在但沒有任何程式讀取 |
其他行為缺陷
| 問題 | 位置 | 影響 |
|---|---|---|
| Email 副本不會投遞 | deny.go:157 |
smtp.SendMail 的收件者只有 To,CC 只出現在標頭 |
只有 CountryDB 時地理偵測整段停用 |
score.go:441 |
calcGeo 要求 CityDB 存在 |
| 每個請求輸出除錯字串 | score.go:457 |
啟用 GeoLite2 時以標準 log.Print 印出位置與 key,不經 Logger |
預設值在請求路徑寫回 Config |
instance.go、score.go、geo.go |
並行請求同時寫入相同欄位,go test -race 會回報資料競爭 |
| 內網與外網交替時誤判快速移動 | geo.go |
內網紀錄經緯度為 (0, 0),見 地理偵測 |
LoginFailure/NotFound404 重複計入請求數 |
score.go |
兩者內部再次執行裝置識別,同一請求計入兩次每分鐘計數 |
重現:Redis 中斷時的 panic
package main
import (
"fmt"
"net/http/httptest"
"strconv"
"time"
"github.com/alicebob/miniredis/v2"
golangIPSentry "github.com/pardnchiu/golang-ip-sentry"
)
func main() {
mr, err := miniredis.Run()
if err != nil {
panic(err)
}
port, _ := strconv.Atoi(mr.Port())
sentry, err := golangIPSentry.New(golangIPSentry.Config{
Redis: golangIPSentry.Redis{Host: mr.Host(), Port: port},
Parameter: golangIPSentry.Parameter{BlockTimeMin: time.Minute, BlockTimeMax: time.Hour},
})
if err != nil {
panic(err)
}
mr.Close()
defer func() { fmt.Println("recovered:", recover()) }()
r := httptest.NewRequest("GET", "https://example.com/", nil)
sentry.Check(r, httptest.NewRecorder())
}
實際輸出:
recovered: runtime error: invalid memory address or nil pointer dereference