文件 v1.0.0

已知問題

本頁列出 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
EN