Перейти к содержимому
Русский

HTML responses & XSS prevention

Это содержимое пока не доступно на вашем языке.

The html tagged template escapes every interpolation by default, so building an HTML response is safe without thinking about it. completeHtml sends it with the right content-type.

import { completeHtml, html, Status } from 'actor-ts/http';
get((req) => {
const name = req.query.name ?? 'world'; // untrusted
return completeHtml(Status.OK, html`
<h1>Hello, ${name}!</h1>
`);
});

If name is <script>alert(1)</script>, the output is Hello, &lt;script&gt;alert(1)&lt;/script&gt;! — inert.

ExportWhat it does
escapeHtml(s)Escape & < > " ' and the backtick.
html`…`Tagged template; escapes interpolations, returns SafeHtml.
SafeHtmlBrand for already-safe HTML; interpolated verbatim.
rawHtml(s)Wrap a string you have already made safe.
completeHtml(status, body, headers?)text/html; charset=utf-8 + X-Content-Type-Options: nosniff.

Interpolation rules for html`…`: a SafeHtml value is inserted verbatim (so fragments nest), arrays are rendered item-by-item, null/undefined become the empty string, and everything else is coerced to a string and escaped.

const items = ['<a>', '<b>'];
const list = html`<ul>${items.map((i) => html`<li>${i}</li>`)}</ul>`;
// <ul><li>&lt;a&gt;</li><li>&lt;b&gt;</li></ul>

Escaping neutralises markup — it does not make attacker-authored HTML safe to render as HTML. If you must accept rich HTML (comments, wiki markup), sanitise it with a dedicated, battle-tested library such as sanitize-html or DOMPurify before wrapping the result in rawHtml. A conservative built-in sanitizer is tracked separately.