Restrict OAuth client branding URLs to http(s)

CIMD and registration accepted any URI scheme for client_uri and
logo_uri, so allowlisted metadata could surface javascript: links on
sign-in. Validate absolute http/https at ingest and only expose those
schemes in branding.

Signed-off-by: Bryan Frimin <bryan@probo.com>
This commit is contained in:
Bryan Frimin
2026-07-17 14:01:25 +02:00
parent 6da00604ed
commit e7df6f6b2a
10 changed files with 322 additions and 17 deletions

View File

@@ -43,6 +43,21 @@ func Parse(raw string) (URI, error) {
func (u URI) String() string { return string(u) }
// IsHTTP reports whether u is an absolute http or https URL.
func (u URI) IsHTTP() bool {
parsed, err := url.Parse(string(u))
if err != nil || parsed.Host == "" {
return false
}
switch parsed.Scheme {
case "http", "https":
return true
default:
return false
}
}
func (u *URI) UnmarshalText(text []byte) error {
parsed, err := Parse(string(text))
if err != nil {

View File

@@ -113,6 +113,32 @@ func TestParse(t *testing.T) {
}
}
func TestURIIsHTTP(t *testing.T) {
t.Parallel()
tests := []struct {
name string
uri URI
want bool
}{
{name: "https", uri: URI("https://example.com"), want: true},
{name: "http", uri: URI("http://localhost:3000"), want: true},
{name: "custom scheme", uri: URI("myapp://callback"), want: false},
{name: "javascript scheme", uri: URI("javascript://example.com/%0Aalert(1)"), want: false},
}
for _, tt := range tests {
t.Run(
tt.name,
func(t *testing.T) {
t.Parallel()
assert.Equal(t, tt.want, tt.uri.IsHTTP())
},
)
}
}
func TestURIUnmarshalText(t *testing.T) {
t.Parallel()