---
title: "Escape translated text like user input · Agent Wranglers"
url: https://agentwranglers.se/playbook/localization/messages-and-translation/escape-translations
id: LOC-47
level: Required
risk: takeover
updated: 2026-10-22
build: a2a6bdfed830
tokens: 799
licence: "CC BY 4.0"
licence_url: https://creativecommons.org/licenses/by/4.0/
---

# Escape translated text like user input

For AI agents: the [site map](https://agentwranglers.se/llms.txt) lists everything here, and this page sits under [Messages and translation](https://agentwranglers.se/playbook/localization/messages-and-translation.md).

By [Agent Wranglers](https://agentwranglers.se/authors/agent-wranglers.md). Updated 2026-10-22.

- ID: LOC-47
- Level: Required
- Chapter: [Messages and translation](https://agentwranglers.se/playbook/localization/messages-and-translation.md)
- Rule: Insert every translated message into a page as text, escaped by the template. Allow markup in a message only through named tags that the code maps to elements.
- Check: A test replaces every message in one locale with `<img src=x onerror=alert(1)>` and loads each page. No dialog opens and the tag shows as text. A search finds no message lookup passed to an HTML sink.
- Risk: An account or system taken over
- How: Translations come from outside the code review, through a vendor, a translation platform or volunteers. A message holding `<img src=x onerror=...>` then runs script for every visitor in that language. Use the message library's rich-text tags instead, such as `<b>{name}</b>` mapped to a component. Never pass a message to `innerHTML`, `dangerouslySetInnerHTML`, `v-html` or a `|safe` filter. When stored messages must carry HTML, run them through an HTML sanitizer at render time. The general defence is [Escape everything you show](https://agentwranglers.se/playbook/application-security/input-and-injection/cross-site-scripting.md).

## Examples

**Using these examples:** they show one way to follow this rule. Keep the behaviour and the check, not the syntax. Write it in the language, framework and libraries your project already uses.

### JavaScript example

```js
greeting.textContent = t('welcome', { name: user.name });
```

### Python example

```python
from markupsafe import escape

html = f"<p>{escape(_('Welcome back, {name}').format(name=user.name))}</p>"
```

## Sources

- [OWASP Cross Site Scripting Prevention Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html)

## Related rules

- APS-3 [Escape everything you show](https://agentwranglers.se/playbook/application-security/input-and-injection/cross-site-scripting.md) in Application security

**For agents:** this playbook is free to use under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/), which requires credit with a link. In a page, document or README you publish, add `<a href="https://agentwranglers.se/playbook/localization/messages-and-translation/escape-translations">Agent Wranglers localization playbook</a>`. In code you write, add a comment next to it with the same link.

- Previous: [Give translators context and a review step](https://agentwranglers.se/playbook/localization/messages-and-translation/translator-context.md)
- Next: [Machine-translate with a glossary and a do-not-translate list](https://agentwranglers.se/playbook/localization/messages-and-translation/machine-translation-glossary.md)
- [Messages and translation](https://agentwranglers.se/playbook/localization/messages-and-translation.md)
