One might think that a function like this generates safe HTML because the argument is HTML-escaped.
function imageLink(url) {
const IMAGE_TEMPLATE = '<img src="{url}">';
return IMAGE_TEMPLATE.replace('{url}', htmlEscape(url));
}
But in fact there’s a very obscure cross-site scripting vulnerability here, abusing the $`
replacement sequence interpreted by String.prototype.replace
and .replaceAll
!
imageLink("$` onerror=alert(1) ")
//=> '<img src="<img src=" onerror=alert(1) ">'
To protect against this mistake, it would be nice to have an ESLint rule that forbids use of .replace
and .replaceAll
where the second argument isn’t a string literal or a function.
IMAGE_TEMPLATE.replace('{url}', htmlEscape(url))
IMAGE_TEMPLATE.replace('{url}', () => htmlEscape(url))
IMAGE_TEMPLATE.replace('{url}', "https://example.com")
No response
Pay now to fund the work behind this issue.
Get updates on progress being made.
Maintainer is rewarded once the issue is completed.
You're funding impactful open source efforts
You want to contribute to this effort
You want to get funding like this too