stripUnsafeHtml
Removes script-like tags, event handlers and quoted javascript: links from HTML you already trust; it is not a sanitizer for untrusted input.
import { stripUnsafeHtml } from '@salla.sa/twilight-theme-engine/utils';In plain words
Some Salla translations contain a little HTML, such as <b> around an amount. To show that formatting, React needs dangerouslySetInnerHTML, which inserts HTML exactly as given. stripUnsafeHtml(html) first removes the obvious dangerous parts: <script>, <iframe>, form fields, attributes like onclick="…" and href="javascript:…" links.
It is a quick filter built from regular expressions, not a complete HTML sanitizer. Use it only on HTML from a source you trust, such as Salla's own translations.
Signature
function stripUnsafeHtml(html: string): string
Try it live
- input
<p onclick="steal()">Hi</p>- stripUnsafeHtml(input)
<p>Hi</p>(changed)
import { useTranslation } from '@salla.sa/twilight-theme-engine/i18n';
import { stripUnsafeHtml } from '@salla.sa/twilight-theme-engine/utils';
// Only for HTML from a trusted source, such as Salla's own translations.
export function FreeShippingAlert() {
const { t } = useTranslation();
const html = t('pages.cart.free_shipping_alert').replace(':amount', '50 SAR');
return <span dangerouslySetInnerHTML={{ __html: stripUnsafeHtml(html) }} />;
}
Example
import { useTranslation } from '@salla.sa/twilight-theme-engine/i18n';
import { stripUnsafeHtml } from '@salla.sa/twilight-theme-engine/utils';
export function FreeShippingAlert({ remaining }: { remaining: string }) {
const { t } = useTranslation();
// A Salla translation: "Get <b> a free shipping</b> when you add <b>:amount</b> to cart"
const html = t('pages.cart.free_shipping_alert').replace(':amount', remaining);
return <span dangerouslySetInnerHTML={{ __html: stripUnsafeHtml(html) }} />;
}
How it behaves
Tags removed, opening and closing:
script,iframe,object,embed,form,input,textarea,select,button,link,metaandbase, in any letter case. Only the tags go; text between them stays.Attributes removed: any
on…=handler preceded by whitespace, with a quoted or unquoted value; and a wholehref="javascript:…"orhref='javascript:…'attribute.Everything else is kept,
<style>,<svg>,<img>anddata:URLs included.CartSummaryuses it for its free-shipping messages, which come from Salla's translations.
Gotchas
It does not make untrusted HTML safe. Checked against the engine's function, these come back unchanged: an unquoted
<a href=javascript:…>, a handler after a slash<img/onerror=… src=x>, an entity-encodedhref="javascript:…", and a<style>block that can restyle the whole page. For text a customer or merchant typed, render it as text instead of HTML.Removing a tag keeps its content:
<b>Hi</b><script>steal()becomes<b>Hi</b>steal(), so the script source shows as text.
Related
Source and docs
- Engine source:
packages/theme-engine/src/utils/sanitize.ts