# HTML built or escaped by hand: `innerHTML` from values, `.replace('<', '&lt;')`

*Shortcuts that trade away safety*: one of the ways AI coding agents bloat software, from lessloc's [pattern catalog](https://lessloc.org/patterns/index.md). lessloc catches it as [`unsafe`](https://lessloc.org/guide/reference.md#tier-1): use `textContent` or the framework's rendering.

## What makes HTML built or escaped by hand a bad practice?

The standards that call it a bad practice: [CWE-79](https://cwe.mitre.org/data/definitions/79.html) Cross-site Scripting; [CWE-116](https://cwe.mitre.org/data/definitions/116.html) Improper Encoding or Escaping of Output.

## What does lessloc do about HTML built or escaped by hand?

lessloc catches it as [`unsafe`](https://lessloc.org/guide/reference.md#tier-1): use `textContent` or the framework's rendering.

- `unsafe` (tier 1): A shortcut that trades away safety: SQL built from values, HTML built or escaped by hand, `Math.random()` for secrets, a fast hash for passwords, certificate checks turned off, text run as code.

## Examples

Caught as `unsafe`:

```js [ck.js]
export function show(el, name) {
  el.innerHTML = `<b>${name}</b>`;
}
```

Written well:

```js [ck.js]
export function show(el, name) {
  el.textContent = name;
}
```

## Related patterns

Hand-written versions of what the platform does safely. They are short, which is why agents reach for them. The other patterns in [Shortcuts that trade away safety](https://lessloc.org/patterns/index.md#shortcuts-that-trade-away-safety):

- [SQL built from values instead of query parameters](https://lessloc.org/patterns/sql-from-values.md): lessloc catches it as `unsafe`: pass values as query parameters.
- [Math.random() or random for tokens and passwords](https://lessloc.org/patterns/weak-randomness.md): lessloc catches it as `unsafe`: `crypto.randomUUID()`, `getRandomValues()` or the `secrets` module.
- [Fast hashes (MD5, SHA-1, SHA-256) for passwords](https://lessloc.org/patterns/password-hash.md): lessloc catches it as `unsafe`: bcrypt, scrypt or argon2.
- [Certificate checks turned off](https://lessloc.org/patterns/tls-off.md): lessloc catches it as `unsafe`.
- [Running text as code: eval, exec, new Function](https://lessloc.org/patterns/eval.md): lessloc catches it as `unsafe`: parse the input instead.
