Skip to content

Commit 1f1121c

Browse files
authored
fix: add exceptions for internal IP addresses (#3608)
1 parent 9f1c8d1 commit 1f1121c

File tree

10 files changed

+492
-15
lines changed

10 files changed

+492
-15
lines changed

client/validator_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -273,13 +273,13 @@ func TestValidateIPRanges(t *testing.T) {
273273
reg := internal.NewRegistryMemory(t, c, &contextx.Static{C: c.Source(ctx)})
274274

275275
v := NewValidator(reg)
276-
c.MustSet(ctx, config.ViperKeyClientHTTPNoPrivateIPRanges, true)
276+
c.MustSet(ctx, config.KeyClientHTTPNoPrivateIPRanges, true)
277277
require.NoError(t, v.ValidateDynamicRegistration(ctx, &Client{}))
278278
require.ErrorContains(t, v.ValidateDynamicRegistration(ctx, &Client{JSONWebKeysURI: "https://localhost:1234"}), "invalid_client_metadata")
279279
require.ErrorContains(t, v.ValidateDynamicRegistration(ctx, &Client{BackChannelLogoutURI: "https://localhost:1234"}), "invalid_client_metadata")
280280
require.ErrorContains(t, v.ValidateDynamicRegistration(ctx, &Client{RequestURIs: []string{"https://google", "https://localhost:1234"}}), "invalid_client_metadata")
281281

282-
c.MustSet(ctx, config.ViperKeyClientHTTPNoPrivateIPRanges, false)
282+
c.MustSet(ctx, config.KeyClientHTTPNoPrivateIPRanges, false)
283283
require.NoError(t, v.ValidateDynamicRegistration(ctx, &Client{}))
284284
require.NoError(t, v.ValidateDynamicRegistration(ctx, &Client{JSONWebKeysURI: "https://localhost:1234"}))
285285
require.NoError(t, v.ValidateDynamicRegistration(ctx, &Client{BackChannelLogoutURI: "https://localhost:1234"}))

consent/strategy_default.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -460,7 +460,7 @@ func (s *DefaultStrategy) verifyAuthentication(
460460
return nil, fosite.ErrAccessDenied.WithHint("The login session cookie was not found or malformed.")
461461
}
462462

463-
loginSession.IdentityProviderSessionID = f.IdentityProviderSessionID
463+
loginSession.IdentityProviderSessionID = sqlxx.NullString(session.IdentityProviderSessionID)
464464
if err := s.r.ConsentManager().ConfirmLoginSession(ctx, loginSession, sessionID, time.Time(session.AuthenticatedAt), session.Subject, session.Remember); err != nil {
465465
return nil, err
466466
}

driver/config/provider.go

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import (
1111
"strings"
1212
"time"
1313

14+
"github.com/pkg/errors"
15+
1416
"github.com/ory/x/hasherx"
1517

1618
"github.com/gofrs/uuid"
@@ -50,7 +52,8 @@ const (
5052
KeySubjectTypesSupported = "oidc.subject_identifiers.supported_types"
5153
KeyDefaultClientScope = "oidc.dynamic_client_registration.default_scope"
5254
KeyDSN = "dsn"
53-
ViperKeyClientHTTPNoPrivateIPRanges = "clients.http.disallow_private_ip_ranges"
55+
KeyClientHTTPNoPrivateIPRanges = "clients.http.disallow_private_ip_ranges"
56+
KeyClientHTTPPrivateIPExceptionURLs = "clients.http.private_ip_exception_urls"
5457
KeyHasherAlgorithm = "oauth2.hashers.algorithm"
5558
KeyBCryptCost = "oauth2.hashers.bcrypt.cost"
5659
KeyPBKDF2Iterations = "oauth2.hashers.pbkdf2.iterations"
@@ -80,7 +83,8 @@ const (
8083
KeyPublicURL = "urls.self.public"
8184
KeyAdminURL = "urls.self.admin"
8285
KeyIssuerURL = "urls.self.issuer"
83-
KeyIdentityProviderAdminURL = "urls.identity_provider.admin_base_url"
86+
KeyIdentityProviderAdminURL = "urls.identity_provider.url"
87+
KeyIdentityProviderHeaders = "urls.identity_provider.headers"
8488
KeyAccessTokenStrategy = "strategies.access_token"
8589
KeyJWTScopeClaimStrategy = "strategies.jwt.scope_claim"
8690
KeyDBIgnoreUnknownTableColumns = "db.ignore_unknown_table_columns"
@@ -200,7 +204,11 @@ func (p *DefaultProvider) WellKnownKeys(ctx context.Context, include ...string)
200204
}
201205

202206
func (p *DefaultProvider) ClientHTTPNoPrivateIPRanges() bool {
203-
return p.getProvider(contextx.RootContext).Bool(ViperKeyClientHTTPNoPrivateIPRanges)
207+
return p.getProvider(contextx.RootContext).Bool(KeyClientHTTPNoPrivateIPRanges)
208+
}
209+
210+
func (p *DefaultProvider) ClientHTTPPrivateIPExceptionURLs() []string {
211+
return p.getProvider(contextx.RootContext).Strings(KeyClientHTTPPrivateIPExceptionURLs)
204212
}
205213

206214
func (p *DefaultProvider) AllowedTopLevelClaims(ctx context.Context) []string {
@@ -401,6 +409,21 @@ func (p *DefaultProvider) KratosAdminURL(ctx context.Context) (*url.URL, bool) {
401409

402410
return u, u != nil
403411
}
412+
func (p *DefaultProvider) KratosRequestHeader(ctx context.Context) http.Header {
413+
hh := map[string]string{}
414+
if err := p.getProvider(ctx).Unmarshal(KeyIdentityProviderHeaders, &hh); err != nil {
415+
p.l.WithError(errors.WithStack(err)).
416+
Errorf("Configuration value from key %s could not be decoded.", KeyIdentityProviderHeaders)
417+
return nil
418+
}
419+
420+
h := make(http.Header)
421+
for k, v := range hh {
422+
h.Set(k, v)
423+
}
424+
425+
return h
426+
}
404427

405428
func (p *DefaultProvider) OAuth2ClientRegistrationURL(ctx context.Context) *url.URL {
406429
return p.getProvider(ctx).RequestURIF(KeyOAuth2ClientRegistrationURL, new(url.URL))

driver/registry_base.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,11 @@ func (m *RegistryBase) HTTPClient(ctx context.Context, opts ...httpx.ResilientOp
363363
}
364364

365365
if m.Config().ClientHTTPNoPrivateIPRanges() {
366-
opts = append(opts, httpx.ResilientClientDisallowInternalIPs())
366+
opts = append(
367+
opts,
368+
httpx.ResilientClientDisallowInternalIPs(),
369+
httpx.ResilientClientAllowInternalIPRequestsTo(m.Config().ClientHTTPPrivateIPExceptionURLs()...),
370+
)
367371
}
368372
return httpx.NewResilientClient(opts...)
369373
}

driver/registry_base_test.go

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@ package driver
66
import (
77
"context"
88
"errors"
9+
"fmt"
910
"io"
11+
"net/http"
12+
"net/http/httptest"
1013
"testing"
1114

1215
"github.com/ory/x/randx"
@@ -33,7 +36,7 @@ func TestGetJWKSFetcherStrategyHostEnforcment(t *testing.T) {
3336
c := config.MustNew(context.Background(), l, configx.WithConfigFiles("../internal/.hydra.yaml"))
3437
c.MustSet(ctx, config.KeyDSN, "memory")
3538
c.MustSet(ctx, config.HSMEnabled, "false")
36-
c.MustSet(ctx, config.ViperKeyClientHTTPNoPrivateIPRanges, true)
39+
c.MustSet(ctx, config.KeyClientHTTPNoPrivateIPRanges, true)
3740

3841
registry, err := NewRegistryWithoutInit(c, l)
3942
require.NoError(t, err)
@@ -89,3 +92,33 @@ func TestRegistryBase_CookieStore_MaxAgeZero(t *testing.T) {
8992

9093
assert.Equal(t, cs.Options.MaxAge, 0)
9194
}
95+
96+
func TestRegistryBase_HTTPClient(t *testing.T) {
97+
ts := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, _ *http.Request) {
98+
writer.WriteHeader(http.StatusOK)
99+
}))
100+
defer ts.Close()
101+
102+
t.Setenv("CLIENTS_HTTP_PRIVATE_IP_EXCEPTION_URLS", fmt.Sprintf("[%q]", ts.URL+"/exception/*"))
103+
104+
ctx := context.Background()
105+
r := new(RegistryBase)
106+
r.WithConfig(config.MustNew(
107+
ctx,
108+
logrusx.New("", ""),
109+
configx.WithValues(map[string]interface{}{
110+
config.KeyClientHTTPNoPrivateIPRanges: true,
111+
}),
112+
))
113+
114+
t.Run("case=matches exception glob", func(t *testing.T) {
115+
res, err := r.HTTPClient(ctx).Get(ts.URL + "/exception/foo")
116+
require.NoError(t, err)
117+
assert.Equal(t, 200, res.StatusCode)
118+
})
119+
120+
t.Run("case=does not match exception glob", func(t *testing.T) {
121+
_, err := r.HTTPClient(ctx).Get(ts.URL + "/foo")
122+
require.Error(t, err)
123+
})
124+
}

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ require (
4242
github.com/ory/hydra-client-go/v2 v2.1.1
4343
github.com/ory/jsonschema/v3 v3.0.8
4444
github.com/ory/kratos-client-go v0.13.1
45-
github.com/ory/x v0.0.580
45+
github.com/ory/x v0.0.582-0.20230816082414-f1e6acad79b5
4646
github.com/pborman/uuid v1.2.1
4747
github.com/pkg/errors v0.9.1
4848
github.com/prometheus/client_golang v1.16.0

0 commit comments

Comments
 (0)