Skip to content

Commit de46c08

Browse files
committed
feat: support ip exceptions
1 parent fec6772 commit de46c08

File tree

4 files changed

+28
-1
lines changed

4 files changed

+28
-1
lines changed

driver/config/config.go

+5
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ const (
173173
ViperKeyWebAuthnRPIcon = "selfservice.methods.webauthn.config.rp.issuer"
174174
ViperKeyWebAuthnPasswordless = "selfservice.methods.webauthn.config.passwordless"
175175
ViperKeyClientHTTPNoPrivateIPRanges = "clients.http.disallow_private_ip_ranges"
176+
ViperKeyClientHTTPPrivateIPExceptionURLs = "clients.http.private_ip_exception_urls"
176177
ViperKeyVersion = "version"
177178
)
178179

@@ -602,6 +603,10 @@ func (p *Config) ClientHTTPNoPrivateIPRanges(ctx context.Context) bool {
602603
return p.GetProvider(ctx).Bool(ViperKeyClientHTTPNoPrivateIPRanges)
603604
}
604605

606+
func (p *Config) ClientHTTPPrivateIPExceptionURLs(ctx context.Context) []string {
607+
return p.GetProvider(ctx).Strings(ViperKeyClientHTTPPrivateIPExceptionURLs)
608+
}
609+
605610
func (p *Config) SelfServiceFlowRegistrationEnabled(ctx context.Context) bool {
606611
return p.GetProvider(ctx).Bool(ViperKeySelfServiceRegistrationEnabled)
607612
}

driver/config/config_test.go

+5
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,13 @@ func TestViperProvider(t *testing.T) {
5757

5858
t.Run("group=client config", func(t *testing.T) {
5959
assert.False(t, p.ClientHTTPNoPrivateIPRanges(ctx), "Should not have private IP ranges disabled per default")
60+
assert.Equal(t, []string{}, p.ClientHTTPPrivateIPExceptionURLs(ctx), "Should return the correct exceptions")
61+
6062
p.MustSet(ctx, config.ViperKeyClientHTTPNoPrivateIPRanges, true)
6163
assert.True(t, p.ClientHTTPNoPrivateIPRanges(ctx), "Should disallow private IP ranges if set")
64+
65+
p.MustSet(ctx, config.ViperKeyClientHTTPPrivateIPExceptionURLs, []string{"https://foobar.com/baz"})
66+
assert.Equal(t, []string{"https://foobar.com/baz"}, p.ClientHTTPPrivateIPExceptionURLs(ctx), "Should return the correct exceptions")
6267
})
6368

6469
t.Run("group=urls", func(t *testing.T) {

driver/registry_default.go

+6-1
Original file line numberDiff line numberDiff line change
@@ -718,7 +718,12 @@ func (m *RegistryDefault) HTTPClient(ctx context.Context, opts ...httpx.Resilien
718718

719719
// One of the few exceptions, this usually should not be hot reloaded.
720720
if m.Config().ClientHTTPNoPrivateIPRanges(contextx.RootContext) {
721-
opts = append(opts, httpx.ResilientClientDisallowInternalIPs())
721+
opts = append(
722+
opts,
723+
httpx.ResilientClientDisallowInternalIPs(),
724+
// One of the few exceptions, this usually should not be hot reloaded.
725+
httpx.ResilientClientAllowInternalIPRequestsTo(m.Config().ClientHTTPPrivateIPExceptionURLs(contextx.RootContext)...),
726+
)
722727
}
723728
return httpx.NewResilientClient(opts...)
724729
}

selfservice/hook/web_hook_integration_test.go

+12
Original file line numberDiff line numberDiff line change
@@ -726,6 +726,7 @@ func TestDisallowPrivateIPRanges(t *testing.T) {
726726
ctx := context.Background()
727727
conf, reg := internal.NewFastRegistryWithMocks(t)
728728
conf.MustSet(ctx, config.ViperKeyClientHTTPNoPrivateIPRanges, true)
729+
conf.MustSet(ctx, config.ViperKeyClientHTTPPrivateIPExceptionURLs, []string{"http://localhost/exception"})
729730
logger := logrusx.New("kratos", "test")
730731
whDeps := x.SimpleLoggerWithClient{L: logger, C: reg.HTTPClient(context.Background()), T: otelx.NewNoop(logger, conf.Tracing(ctx))}
731732

@@ -748,8 +749,19 @@ func TestDisallowPrivateIPRanges(t *testing.T) {
748749
err := wh.ExecuteLoginPostHook(nil, req, node.DefaultGroup, f, s)
749750
require.Error(t, err)
750751
require.Contains(t, err.Error(), "ip 127.0.0.1 is in the 127.0.0.0/8 range")
752+
})
751753

754+
t.Run("allowed to call exempt url", func(t *testing.T) {
755+
wh := hook.NewWebHook(&whDeps, json.RawMessage(`{
756+
"url": "http://localhost/exception",
757+
"method": "GET",
758+
"body": "file://stub/test_body.jsonnet"
759+
}`))
760+
err := wh.ExecuteLoginPostHook(nil, req, node.DefaultGroup, f, s)
761+
require.Error(t, err, "the target does not exist and we still receive an error")
762+
require.NotContains(t, err.Error(), "ip 127.0.0.1 is in the 127.0.0.0/8 range", "but the error is not related to the IP range.")
752763
})
764+
753765
t.Run("not allowed to load from source", func(t *testing.T) {
754766
req := &http.Request{
755767
Header: map[string][]string{"Some-Header": {"Some-Value"}},

0 commit comments

Comments
 (0)