Skip to content
Ilha
Esc
↑↓navigate↵open⌘Jpreview
On this page

ILHA007: Unsafe raw text in script or style

renderToString refused to emit a script or style element whose text contains its own closing tag.

<script> and <style> hold raw text, so Ilha cannot escape their children. If the text contains </script or </style, the browser would end the element early and parse the rest as markup. renderToString() throws ILHA007 instead of shipping that HTML.

Why it happens

You interpolated untrusted or unescaped text into a <script> or <style> element.

Bad

import { renderToString } from "ilha";

const userText = "</script><img src=x onerror=alert(1)>";

const Page = () => <script>{`window.note = "${userText}"`}</script>;

await renderToString(Page);

Fixed

Serialize data as JSON and escape the < character, so the closing tag can never appear:

import { const renderToString: (fn: Component, opts?: RenderToStringOptions) => Promise<string>renderToString } from "ilha";

const const userText: "</script><img src=x onerror=alert(1)>"userText = "</script><img src=x onerror=alert(1)>";
const const json: stringjson = var JSON: JSON
An intrinsic object that provides functions to convert JavaScript values to and from the JavaScript Object Notation (JSON) format.
JSON
.JSON.stringify(value: any, replacer?: (this: any, key: string, value: any) => any, space?: string | number): string (+1 overload)
Converts a JavaScript value to a JavaScript Object Notation (JSON) string.
@paramvalue A JavaScript value, usually an object or array, to be converted.@paramreplacer A function that transforms the results.@paramspace Adds indentation, white space, and line break characters to the return-value JSON text to make it easier to read.@throws{TypeError} If a circular reference or a BigInt value is found.
stringify
({ note: stringnote: const userText: "</script><img src=x onerror=alert(1)>"userText }).String.replaceAll(searchValue: string | RegExp, replaceValue: string): string (+1 overload)
Replace all instances of a substring in a string, using a regular expression or search string.
@paramsearchValue A string to search for.@paramreplaceValue A string containing the text to replace for every successful match of searchValue in this string.
replaceAll
("<", "\\u003c");
const const Page: () => ViewPage = () => <JSX.IntrinsicElements.script: ScriptHTMLAttributesscript type?: Attrtype="application/json">{const json: stringjson}</JSX.IntrinsicElements.script: ScriptHTMLAttributesscript>; const const html: stringhtml = await function renderToString(fn: Component, opts?: RenderToStringOptions): Promise<string>renderToString(const Page: () => ViewPage);

Was this page helpful?