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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user