From e1ba9360e85f95765fe13449ade64d6951491a5c Mon Sep 17 00:00:00 2001 From: "Mr.X" Date: Fri, 19 Jun 2026 21:56:51 +0530 Subject: [PATCH] docs: clarify text/template threat model and SSTI risks (#73) --- src/output-encoding/cross-site-scripting.md | 22 ++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/output-encoding/cross-site-scripting.md b/src/output-encoding/cross-site-scripting.md index df3e65a..249a25c 100644 --- a/src/output-encoding/cross-site-scripting.md +++ b/src/output-encoding/cross-site-scripting.md @@ -111,8 +111,28 @@ Making `param1` equal to "<h1>" will lead to `Content-Type` being sent as ![XSS while using text/template package][text-template-xss] +> **Understanding Go template threat models** +> +> The `text/template` package performs no output encoding. It is designed for generating text-based +> formats (configuration files, plain-text emails, etc.), not HTML output. When used to render HTML +> without manual escaping, user input is written verbatim — making XSS inevitable. +> +> The `html/template` package automatically contextual-escapes values, but **only when untrusted data +> is passed as template parameters** (e.g. `{{ . }}`). This safety guarantee does **not** apply when +> user input is used to build the template source string itself: +> +> ```go +> tmpl.Parse(`
` + userInput + `
`) // DANGEROUS +> ``` +> +> If user-controlled data ever becomes part of the template definition, the application becomes +> vulnerable to **Server-Side Template Injection (SSTI)** — an attack that can bypass auto-escaping, +> access unexported struct fields, invoke methods, or execute arbitrary code. **User input must never +> be concatenated into the template source; it must only be supplied as a parameter value.** + By replacing the [text/template package][6] with the [html/template][2] one, -you'll be ready to proceed... safely. +you'll be ready to proceed... safely, provided untrusted data is only passed +as template parameters (never used to construct the template source). ```go package main