Skip to content

Commit

Permalink
🩹 Fix: Properly handle error of "net.ParseCIDR" in "(*App).handleTrus…
Browse files Browse the repository at this point in the history
…tedProxy" (#2243)

* app: do not use empty *net.IPNet in case of an error of "net.ParseCIDR"

* app: expose error returned by "net.ParseCIDR"

* ctx: do not repeatedly call method in loop

* ctx: add test for "IsProxyTrusted" func
  • Loading branch information
leonklingele committed Dec 5, 2022
1 parent 077a5dc commit d9d2153
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 8 deletions.
7 changes: 3 additions & 4 deletions app.go
Expand Up @@ -585,12 +585,11 @@ func New(config ...Config) *App {
func (app *App) handleTrustedProxy(ipAddress string) {
if strings.Contains(ipAddress, "/") {
_, ipNet, err := net.ParseCIDR(ipAddress)

if err != nil {
fmt.Printf("[Warning] IP range `%s` could not be parsed. \n", ipAddress)
fmt.Printf("[Warning] IP range %q could not be parsed: %v\n", ipAddress, err)
} else {
app.config.trustedProxyRanges = append(app.config.trustedProxyRanges, ipNet)
}

app.config.trustedProxyRanges = append(app.config.trustedProxyRanges, ipNet)
} else {
app.config.trustedProxiesMap[ipAddress] = struct{}{}
}
Expand Down
9 changes: 5 additions & 4 deletions ctx.go
Expand Up @@ -1747,13 +1747,14 @@ func (c *Ctx) IsProxyTrusted() bool {
return true
}

_, trusted := c.app.config.trustedProxiesMap[c.fasthttp.RemoteIP().String()]
if trusted {
return trusted
ip := c.fasthttp.RemoteIP()

if _, trusted := c.app.config.trustedProxiesMap[ip.String()]; trusted {
return true
}

for _, ipNet := range c.app.config.trustedProxyRanges {
if ipNet.Contains(c.fasthttp.RemoteIP()) {
if ipNet.Contains(ip) {
return true
}
}
Expand Down
99 changes: 99 additions & 0 deletions ctx_test.go
Expand Up @@ -1023,6 +1023,105 @@ func Test_Ctx_Get(t *testing.T) {
utils.AssertEqual(t, "default", c.Get("unknown", "default"))
}

// go test -run Test_Ctx_IsProxyTrusted
func Test_Ctx_IsProxyTrusted(t *testing.T) {
t.Parallel()

{
app := New()
c := app.AcquireCtx(&fasthttp.RequestCtx{})
defer app.ReleaseCtx(c)
utils.AssertEqual(t, true, c.IsProxyTrusted())
}
{
app := New(Config{
EnableTrustedProxyCheck: false,
})
c := app.AcquireCtx(&fasthttp.RequestCtx{})
defer app.ReleaseCtx(c)
utils.AssertEqual(t, true, c.IsProxyTrusted())
}

{
app := New(Config{
EnableTrustedProxyCheck: true,
})
c := app.AcquireCtx(&fasthttp.RequestCtx{})
defer app.ReleaseCtx(c)
utils.AssertEqual(t, false, c.IsProxyTrusted())
}
{
app := New(Config{
EnableTrustedProxyCheck: true,

TrustedProxies: []string{},
})
c := app.AcquireCtx(&fasthttp.RequestCtx{})
defer app.ReleaseCtx(c)
utils.AssertEqual(t, false, c.IsProxyTrusted())
}
{
app := New(Config{
EnableTrustedProxyCheck: true,

TrustedProxies: []string{
"127.0.0.1",
},
})
c := app.AcquireCtx(&fasthttp.RequestCtx{})
defer app.ReleaseCtx(c)
utils.AssertEqual(t, false, c.IsProxyTrusted())
}
{
app := New(Config{
EnableTrustedProxyCheck: true,

TrustedProxies: []string{
"127.0.0.1/8",
},
})
c := app.AcquireCtx(&fasthttp.RequestCtx{})
defer app.ReleaseCtx(c)
utils.AssertEqual(t, false, c.IsProxyTrusted())
}
{
app := New(Config{
EnableTrustedProxyCheck: true,

TrustedProxies: []string{
"0.0.0.0",
},
})
c := app.AcquireCtx(&fasthttp.RequestCtx{})
defer app.ReleaseCtx(c)
utils.AssertEqual(t, true, c.IsProxyTrusted())
}
{
app := New(Config{
EnableTrustedProxyCheck: true,

TrustedProxies: []string{
"0.0.0.1/31",
},
})
c := app.AcquireCtx(&fasthttp.RequestCtx{})
defer app.ReleaseCtx(c)
utils.AssertEqual(t, true, c.IsProxyTrusted())
}
{
app := New(Config{
EnableTrustedProxyCheck: true,

TrustedProxies: []string{
"0.0.0.1/31junk",
},
})
c := app.AcquireCtx(&fasthttp.RequestCtx{})
defer app.ReleaseCtx(c)
utils.AssertEqual(t, false, c.IsProxyTrusted())
}
}

// go test -run Test_Ctx_Hostname
func Test_Ctx_Hostname(t *testing.T) {
t.Parallel()
Expand Down

0 comments on commit d9d2153

Please sign in to comment.