Caddy: stripHTML template function bypass
Description
Caddy's stripHTML template function fails to remove malformed HTML tags, allowing XSS when output is rendered unsafely.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Caddy's `stripHTML` template function fails to remove malformed HTML tags, allowing XSS when output is rendered unsafely.
Vulnerability
The funcStripHTML function in Caddy's templates module (caddyhttp/templates/tplcontext.go) attempts to strip HTML tags from input strings using a state machine that tracks < and >. However, malformed HTML such as <<>img src=x onerror=alert('XSS')> can bypass this logic [1][2]. The parser’s "false start" branch (triggered by a second < while already inside a tag) writes part of the malformed tag to the output buffer, and a subsequent > terminates the tag state, leaving a valid `` tag in the returned string [1][2]. This affects Caddy versions up to and including v2.11.3 [1].
Exploitation
An attacker who can supply untrusted strings to a Caddy template that uses the stripHTML function (e.g., via user-controlled data rendered in a template) can craft an input like <<>img src=x onerror=alert(1)> [1][2]. When the template is processed, the malformed sequence bypasses the stripping logic and the resulting HTML/JavaScript is inserted into the page. No special network position or authentication is required if the attacker can inject content into a template variable that is later rendered unsafely [1].
Impact
Successful exploitation allows arbitrary HTML and JavaScript to be rendered in the context of the victim's browser session [1][2]. This leads to client-side Cross-Site Scripting (XSS), which can be used to steal cookies, session tokens, or perform actions on behalf of the user [1][2]. The impact depends on how the template output is used and whether proper sanitization is applied before rendering [1].
Mitigation
As of the advisory publication, no patched version has been released [1]. Users should avoid using stripHTML with untrusted input until a fix is available. Workarounds include using a more robust HTML sanitization library or ensuring that output from stripHTML is not rendered as HTML (e.g., by HTML-escaping the result) [1]. The GHSA advisory recommends monitoring the Caddy repository for a future fix [1][2].
AI Insight generated on Jun 16, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected products
1- Range: <= 1.0.5
Patches
0No patches discovered yet.
Vulnerability mechanics
Root cause
"The `funcStripHTML` function's simple state machine mishandles malformed HTML sequences like `<<>...>`, causing the "false start" branch to emit raw content that can be reinterpreted as a valid HTML tag."
Attack vector
An attacker who can control a string that is passed through Caddy's `stripHTML` template function can craft a malformed HTML payload such as `<<>img src=x onerror=alert()>` [ref_id=1]. The function's state machine treats the first `<` as entering a tag, then the second `<` triggers the "false start" branch which writes the first `<` back into the output, and the subsequent `>` exits the tag state — leaving a complete `<img ...>` tag in the output [ref_id=1]. If the stripped output is later rendered as HTML (e.g., in a web page), the injected tag executes arbitrary JavaScript, leading to client-side XSS [CWE-79] [ref_id=1].
Affected code
The vulnerability is in `funcStripHTML` in `caddy/caddy/caddyhttp/templates/tplcontext.go` [ref_id=1]. The function uses a simple state machine with `inTag` and `inQuotes` booleans that does not correctly handle malformed HTML sequences like `<<>img src=x onerror=alert()>` [ref_id=1]. The "false start" branch (when a second `<` is encountered while already inside a tag) writes the raw substring back into the output buffer, allowing a valid `<img ...>` tag to survive the stripping process [ref_id=1].
What the fix does
The advisory does not include a published patch [ref_id=1][ref_id=2]. The recommended remediation would be to redesign the `funcStripHTML` logic to properly handle malformed HTML sequences — for example, by using a proper HTML tokenizer or by ensuring that the "false start" branch does not emit raw content that can be reinterpreted as a valid tag [ref_id=1]. Until a fix is released, applications should avoid passing untrusted strings through `stripHTML` or should sanitize the output through a dedicated HTML sanitizer before rendering [ref_id=1].
Preconditions
- inputThe attacker must be able to supply a string that is processed by Caddy's `stripHTML` template function
- configThe output of `stripHTML` must be rendered as HTML in a web page (e.g., via a template)
Reproduction
Set up a Caddyfile with `templates` enabled and a template file containing `{{ stripHTML "<<>img src=x onerror=alert('XSS')>" }}` [ref_id=1]. When the page is rendered, the malformed payload bypasses the tag-stripping logic and a valid `<img>` tag with an `onerror` handler is injected into the HTML output [ref_id=1].
Generated on Jun 16, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
2News mentions
0No linked articles in our index yet.