Skip to content

Commit 007e224

Browse files
hperlalnr
andauthored
fix: tos_uri validation (#3945)
Contributes to ory-corp/cloud#7395 --------- Co-authored-by: Arne Luenser <arne.luenser@ory.sh>
1 parent 6ae0552 commit 007e224

File tree

3 files changed

+29
-8
lines changed

3 files changed

+29
-8
lines changed

client/sdk_test.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ func createTestClient(prefix string) hydra.OAuth2Client {
4343
Owner: pointerx.Ptr(prefix + "an-owner"),
4444
PolicyUri: pointerx.Ptr(prefix + "policy-uri"),
4545
Scope: pointerx.Ptr(prefix + "foo bar baz"),
46-
TosUri: pointerx.Ptr(prefix + "tos-uri"),
46+
TosUri: pointerx.Ptr("https://example.org/" + prefix + "tos"),
4747
ResponseTypes: []string{prefix + "id_token", prefix + "code"},
4848
RedirectUris: []string{"https://" + prefix + "redirect-url", "https://" + prefix + "redirect-uri"},
4949
ClientSecretExpiresAt: pointerx.Ptr[int64](0),
@@ -95,12 +95,15 @@ func TestClientSDK(t *testing.T) {
9595
// createClient.SecretExpiresAt = 10
9696

9797
// returned client is correct on Create
98-
result, _, err := c.OAuth2API.CreateOAuth2Client(ctx).OAuth2Client(createClient).Execute()
99-
require.NoError(t, err)
98+
result, res, err := c.OAuth2API.CreateOAuth2Client(ctx).OAuth2Client(createClient).Execute()
99+
if !assert.NoError(t, err) {
100+
t.Fatalf("error: %s", ioutilx.MustReadAll(res.Body))
101+
}
100102
assert.NotEmpty(t, result.UpdatedAt)
101103
assert.NotEmpty(t, result.CreatedAt)
102104
assert.NotEmpty(t, result.RegistrationAccessToken)
103105
assert.NotEmpty(t, result.RegistrationClientUri)
106+
assert.NotEmpty(t, *result.TosUri)
104107
assert.NotEmpty(t, result.ClientId)
105108
createClient.ClientId = result.ClientId
106109

client/validator.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,18 @@ func (v *Validator) Validate(ctx context.Context, c *Client) error {
8989
}
9090
}
9191

92+
if c.TermsOfServiceURI != "" {
93+
u, err := url.ParseRequestURI(c.TermsOfServiceURI)
94+
if err != nil {
95+
return errorsx.WithStack(ErrInvalidClientMetadata.WithHint("Field tos_uri must be a valid URI."))
96+
}
97+
98+
if u.Scheme != "https" && u.Scheme != "http" {
99+
return errorsx.WithStack(ErrInvalidClientMetadata.WithHintf("tos_uri %s must use https:// or http:// as HTTP scheme.", c.TermsOfServiceURI))
100+
}
101+
102+
}
103+
92104
if len(c.Secret) > 0 && len(c.Secret) < 6 {
93105
return errorsx.WithStack(ErrInvalidClientMetadata.WithHint("Field client_secret must contain a secret that is at least 6 characters long."))
94106
}

client/validator_test.go

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,6 @@ func TestValidate(t *testing.T) {
3838
reg := testhelpers.NewRegistryMemory(t, c, &contextx.Static{C: c.Source(ctx)})
3939
v := NewValidator(reg)
4040

41-
testCtx := context.TODO()
42-
4341
dec := json.NewDecoder(strings.NewReader(validJWKS))
4442
dec.DisallowUnknownFields()
4543
var goodJWKS jose.JSONWebKeySet
@@ -130,6 +128,14 @@ func TestValidate(t *testing.T) {
130128
assert.Equal(t, []string{"https://foo/"}, []string(c.PostLogoutRedirectURIs))
131129
},
132130
},
131+
{
132+
in: &Client{ID: "foo", TermsOfServiceURI: "https://example.org"},
133+
assertErr: assert.NoError,
134+
},
135+
{
136+
in: &Client{ID: "foo", TermsOfServiceURI: "javascript:alert('XSS')"},
137+
assertErr: assert.Error,
138+
},
133139
{
134140
in: &Client{ID: "foo"},
135141
check: func(t *testing.T, c *Client) {
@@ -164,7 +170,7 @@ func TestValidate(t *testing.T) {
164170
return v
165171
}
166172
}
167-
err := tc.v(t).Validate(testCtx, tc.in)
173+
err := tc.v(t).Validate(ctx, tc.in)
168174
if tc.assertErr != nil {
169175
tc.assertErr(t, err)
170176
} else {
@@ -180,7 +186,7 @@ type fakeHTTP struct {
180186
c *http.Client
181187
}
182188

183-
func (f *fakeHTTP) HTTPClient(ctx context.Context, opts ...httpx.ResilientOptions) *retryablehttp.Client {
189+
func (f *fakeHTTP) HTTPClient(_ context.Context, opts ...httpx.ResilientOptions) *retryablehttp.Client {
184190
c := httpx.NewResilientClient(opts...)
185191
c.HTTPClient = f.c
186192
return c
@@ -191,7 +197,7 @@ func TestValidateSectorIdentifierURL(t *testing.T) {
191197
var payload string
192198

193199
var h http.HandlerFunc = func(w http.ResponseWriter, r *http.Request) {
194-
w.Write([]byte(payload))
200+
_, _ = w.Write([]byte(payload))
195201
}
196202
ts := httptest.NewTLSServer(h)
197203
defer ts.Close()

0 commit comments

Comments
 (0)