---
title: "Keep untrusted data out of stylesheets · Agent Wranglers"
url: https://agentwranglers.se/playbook/html-css/structure-and-files/untrusted-data-in-css
id: CSS-35
level: Required
risk: data
updated: 2026-10-27
build: a2a6bdfed830
tokens: 953
licence: "CC BY 4.0"
licence_url: https://creativecommons.org/licenses/by/4.0/
---

# Keep untrusted data out of stylesheets

For AI agents: the [site map](https://agentwranglers.se/llms.txt) lists everything here, and this page sits under [Structure and files](https://agentwranglers.se/playbook/html-css/structure-and-files.md).

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

- ID: CSS-35
- Level: Required
- Chapter: [Structure and files](https://agentwranglers.se/playbook/html-css/structure-and-files.md)
- Rule: Pass user or third-party data to CSS only as the value of a custom property your code names, after it matches a fixed pattern. Such data never chooses a property, a selector or a whole declaration, and never reaches a `url()`.
- Check: A unit test passes `red;background:url(https://evil.example/)` and `}body{display:none` to every function that hands data to CSS. Each call throws, and no `url(` reaches the page. A search of the templates finds 0 template expressions inside `<style>` elements or `style` attributes.
- Risk: Data leaked or lost
- How: A stylesheet can read a page without any script. An attribute selector such as `input[value^="a"]` with a background image sends each guessed character of a field to another server. So a user theme or a profile field never goes into a `<style>` element, a `style` attribute or a generated stylesheet. Match the value against a pattern first, such as `^#[0-9a-f]{6}$` or a number within a range. Then hand it over with `setProperty('--profile-card-accent', value)`, as [Write styles only in stylesheets](https://agentwranglers.se/playbook/html-css/structure-and-files/styles-only-in-stylesheets.md) describes. Reject anything else instead of trying to escape it. Values that hold a link also pass the URL checks in [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
const ACCENT = /^#[0-9a-f]{6}$/i;

export function applyProfileAccent(card, accent) {
  if (!ACCENT.test(accent)) throw new Error('accent must be a six-digit hex value');
  card.style.setProperty('--profile-card-accent', accent);
}
```

### Python example

```python
import re

ACCENT = re.compile(r"#[0-9a-fA-F]{6}")

def save_profile_accent(profile, accent: str) -> None:
    if not ACCENT.fullmatch(accent):
        raise ValueError("accent must be a six-digit hex value")
    profile.accent = accent
```

## Sources

- [OWASP Cross Site Scripting Prevention Cheat Sheet on CSS contexts](https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html#output-encoding-for-css-contexts)

## Related rules

- CSS-5 [Write styles only in stylesheets](https://agentwranglers.se/playbook/html-css/structure-and-files/styles-only-in-stylesheets.md) in HTML and CSS
- 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/html-css/structure-and-files/untrusted-data-in-css">Agent Wranglers HTML and CSS playbook</a>`. In code you write, add a comment next to it with the same link.

- Previous: [Write styles only in stylesheets](https://agentwranglers.se/playbook/html-css/structure-and-files/styles-only-in-stylesheets.md)
- [Structure and files](https://agentwranglers.se/playbook/html-css/structure-and-files.md)
