go.lang.security.injection.open-redirect.open-redirect
semgrep
Author
unknown
Download Count*
License
An HTTP redirect was found to be crafted from user-input $REQUEST
. This can lead to open redirect vulnerabilities, potentially allowing attackers to redirect users to malicious web sites. It is recommend where possible to not allow user-input to craft the redirect URL. When user-input is necessary to craft the request, it is recommended to follow OWASP best practices to restrict the URL to domains in an allowlist.
Run Locally
Run in CI
Defintion
rules:
- id: open-redirect
languages:
- go
severity: WARNING
message: An HTTP redirect was found to be crafted from user-input `$REQUEST`.
This can lead to open redirect vulnerabilities, potentially allowing
attackers to redirect users to malicious web sites. It is recommend where
possible to not allow user-input to craft the redirect URL. When
user-input is necessary to craft the request, it is recommended to follow
OWASP best practices to restrict the URL to domains in an allowlist.
options:
interfile: true
metadata:
cwe:
- "CWE-601: URL Redirection to Untrusted Site ('Open Redirect')"
references:
- https://knowledge-base.secureflag.com/vulnerabilities/unvalidated_redirects___forwards/open_redirect_go_lang.html
category: security
technology:
- go
confidence: HIGH
description: An HTTP redirect was found to be crafted from user-input leading to
an open redirect vulnerability
subcategory:
- vuln
impact: MEDIUM
likelihood: MEDIUM
interfile: true
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
vulnerability_class:
- Open Redirect
mode: taint
pattern-sources:
- label: INPUT
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)$
- label: CLEAN
requires: INPUT
patterns:
- pattern-either:
- pattern: |
"$URLSTR" + $INPUT
- patterns:
- pattern-either:
- pattern: fmt.Fprintf($F, "$URLSTR", $INPUT, ...)
- pattern: fmt.Sprintf("$URLSTR", $INPUT, ...)
- pattern: fmt.Printf("$URLSTR", $INPUT, ...)
- metavariable-regex:
metavariable: $URLSTR
regex: .*//[a-zA-Z0-10]+\..*
pattern-sinks:
- requires: INPUT and not CLEAN
patterns:
- pattern: http.Redirect($W, $REQ, $URL, ...)
- focus-metavariable: $URL
Examples
open-redirect.go
package main
import (
"fmt"
"net/http"
"strings"
)
func newRedirectServerFmt(addr string, rootPath string) *http.Server {
return &http.Server{
Addr: addr,
Handler: http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
target := fmt.Sprintf("https://%s/path/to/%s", req.Host, req.URL.Path)
if rootPath != "" {
target += "/" + strings.TrimRight(strings.TrimLeft(rootPath, "/"), "/")
}
target += req.URL.Path
if len(req.URL.RawQuery) > 0 {
target += "?" + req.URL.RawQuery
}
// ruleid: open-redirect
http.Redirect(w, req, target, http.StatusTemporaryRedirect)
}),
}
}
func newRedirectServerAdd(addr string, rootPath string) *http.Server {
return &http.Server{
Addr: addr,
Handler: http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
target := "https://" + req.Host + "/path/to/" + req.URL.Path
if rootPath != "" {
target += "/" + strings.TrimRight(strings.TrimLeft(rootPath, "/"), "/")
}
target += req.URL.Path
if len(req.URL.RawQuery) > 0 {
target += "?" + req.URL.RawQuery
}
// ruleid: open-redirect
http.Redirect(w, req, target, http.StatusTemporaryRedirect)
}),
}
}
func main() {
newRedirectServerAdd("127.0.0.1:8080", "/test")
newRedirectServerFmt("127.0.0.1:8080", "/test")
}
Short Link: https://sg.run/2ZW45