Skip to content

Commit ea43e42

Browse files
committed
fix(platform-server): enforce allowOriginChange for protocol-relative urls
resolveUrl routes every return path through the origin-change safety check except the protocol-relative branch, which returns the resolved URL directly. A caller passing {allowProtocolRelative: true, allowOriginChange: false} could then resolve a //host input to a different origin, ignoring the allowOriginChange: false it asked for. Re-check the resolved origin in that branch so the option is honored consistently.
1 parent f48d276 commit ea43e42

2 files changed

Lines changed: 34 additions & 1 deletion

File tree

packages/platform-server/src/url.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,16 @@ export function resolveUrl(
102102
);
103103
}
104104

105-
return new URL(urlStr, origin);
105+
resolved = new URL(urlStr, origin);
106+
107+
// A protocol-relative URL inherits the base scheme, so the only origin-sensitive
108+
// change it can introduce is the host. Honor `allowOriginChange` here too, the same
109+
// way every other return path does.
110+
if (!allowOriginChange && resolved.origin !== originUrl.origin) {
111+
throwSuspiciousUrlError(urlStr);
112+
}
113+
114+
return resolved;
106115
}
107116

108117
resolved = new URL(urlStr, origin);

packages/platform-server/test/url_spec.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,30 @@ describe('resolveUrl', () => {
4848
expect(url.href).toBe('http://test.com/other-path');
4949
});
5050

51+
it('should throw for a protocol-relative url that changes origin when allowOriginChange is false', () => {
52+
expect(() =>
53+
resolveUrl('//evil.com/path', 'http://test.com', {
54+
allowProtocolRelative: true,
55+
allowOriginChange: false,
56+
}),
57+
).toThrowError(/NG05703/);
58+
});
59+
60+
it('should resolve a same-origin protocol-relative url when allowOriginChange is false', () => {
61+
const url = resolveUrl('//test.com/other-path', 'http://test.com', {
62+
allowProtocolRelative: true,
63+
allowOriginChange: false,
64+
});
65+
expect(url.href).toBe('http://test.com/other-path');
66+
});
67+
68+
it('should resolve a cross-origin protocol-relative url when origin changes are allowed', () => {
69+
const url = resolveUrl('//other.com/path', 'http://test.com', {
70+
allowProtocolRelative: true,
71+
});
72+
expect(url.origin).toBe('http://other.com');
73+
});
74+
5175
it('should throw an error for malformed absolute URLs', () => {
5276
const malformedUrls = [
5377
'http://evil.com:80:80/path',

0 commit comments

Comments
 (0)