CVE-2023-24538 is a security vulnerability that affects Go’s html/template and text/template packages. This issue arises because these templates did not properly handle backticks () as delimiters for JavaScript string literals.</b> Backticks, introduced in ES6 as template literals, allow multi-line and interpolated JavaScript strings. If a Go template action (like {{.}}`) is used _inside_ a JS template literal, it could be exploited to inject malicious JavaScript code.

Let’s dive deeper—with clear examples and actionable advice—into what went wrong, how this could be exploited, and best practices to stay secure.

What’s the Problem?

When you use Go templates to generate web pages, you often embed data into scripts. Prior to the patch, Go’s html/template escape logic didn’t treat backticks (<pre><code class="language-) properly as JS string delimiters. That means user-supplied values inserted inside JS template literals could break out, letting attackers inject arbitrary, and potentially harmful, JavaScript."> Example (unsafe, vulnerable code):go
// index.tmpl
<br>let userInput = <i>{{.UserInput}}</i><br>

Suppose .UserInput came from untrusted user data. Eve, an attacker, could supply a value like:
`; alert('Hacked!');//


This turns your page into:

html
<br>let userInput = <i>; alert(&#039;Hacked!&#039;);//</i><br>

Which, when the script runs, immediately shows the alert. This is Cross Site Scripting (XSS).

---

## Exploit Details

ES6 template literals (` ) are powerful, because they support nesting and variable interpolation:

js
let str = Hello, ${user}!;


Go templates allow code like {{.}} which inserts user data. If you combine them in a JS template literal, any injected backtick or ${} ends the string and allows attackers to write their own JS.

Malicious payload:


`; alert('pwned') //


It terminates the string, adds an alert, and comments the rest, leading to XSS.

---

## Why Not Just Escape the Backtick?

Properly escaping all cases, considering ES6’s power, is complicated and error-prone. For example, a user might try:


${evilFunction()}


Which Go’s template engine might not recognize correctly as an injection risk. Due to this complexity, the Go project decided: _disallow_ Go template actions inside JavaScript template literals. This mirrors the standard in github.com/google/safehtml.

> Bottom line: It’s not feasible to safely mix Go template actions inside JS template literals.

---

## How Was It Fixed?

Starting in Go 1.20.7, 1.19.12, and 1.18.19, and backported to affected releases:

- Parsing a template with {{.}} inside a JS template literal (backtick) now returns an Error, with internal ErrorCode 12.
- If you try to use code like 

let foo = <i>{{.}}</i>`, Go will not compile the template – it errors out.

Error example

package main

import (
	"html/template"
	"os"
)

func main() {
	tmpl := "{{.UserInput}}"
	_, err := template.New("example").Parse("<script>var a = " + tmpl + ";</script>")
	if err != nil {
		println("Error parsing template:", err.Error())
	}
}


Output:  

Error parsing template: html/template:template:1: unexpected template action in JavaScript template literal

You CAN re-enable prior behavior with the Go runtime flag

GODEBUG=jstmpllitinterp=1


But warning:

Upgrade Go—use 1.20.7, 1.19.12, 1.18.19 or newer. See official Go security advisories.

2. Don’t put {{.}}, {{.Field}}, etc. inside JS template literals (backticks) in your templates.
3. If you must output user data into JavaScript, encode it manually or place it as JSON outside JS template literals:

let userInput = {{ .UserInput | js }};

References

- Go Security Advisory for html/template and text/template (CVE-2023-24538)
- Go Release Notes—Go 1.20.7
- Upstream Fix code example
- GitHub SafeHTML Package
- CVE-2023-24538 on Mitre

Conclusion

CVE-2023-24538 is a great example of new JavaScript language features (backtick template literals) introducing novel security risks for server-rendered templates. Go’s fix prevents a whole class of XSS holes, and the community recommends _never interpolating Go template actions inside JS template literals._ Always escape user data, keep dependencies and runtimes up to date, and stay tuned for new security advisories!

Timeline

Published on: 04/06/2023 16:15:00 UTC
Last modified on: 04/17/2023 16:54:00 UTC