fix(middlewares): failure to detect remote ip (#5339)
This fixes an edge case where the RemoteIP detection could safely fail with an error, and instead defaults to the TCP packet information. Signed-off-by: James Elliott <james-d-elliott@users.noreply.github.com>pull/5340/head
parent
c3cc4061b8
commit
34ec813370
|
@ -452,12 +452,13 @@ func (ctx *AutheliaCtx) SetJSONBody(value any) error {
|
|||
|
||||
// RemoteIP return the remote IP taking X-Forwarded-For header into account if provided.
|
||||
func (ctx *AutheliaCtx) RemoteIP() net.IP {
|
||||
XForwardedFor := ctx.Request.Header.PeekBytes(headerXForwardedFor)
|
||||
if XForwardedFor != nil {
|
||||
ips := strings.Split(string(XForwardedFor), ",")
|
||||
if header := ctx.Request.Header.PeekBytes(headerXForwardedFor); len(header) != 0 {
|
||||
ips := strings.SplitN(string(header), ",", 2)
|
||||
|
||||
if len(ips) > 0 {
|
||||
return net.ParseIP(strings.Trim(ips[0], " "))
|
||||
if len(ips) != 0 {
|
||||
if ip := net.ParseIP(strings.Trim(ips[0], " ")); ip != nil {
|
||||
return ip
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package middlewares_test
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/url"
|
||||
"testing"
|
||||
|
||||
|
@ -17,6 +18,37 @@ import (
|
|||
"github.com/authelia/authelia/v4/internal/session"
|
||||
)
|
||||
|
||||
func TestAutheliaCtx_RemoteIP(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
have []byte
|
||||
expected net.IP
|
||||
}{
|
||||
{"ShouldDefaultToRemoteAddr", nil, net.ParseIP("127.0.0.127")},
|
||||
{"ShouldParseProperlyFormattedXFFWithIPv4", []byte("192.168.1.1, 127.0.0.1"), net.ParseIP("192.168.1.1")},
|
||||
{"ShouldParseProperlyFormattedXFFWithIPv6", []byte("2001:db8:85a3:8d3:1319:8a2e:370:7348, 127.0.0.1"), net.ParseIP("2001:db8:85a3:8d3:1319:8a2e:370:7348")},
|
||||
{"ShouldFallbackToRemoteAddrOnImproperlyFormattedXFFWithIPv6", []byte("[2001:db8:85a3:8d3:1319:8a2e:370:7348], 127.0.0.1"), net.ParseIP("127.0.0.127")},
|
||||
{"ShouldFallbackToRemoteAddrOnBlankXFFHeader", []byte(""), net.ParseIP("127.0.0.127")},
|
||||
{"ShouldFallbackToRemoteAddrOnBlankXFFEntry", []byte(", 127.0.0.1"), net.ParseIP("127.0.0.127")},
|
||||
{"ShouldFallbackToRemoteAddrOnBadXFFEntry", []byte("abc, 127.0.0.1"), net.ParseIP("127.0.0.127")},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
mock := mocks.NewMockAutheliaCtx(t)
|
||||
defer mock.Close()
|
||||
|
||||
mock.Ctx.SetRemoteAddr(&net.TCPAddr{Port: 80, IP: net.ParseIP("127.0.0.127")})
|
||||
|
||||
if tc.have != nil {
|
||||
mock.Ctx.RequestCtx.Request.Header.SetBytesV(fasthttp.HeaderXForwardedFor, tc.have)
|
||||
}
|
||||
|
||||
assert.Equal(t, tc.expected, mock.Ctx.RemoteIP())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestContentTypes(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
|
|
Loading…
Reference in New Issue