go.lang.security.audit.net.wip-xss-using-responsewriter-and-printf.wip-xss-using-responsewriter-and-printf
Verifed by r2c
Community Favorite

Author
98,168
Download Count*
License
Found data going from url query parameters into formatted data written to ResponseWriter. This could be XSS and should not be done. If you must do this, ensure your data is sanitized or escaped.
Run Locally
Run in CI
Defintion
rules:
- id: wip-xss-using-responsewriter-and-printf
patterns:
- pattern-inside: |
func $FUNC(..., $W http.ResponseWriter, ...) {
...
var $TEMPLATE = "..."
...
$W.Write([]byte(fmt.$PRINTF($TEMPLATE, ...)), ...)
...
}
- pattern-either:
- pattern: |
$PARAMS = r.URL.Query()
...
$DATA, $ERR := $PARAMS[...]
...
$INTERM = $ANYTHING(..., $DATA, ...)
...
$W.Write([]byte(fmt.$PRINTF(..., $INTERM, ...)))
- pattern: |
$PARAMS = r.URL.Query()
...
$DATA, $ERR := $PARAMS[...]
...
$INTERM = $DATA[...]
...
$W.Write([]byte(fmt.$PRINTF(..., $INTERM, ...)))
- pattern: |
$DATA, $ERR := r.URL.Query()[...]
...
$INTERM = $DATA[...]
...
$W.Write([]byte(fmt.$PRINTF(..., $INTERM, ...)))
- pattern: |
$DATA, $ERR := r.URL.Query()[...]
...
$INTERM = $ANYTHING(..., $DATA, ...)
...
$W.Write([]byte(fmt.$PRINTF(..., $INTERM, ...)))
- pattern: |
$PARAMS = r.URL.Query()
...
$DATA, $ERR := $PARAMS[...]
...
$W.Write([]byte(fmt.$PRINTF(..., $DATA, ...)))
message: Found data going from url query parameters into formatted data written
to ResponseWriter. This could be XSS and should not be done. If you must
do this, ensure your data is sanitized or escaped.
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
confidence: MEDIUM
references:
- https://owasp.org/Top10/A03_2021-Injection
cwe2022-top25: true
cwe2021-top25: true
subcategory:
- vuln
likelihood: LOW
impact: MEDIUM
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
severity: WARNING
languages:
- go
Examples
wip-xss-using-responsewriter-and-printf.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 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)
w.Write([]byte(fmt.Sprintf(template, quoteText, movie, year)))
}
func errorPage(w http.ResponseWriter, r *http.Request) {
// ruleid: wip-xss-using-responsewriter-and-printf
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)
w.Write([]byte(fmt.Sprintf(template, url)))
}
func main() {
http.HandleFunc("/", indexPage)
http.HandleFunc("/error", errorPage)
http.ListenAndServe(":8080", nil)
}
Short Link: https://sg.run/Zvon