fix(19.7): RB-IN-01 the My account URL check refuses control characters

Browsers strip tab and newline from URLs, so "/\t/host" passed the
SPA's same-origin check and resolved off-site. The check now refuses any
ASCII control character first, as Go's url.Parse does on the server, and
an absolute URL must parse with a host, so both sides apply one rule.
This commit is contained in:
2026-10-23 20:31:28 +02:00
parent a5ce43f211
commit 633d45082e
2 changed files with 29 additions and 5 deletions

View File

@@ -23,14 +23,23 @@ const running = ref('')
const links = ref<Record<string, string>>({})
/**
* The URL when it may be rendered and opened: an absolute http(s) URL or a
* same-origin path (one leading "/"), else ''. The server applies the same
* rule; this keeps a javascript: or data: URL out of href and window.open
* even if one gets through.
* The URL when it may be rendered and opened: an absolute http(s) URL with a
* host or a same-origin path (one leading "/"), else ''. The server applies
* the same rule (Go's url.Parse refuses control characters); this keeps a
* javascript: or data: URL out of href and window.open even if one gets
* through. A control character is refused first: browsers strip tab and
* newline, so "/\t/host" would otherwise resolve to //host, off-site.
*/
function safeUrl(u: string): string {
if (/[\u0000-\u001f\u007f]/.test(u)) {
return ''
}
if (/^https?:\/\//i.test(u)) {
return u
try {
return new URL(u).host !== '' ? u : ''
} catch {
return ''
}
}
if (u.startsWith('/') && !u.startsWith('//') && !u.startsWith('/\\')) {
return u