Skip to content

Commit 7c67546

Browse files
matyasfgit-nandor
authored andcommitted
refactor(ui-utils): disallow some weird control characters in safeHref
1 parent 9fb945c commit 7c67546

1 file changed

Lines changed: 13 additions & 4 deletions

File tree

packages/ui-utils/src/safeHref.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,15 +48,24 @@ const SAFE_SCHEMES = [
4848
'callto:',
4949
'cid:',
5050
'xmpp:',
51+
'matrix:',
5152
'webcal:',
5253
'feed:',
5354
'geo:'
5455
]
5556

57+
/**
58+
* Remove all control characters (e.g. line break, tab, escape) and trim the
59+
* string
60+
*/
61+
function normalizeValue(value: string) {
62+
// eslint-disable-next-line no-control-regex
63+
return value.replace(/[\u0000-\u001F\u007F]/g, '').trim()
64+
}
65+
5666
// Extract the scheme from a URL-ish value, or `null` if it has none.
5767
function extractScheme(value: string): string | null {
58-
const normalized = value.replace(/[\t\n\r]/g, '').trim()
59-
const schemeMatch = normalized.match(/^([a-zA-Z][a-zA-Z0-9+.-]*):/)
68+
const schemeMatch = normalizeValue(value).match(/^([a-zA-Z][a-zA-Z0-9+.-]*):/)
6069
return schemeMatch ? schemeMatch[1].toLowerCase() + ':' : null
6170
}
6271

@@ -74,7 +83,7 @@ const DATA_URI_TAGS: ReadonlyArray<[string, string]> = [
7483
// isn't, validate the scheme directly so server-rendered components don't
7584
// silently drop every href.
7685
function ssrSafeHref(value: string, tag: string, attr: string): boolean {
77-
const normalized = value.replace(/[\t\n\r]/g, '').trim()
86+
const normalized = normalizeValue(value)
7887
if (normalized === '') return true
7988
const firstChar = normalized.charAt(0)
8089
if (firstChar === '#' || firstChar === '/' || firstChar === '?') return true
@@ -110,7 +119,7 @@ function safeHref(
110119
tag: string,
111120
attr: string
112121
): string | undefined {
113-
if (href == null) return undefined
122+
if (href == null || typeof href === 'undefined') return undefined
114123
const value = String(href)
115124

116125
// Pre-check our scheme allowlist before DOMPurify, since DOMPurify's default

0 commit comments

Comments
 (0)