JSX runtime escape

PRISM's compile pass folds JSX into string concatenation.{" "}Attribute values always go through __bextEsc. Text children pass through unchanged — the caller is responsible for escaping. The first column below shows the footgun; the second uses escapeHtml().

Output

Payload{raw}{escapeHtml(raw)}attribute
plain texthello worldhello world
HTML charsstrong<b>strong</b>
image tag<img src=x>
ampersand & quotesTom & Jerry's "best" episodeTom & Jerry's "best" episode
attr injection" onmouseover="x" onmouseover="x

Source

// PRISM's escape policy:
    //    — attributes ALWAYS go through __bextEsc.
//   

{x}

— children pass through UNCHANGED. Caller's // responsibility to escape if x might contain HTML. // // The compile pass folds

{x}

to "

" + (x) + "

". To stay // safe, wrap user-supplied values in escapeHtml() (re-exported from // the JSX runtime) when they shouldn't be interpreted as HTML. import { escapeHtml } from "@bext-stack/framework/jsx-runtime"; export default function Page({ user }) { return (

raw: {user.bio}

{/* dangerous if bio is user input */}

safe: {escapeHtml(user.bio)}

{/* always emits text */} {/* attributes auto-escaped */}
); }