Documentation v1.0.0

Known Issues

This page lists confirmed defects in the v1.0.0 source that make behavior differ from the design, and what to do until they are fixed.

Security and Availability

Issue Location Impact Workaround
Nil pointer panic when Redis fails during scoring instance.go:156 dynamicScore returns nil, err; Check only logs the error, then reads score.IsBlock Use gin.Recovery() with Gin; net/http drops that connection
Proxy headers are trusted for the client IP device.go getClientIP Forging X-Forwarded-For and similar headers bypasses rate limits, Block, and Deny, or impersonates an Allow-listed IP Have the front proxy overwrite or strip the headers; see Client IP Resolution
Blocks become permanent when BlockTimeMin / BlockTimeMax is 0 block.go Add Unset values make block records never expire Set both to positive values

Designed Features That Never Run

Feature Location Reason
HighRiskCountry scoring geo.go:248 History parsing stores the country code in Country, but the comparison reads CountryCode, which is always empty
Automatic Block.Add on a high score score.go:196 The condition is > 100, but calcScore already caps the total at 100
Escalating to Deny after BlockToBan requests while blocked instance.go:141 device.Is.Block returns 403 one step earlier, so the check never runs
too_frequent_requests score.go:546 Needs 16 intervals while the list keeps at most 10; ScoreFrequencyRequest also has no default
ScoreNormal type.go The field exists but nothing reads it

Other Behavior Defects

Issue Location Impact
Email CC is never delivered deny.go:157 smtp.SendMail receives only To as recipients; CC appears only in the header
Geo detection off when only CountryDB is set score.go:441 calcGeo requires CityDB
Debug string printed on every request score.go:457 With GeoLite2 on, the location and key go through the standard log.Print, bypassing Logger
Defaults written back into Config on the request path instance.go, score.go, geo.go Concurrent requests write the same fields, which go test -race reports as a data race
False rapid-move flag when alternating private and public IPs geo.go Private records sit at (0, 0); see Geo Detection
LoginFailure / NotFound404 count the request twice score.go Both run device identification again, so one request counts twice per minute

Reproduction: Panic on Redis Outage

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())
}

Actual output:

recovered: runtime error: invalid memory address or nil pointer dereference
中文