Merge commit from fork

Deny 0.0.0.0 when configured to deny loopback addresses
This commit is contained in:
Sergei Aleksandrovich
2025-01-27 21:58:52 +06:00
committed by GitHub
2 changed files with 131 additions and 1 deletions

View File

@@ -41,7 +41,7 @@ func VerifySourceNetwork(addr string) error {
return ErrInvalidSourceAddress
}
if !config.AllowLoopbackSourceAddresses && ip.IsLoopback() {
if !config.AllowLoopbackSourceAddresses && (ip.IsLoopback() || ip.IsUnspecified()) {
return ErrSourceAddressNotAllowed
}

130
security/source_test.go Normal file
View File

@@ -0,0 +1,130 @@
package security
import (
"testing"
"github.com/imgproxy/imgproxy/v3/config"
"github.com/stretchr/testify/assert"
)
func TestVerifySourceNetwork(t *testing.T) {
testCases := []struct {
name string
addr string
allowLoopback bool
allowLinkLocal bool
allowPrivate bool
expectedErr error
}{
{
name: "Invalid IP address",
addr: "not-an-ip",
allowLoopback: true,
allowLinkLocal: true,
allowPrivate: true,
expectedErr: ErrInvalidSourceAddress,
},
{
name: "Loopback local not allowed",
addr: "127.0.0.1",
allowLoopback: false,
allowLinkLocal: true,
allowPrivate: true,
expectedErr: ErrSourceAddressNotAllowed,
},
{
name: "Loopback local allowed",
addr: "127.0.0.1",
allowLoopback: true,
allowLinkLocal: true,
allowPrivate: true,
expectedErr: nil,
},
{
name: "Unspecified (0.0.0.0) not allowed",
addr: "0.0.0.0",
allowLoopback: false,
allowLinkLocal: true,
allowPrivate: true,
expectedErr: ErrSourceAddressNotAllowed,
},
{
name: "Link local unicast not allowed",
addr: "169.254.0.1",
allowLoopback: true,
allowLinkLocal: false,
allowPrivate: true,
expectedErr: ErrSourceAddressNotAllowed,
},
{
name: "Link local unicast allowed",
addr: "169.254.0.1",
allowLoopback: true,
allowLinkLocal: true,
allowPrivate: true,
expectedErr: nil,
},
{
name: "Private address not allowed",
addr: "192.168.0.1",
allowLoopback: true,
allowLinkLocal: true,
allowPrivate: false,
expectedErr: ErrSourceAddressNotAllowed,
},
{
name: "Private address allowed",
addr: "192.168.0.1",
allowLoopback: true,
allowLinkLocal: true,
allowPrivate: true,
expectedErr: nil,
},
{
name: "Global unicast should be allowed",
addr: "8.8.8.8",
allowLoopback: false,
allowLinkLocal: false,
allowPrivate: false,
expectedErr: nil,
},
{
name: "Port in address with global IP",
addr: "8.8.8.8:8080",
allowLoopback: false,
allowLinkLocal: false,
allowPrivate: false,
expectedErr: nil,
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
// Backup original config
originalLoopback := config.AllowLoopbackSourceAddresses
originalLinkLocal := config.AllowLinkLocalSourceAddresses
originalPrivate := config.AllowPrivateSourceAddresses
// Restore original config after test
defer func() {
config.AllowLoopbackSourceAddresses = originalLoopback
config.AllowLinkLocalSourceAddresses = originalLinkLocal
config.AllowPrivateSourceAddresses = originalPrivate
}()
// Override config for the test
config.AllowLoopbackSourceAddresses = tc.allowLoopback
config.AllowLinkLocalSourceAddresses = tc.allowLinkLocal
config.AllowPrivateSourceAddresses = tc.allowPrivate
err := VerifySourceNetwork(tc.addr)
if tc.expectedErr != nil {
assert.Error(t, err)
assert.Equal(t, tc.expectedErr, err)
} else {
assert.NoError(t, err)
}
})
}
}