mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
fix(platform-server): avoid stripping unicode whitespace during url resolution
Avoid trimming urlStr with String.prototype.trim() in resolveUrl to ensure URL parsing and resolution align with the WHATWG URL standard.
This commit is contained in:
@@ -57,8 +57,6 @@ export function resolveUrl(
|
||||
return originUrl || null;
|
||||
}
|
||||
|
||||
urlStr = urlStr.trim();
|
||||
|
||||
// Fast-path: if the URL is a valid, standard absolute URL, parse and return it immediately.
|
||||
let resolved: URL | undefined;
|
||||
try {
|
||||
|
||||
@@ -1582,6 +1582,17 @@ class HiddenModule {}
|
||||
});
|
||||
});
|
||||
|
||||
it('should resolve non-breaking space prefixed URLs as relative paths on the same origin', async () => {
|
||||
ref.injector.get(NgZone).run(() => {
|
||||
http.get('\u00A0//attacker.example/collect').subscribe((body) => {
|
||||
expect(body).toEqual('success!');
|
||||
});
|
||||
mock
|
||||
.expectOne('http://localhost:4000/%C2%A0//attacker.example/collect')
|
||||
.flush('success!');
|
||||
});
|
||||
});
|
||||
|
||||
it('should reject backslash bypass SSRF attempts in relative requests and throw a suspicious origin error', async () => {
|
||||
const badUrls = [
|
||||
'/\\attacker.com',
|
||||
|
||||
@@ -68,6 +68,22 @@ describe('resolveUrl', () => {
|
||||
const url = 'ht\ntp://evil.com/path';
|
||||
expect(() => resolveUrl(url, 'http://test.com')).toThrowError(/NG05703/);
|
||||
});
|
||||
|
||||
it('should not trim unicode whitespace into protocol-relative URLs', () => {
|
||||
const urls = ['\u00A0//attacker.example/collect', '\uFEFF//attacker.example/collect'];
|
||||
|
||||
for (const urlStr of urls) {
|
||||
const urlWithProtocolRelative = resolveUrl(urlStr, 'http://test.com', {
|
||||
allowProtocolRelative: true,
|
||||
});
|
||||
expect(urlWithProtocolRelative.origin).toBe('http://test.com');
|
||||
expect(urlWithProtocolRelative.pathname).toContain('//attacker.example/collect');
|
||||
|
||||
const urlWithoutProtocolRelative = resolveUrl(urlStr, 'http://test.com');
|
||||
expect(urlWithoutProtocolRelative.origin).toBe('http://test.com');
|
||||
expect(urlWithoutProtocolRelative.pathname).toContain('//attacker.example/collect');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('without origin', () => {
|
||||
@@ -76,6 +92,7 @@ describe('resolveUrl', () => {
|
||||
expect(resolveUrl('deep/path')).toBeNull();
|
||||
expect(resolveUrl('/\\attacker.com/deep/path')).toBeNull();
|
||||
expect(resolveUrl('\\\\attacker.com/deep/path')).toBeNull();
|
||||
expect(resolveUrl('\u00A0//attacker.com/deep/path')).toBeNull();
|
||||
});
|
||||
|
||||
it('should parse valid absolute URLs', () => {
|
||||
|
||||
Reference in New Issue
Block a user