Skip to content

Commit e5c55a5

Browse files
committed
Allow private-use URI schemes in redirect URI validation (#356)
1 parent 2659e49 commit e5c55a5

2 files changed

Lines changed: 24 additions & 4 deletions

File tree

src/Forms/ClientForm.php

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,12 @@ class ClientForm extends Form
3333
protected const string TYPE_ARRAY = 'array';
3434

3535
/**
36-
* RFC3986. AppendixB. Parsing a URI Reference with a Regular Expression.
37-
* From v6.*, the regex was modified to allow URI without host, to support adding entries like
38-
* `openid-credential-offer://`
36+
* URI with an RFC3986 compliant scheme, followed by any non-whitespace characters. Since the scheme may be
37+
* followed by an empty authority component, entries like `openid-credential-offer://` (OID4VCI) or
38+
* `app.example:///oauth-callback` (RFC8252 private-use URI scheme) are allowed. Scheme alone (`https:`) is not.
39+
* Fragment component is not allowed, since response parameters are appended as query (OIDC Core, 3.1.2.1).
3940
*/
40-
final public const string REGEX_URI = '/^[^:]+:\/\/?([^\s\/$.?#].[^\s]*)?$/';
41+
final public const string REGEX_URI = '/^[a-zA-Z][a-zA-Z0-9+\-.]*:(\/\/[^\s#]*|[^\s#]+)$/';
4142

4243
/**
4344
* Must have http:// or https:// scheme, and at least one 'domain.top-level-domain' pair, or more subdomains.

tests/unit/src/Forms/ClientFormTest.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,25 @@ public static function redirectUriProvider(): array
191191
['openid-credential-offer://', true],
192192
['foo://', true],
193193
['https://', true],
194+
195+
// Private-use URI schemes for native apps (RFC8252), with empty authority component
196+
['app.immich:///oauth-callback', true],
197+
['com.example.app:/oauth2redirect/example-provider', true],
198+
['com.example.app:oauth2redirect', true],
199+
['urn:ietf:wg:oauth:2.0:oob', true],
200+
['x://a', true],
201+
202+
// Scheme must comply with RFC3986, and no whitespace is allowed
203+
['1foo://example.com', false],
204+
['foo bar://example.com', false],
205+
[' https://example.com', false],
206+
['https://example.com/foo bar', false],
207+
['://example.com', false],
208+
209+
// Fragment component is not allowed (OIDC Core, 3.1.2.1)
210+
['https://example.com/foo#bar', false],
211+
['com.example.app:#oauth2redirect', false],
212+
['app.immich:///oauth-callback#foo', false],
194213
];
195214
}
196215

0 commit comments

Comments
 (0)