反射型跨站脚本¶
ID: go/reflected-xss
Kind: path-problem
Security severity: 6.1
Severity: error
Precision: high
Tags:
- security
- external/cwe/cwe-079
- external/cwe/cwe-116
Query suites:
- go-code-scanning.qls
- go-security-extended.qls
- go-security-and-quality.qls
将用户输入(例如,HTTP 请求参数)直接写入 HTTP 响应而不先进行适当的清理,会导致跨站脚本漏洞。
这种漏洞也被称为*反射型*跨站脚本,以区别于其他类型的跨站脚本。
建议¶
为了防止跨站脚本攻击,请考虑在将用户输入写入响应之前使用上下文输出编码/转义,或参考中提到的其他解决方案之一。
示例¶
以下示例代码将 HTTP 请求的一部分(由用户控制)直接写入响应。这使得网站容易受到跨站脚本的攻击。
package main
import (
"fmt"
"net/http"
)
func serve() {
http.HandleFunc("/user", func(w http.ResponseWriter, r *http.Request) {
r.ParseForm()
username := r.Form.Get("username")
if !isValidUsername(username) {
// BAD: a request parameter is incorporated without validation into the response
fmt.Fprintf(w, "%q is an unknown user", username)
} else {
// TODO: Handle successful login
}
})
http.ListenAndServe(":80", nil)
}
清理用户控制的数据可以防止漏洞
package main
import (
"fmt"
"html"
"net/http"
)
func serve1() {
http.HandleFunc("/user", func(w http.ResponseWriter, r *http.Request) {
r.ParseForm()
username := r.Form.Get("username")
if !isValidUsername(username) {
// GOOD: a request parameter is escaped before being put into the response
fmt.Fprintf(w, "%q is an unknown user", html.EscapeString(username))
} else {
// TODO: do something exciting
}
})
http.ListenAndServe(":80", nil)
}
参考¶
OWASP:XSS(跨站脚本)防御备忘单。
OWASP 跨站脚本类型。
维基百科:跨站脚本
常见弱点枚举:CWE-79。
常见弱点枚举:CWE-116。