# XSS attribute context breakout

User value in an HTML attribute where the delimiting quote is unescaped or re-parsed downstream

_Area: Web injection and code execution. Seen in 20 disclosed reports; 11 confirmed bounties, median $2,000, range $500-$16,000; latest 2026-10-14. Updated 2026-10-23._

## How it works
A user-controlled value is placed inside an HTML attribute (`href`, `src`, `content`, `data-*`) by string concatenation or template interpolation. The code assumes the value is "just text" and escapes for HTML text context, or escapes nothing. If the quote delimiting the attribute is not escaped, the value closes the attribute and opens new attributes or a new tag. The broken assumption: "escaping for HTML text is enough" or "this field is validated upstream." Attribute context needs its own quote escaping. A second failure mode: the value is escaped correctly on the server, but a client library reads the attribute back, the browser has already decoded it, and the library re-parses it as markup or evaluates it as JS [E3](https://bugbountylibrary.com/r/h1%3A3988961.md)[E4](https://bugbountylibrary.com/r/h1%3A217790.md).

## Where it shows up
- String-interpolated tags: `<a href="#{url}">`, `<img src="#{x}" />` [E1](https://bugbountylibrary.com/r/h1%3A1212067.md)[E7](https://bugbountylibrary.com/r/h1%3A1731349.md)
- Regexes allowing "any char except X" feeding an attribute [E1](https://bugbountylibrary.com/r/h1%3A1212067.md)
- New REST/metadata write paths that skip the sanitizer legacy upload paths enforce [E2](https://bugbountylibrary.com/r/h1%3A3931771.md)
- `data-*` attributes read back by jQuery/HTML parsing: browser attribute decoding undoes server escaping before the library re-parses [E3](https://bugbountylibrary.com/r/h1%3A3988961.md)
- Template engines that escape HTML but the value lands in a JS/JSON attribute consumed by `new Function` [E4](https://bugbountylibrary.com/r/h1%3A217790.md)
- Single-quoted `content` attributes where only double quotes are filtered [E5](https://bugbountylibrary.com/r/blog%3Apwn-ai-blog-apache-jspwiki-preauth-xss-to-ato.md)
- Reflected params in `data-origin`/dataset used for postMessage origin checks [E6](https://bugbountylibrary.com/r/blog%3Agist-github-com-renwax23-0311842bb790ce98fe0cd8f41141fdf0.md)
- Downstream re-parse: `data-tooltip-html` + `dangerouslySetInnerHTML` [E3](https://bugbountylibrary.com/r/h1%3A3988961.md)

## How to review
The invariant: every user-controlled value entering an attribute must be escaped for that attribute's quote style at the final sink, and must not be re-parsed as markup or evaluated as JS downstream. Grep for interpolated tags, `.after(`/`.html(`/`.append(`, `dangerouslySetInnerHTML`, and `dataset`/`data-*` reads. For each sink ask: is the delimiter quote escaped? Is the escape applied at the final sink, not an earlier layer? Does a client library decode and re-evaluate the attribute? For JS/JSON attribute contexts (data-define, data-origin), require JS-context escaping, not HTML escaping [E4](https://bugbountylibrary.com/r/h1%3A217790.md)[E6](https://bugbountylibrary.com/r/blog%3Agist-github-com-renwax23-0311842bb790ce98fe0cd8f41141fdf0.md). For upload paths, check whether `filename*` (RFC 5987) in Content-Disposition reaches the sink unescaped [E1](https://bugbountylibrary.com/r/h1%3A1212067.md). Distinguish reflected sinks (single request, needs victim interaction) from stored sinks (persisted, fires for every viewer).

## Variants seen
- Filename with quotes breaking href in markdown links, bypassing upload sanitizer via RFC 5987 filename* [E1](https://bugbountylibrary.com/r/h1%3A1212067.md)
- Unsanitized sub-size filename from REST metadata concatenated into single-quoted src [E2](https://bugbountylibrary.com/r/h1%3A3931771.md)
- Email concatenated into jQuery `.after()` markup; server escaping undone by browser attribute decoding before re-parse [E3](https://bugbountylibrary.com/r/h1%3A3988961.md)
- Adjacent JS/JSON context: lodash template value in data-define attribute evaluated by twine [E4](https://bugbountylibrary.com/r/h1%3A217790.md)
- Username in single-quoted meta content, colon filter bypassed via existing CSS class [E5](https://bugbountylibrary.com/r/blog%3Apwn-ai-blog-apache-jspwiki-preauth-xss-to-ato.md)
- Adjacent JS/JSON context: replyUrl reflected into script data-origin [E6](https://bugbountylibrary.com/r/blog%3Agist-github-com-renwax23-0311842bb790ce98fe0cd8f41141fdf0.md)
- Parent-node lang attribute read instead of validated child, concatenated into img src [E7](https://bugbountylibrary.com/r/h1%3A1731349.md)
- Fix sanitized plain labels but not scoped-label color path [E8](https://bugbountylibrary.com/r/h1%3A1693150.md)

## Why fixes fail
E8: the patch for the original label-color XSS only sanitized plain labels; the scoped-label rendering path still emitted the attacker-controlled color into attributes unsanitized. When a fix covers one rendering path, enumerate sibling paths formatting the same field.

## Impact and severity
Stored XSS on public dashboards [E3](https://bugbountylibrary.com/r/h1%3A3988961.md), admin-context XSS [E2](https://bugbountylibrary.com/r/h1%3A3931771.md)[E4](https://bugbountylibrary.com/r/h1%3A217790.md), preauth stored XSS to account takeover [E5](https://bugbountylibrary.com/r/blog%3Apwn-ai-blog-apache-jspwiki-preauth-xss-to-ato.md), OAuth token theft and account takeover [E6](https://bugbountylibrary.com/r/blog%3Agist-github-com-renwax23-0311842bb790ce98fe0cd8f41141fdf0.md). Severity rises with CSP bypass [E1](https://bugbountylibrary.com/r/h1%3A1212067.md)[E6](https://bugbountylibrary.com/r/blog%3Agist-github-com-renwax23-0311842bb790ce98fe0cd8f41141fdf0.md)[E8](https://bugbountylibrary.com/r/h1%3A1693150.md), privileged viewers, and chaining to CSRF or token leak.

## Evidence
- E1: https://bugbountylibrary.com/r/h1%3A1212067.md
- E2: https://bugbountylibrary.com/r/h1%3A3931771.md
- E3: https://bugbountylibrary.com/r/h1%3A3988961.md
- E4: https://bugbountylibrary.com/r/h1%3A217790.md
- E5: https://bugbountylibrary.com/r/blog%3Apwn-ai-blog-apache-jspwiki-preauth-xss-to-ato.md
- E6: https://bugbountylibrary.com/r/blog%3Agist-github-com-renwax23-0311842bb790ce98fe0cd8f41141fdf0.md
- E7: https://bugbountylibrary.com/r/h1%3A1731349.md
- E8: https://bugbountylibrary.com/r/h1%3A1693150.md
