go.lang.security.injection.raw-html-format.raw-html-format

Author
unknown
Download Count*
License
Detected user input flowing into a manually constructed HTML string. You may be accidentally bypassing secure methods of rendering HTML by manually constructing HTML and this could create a cross-site scripting vulnerability, which could let attackers steal sensitive user data. Use the html/template
package which will safely render HTML instead, or inspect that the HTML is rendered safely.
Run Locally
Run in CI
Defintion
rules:
- id: raw-html-format
languages:
- go
severity: WARNING
message: Detected user input flowing into a manually constructed HTML string.
You may be accidentally bypassing secure methods of rendering HTML by
manually constructing HTML and this could create a cross-site scripting
vulnerability, which could let attackers steal sensitive user data. Use
the `html/template` package which will safely render HTML instead, or
inspect that the HTML is rendered safely.
metadata:
cwe:
- "CWE-79: Improper Neutralization of Input During Web Page Generation
('Cross-site Scripting')"
owasp:
- A07:2017 - Cross-Site Scripting (XSS)
- A03:2021 - Injection
category: security
technology:
- go
references:
- https://blogtitle.github.io/robn-go-security-pearls-cross-site-scripting-xss/
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
confidence: MEDIUM
cwe2022-top25: true
cwe2021-top25: true
subcategory:
- vuln
likelihood: HIGH
impact: MEDIUM
vulnerability_class:
- Cross-Site-Scripting (XSS)
mode: taint
pattern-sources:
- patterns:
- pattern-either:
- pattern: |
($REQUEST : *http.Request).$ANYTHING
- pattern: |
($REQUEST : http.Request).$ANYTHING
- metavariable-regex:
metavariable: $ANYTHING
regex: ^(BasicAuth|Body|Cookie|Cookies|Form|FormValue|GetBody|Host|MultipartReader|ParseForm|ParseMultipartForm|PostForm|PostFormValue|Referer|RequestURI|Trailer|TransferEncoding|UserAgent|URL)$
pattern-sanitizers:
- pattern: html.EscapeString(...)
pattern-sinks:
- patterns:
- pattern-either:
- pattern: fmt.Printf("$HTMLSTR", ...)
- pattern: fmt.Sprintf("$HTMLSTR", ...)
- pattern: fmt.Fprintf($W, "$HTMLSTR", ...)
- pattern: '"$HTMLSTR" + ...'
- metavariable-pattern:
metavariable: $HTMLSTR
language: generic
pattern: <$TAG ...
Examples
raw-html-format.go
package main
import (
"fmt"
"log"
"net/http"
)
func getMovieQuote() map[string]string {
m := make(map[string]string)
m["quote"] = "I'll be back."
m["movie"] = "The Terminator"
m["year"] = "1984"
return m
}
func healthCheck(w http.ResponseWriter, r *http.Request) {
// ok: raw-html-format
w.Write([]byte("alive"))
}
func indexPage(w http.ResponseWriter, r *http.Request) {
const tme = `<html>`
const template = `
<html>
<body>
<h1>Random Movie Quotes</h1>
<h2>%s</h2>
<h4>~%s, %s</h4>
</body>
</html>`
quote := getMovieQuote()
quoteText := quote["quote"]
movie := quote["movie"]
year := quote["year"]
w.WriteHeader(http.StatusAccepted)
// ok: raw-html-format
w.Write([]byte(fmt.Sprintf(template, quoteText, movie, year)))
}
func errorPage(w http.ResponseWriter, r *http.Request) {
params := r.URL.Query()
urls, ok := params["url"]
if !ok {
log.Println("Error")
return
}
url := urls[0]
const template = `
<html>
<body>
<h1>error; page not found. <a href="%s">go back</a></h1>
</body>
</html>`
w.WriteHeader(http.StatusAccepted)
// ruleid:raw-html-format
w.Write([]byte(fmt.Sprintf(template, url)))
}
func errorPage2(w http.ResponseWriter, r *http.Request) {
params := r.URL.Query()
urls, ok := params["url"]
if !ok {
log.Println("Error")
return
}
url := urls[0]
const template = `
<html>
<body>
<h1>error; page not found. <a href="%s">go back</a></h1>
</body>
</html>`
w.WriteHeader(http.StatusAccepted)
// ruleid:raw-html-format
w.Write([]byte(fmt.Printf(template, url)))
}
func errorPage3(w http.ResponseWriter, r *http.Request) {
params := r.URL.Query()
urls, ok := params["url"]
if !ok {
log.Println("Error")
return
}
url := urls[0]
const template = `
<html>
<body>
<h1>error; page not found. <a href="%s">go back</a></h1>
</body>
</html>`
w.WriteHeader(http.StatusAccepted)
// ruleid:raw-html-format
fmt.Fprintf(w, template, url)
}
func errorPage4(w http.ResponseWriter, r *http.Request) {
params := r.URL.Query()
urls, ok := params["url"]
if !ok {
log.Println("Error")
return
}
url := urls[0]
// ruleid:raw-html-format
const template = "<html><body><h1>error; page not found. <a href='" + url + "'>go back </a></h1>"
w.WriteHeader(http.StatusAccepted)
w.Write([]byte(template))
}
func main() {
http.HandleFunc("/", indexPage)
http.HandleFunc("/error", errorPage)
http.ListenAndServe(":8080", nil)
}
Short Link: https://sg.run/3r1G