mirror of
https://github.com/github/codeql.git
synced 2026-01-29 14:23:03 +01:00
OpenUrlRedirect: make functions like isValidRedirect barrier guards
This commit is contained in:
@@ -101,11 +101,13 @@ module OpenUrlRedirect {
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to a function called `isLocalUrl` or similar, which is
|
||||
* A call to a function called `isLocalUrl`, `isValidRedirect`, or similar, which is
|
||||
* considered a barrier for purposes of URL redirection.
|
||||
*/
|
||||
class LocalUrlBarrierGuard extends BarrierGuard, DataFlow::CallNode {
|
||||
LocalUrlBarrierGuard() { this.getCalleeName().regexpMatch("(?i)(is_?)?local_?url") }
|
||||
class RedirectCheckBarrierGuard extends BarrierGuard, DataFlow::CallNode {
|
||||
RedirectCheckBarrierGuard() {
|
||||
this.getCalleeName().regexpMatch("(?i)(is_?)?(local_?url|valid_?redir(ect)?)")
|
||||
}
|
||||
|
||||
override predicate checks(Expr e, boolean outcome) {
|
||||
// `isLocalUrl(e)` is a barrier for `e` if it evaluates to `true`
|
||||
|
||||
@@ -6,6 +6,7 @@ edges
|
||||
| stdlib.go:43:13:43:18 | selection of Form : Values | stdlib.go:45:23:45:28 | target |
|
||||
| stdlib.go:63:13:63:18 | selection of Form : Values | stdlib.go:66:23:66:40 | ...+... |
|
||||
| stdlib.go:88:13:88:18 | selection of Form : Values | stdlib.go:91:23:91:28 | target |
|
||||
| stdlib.go:133:13:133:18 | selection of Form : Values | stdlib.go:139:23:139:28 | target |
|
||||
nodes
|
||||
| OpenUrlRedirect.go:10:23:10:28 | selection of Form : Values | semmle.label | selection of Form : Values |
|
||||
| OpenUrlRedirect.go:10:23:10:42 | call to Get | semmle.label | call to Get |
|
||||
@@ -21,6 +22,8 @@ nodes
|
||||
| stdlib.go:66:23:66:40 | ...+... | semmle.label | ...+... |
|
||||
| stdlib.go:88:13:88:18 | selection of Form : Values | semmle.label | selection of Form : Values |
|
||||
| stdlib.go:91:23:91:28 | target | semmle.label | target |
|
||||
| stdlib.go:133:13:133:18 | selection of Form : Values | semmle.label | selection of Form : Values |
|
||||
| stdlib.go:139:23:139:28 | target | semmle.label | target |
|
||||
#select
|
||||
| OpenUrlRedirect.go:10:23:10:42 | call to Get | OpenUrlRedirect.go:10:23:10:28 | selection of Form : Values | OpenUrlRedirect.go:10:23:10:42 | call to Get | Untrusted URL redirection due to $@. | OpenUrlRedirect.go:10:23:10:28 | selection of Form | user-provided value |
|
||||
| stdlib.go:14:30:14:35 | target | stdlib.go:12:13:12:18 | selection of Form : Values | stdlib.go:14:30:14:35 | target | Untrusted URL redirection due to $@. | stdlib.go:12:13:12:18 | selection of Form | user-provided value |
|
||||
@@ -29,3 +32,4 @@ nodes
|
||||
| stdlib.go:45:23:45:28 | target | stdlib.go:43:13:43:18 | selection of Form : Values | stdlib.go:45:23:45:28 | target | Untrusted URL redirection due to $@. | stdlib.go:43:13:43:18 | selection of Form | user-provided value |
|
||||
| stdlib.go:66:23:66:40 | ...+... | stdlib.go:63:13:63:18 | selection of Form : Values | stdlib.go:66:23:66:40 | ...+... | Untrusted URL redirection due to $@. | stdlib.go:63:13:63:18 | selection of Form | user-provided value |
|
||||
| stdlib.go:91:23:91:28 | target | stdlib.go:88:13:88:18 | selection of Form : Values | stdlib.go:91:23:91:28 | target | Untrusted URL redirection due to $@. | stdlib.go:88:13:88:18 | selection of Form | user-provided value |
|
||||
| stdlib.go:139:23:139:28 | target | stdlib.go:133:13:133:18 | selection of Form : Values | stdlib.go:139:23:139:28 | target | Untrusted URL redirection due to $@. | stdlib.go:133:13:133:18 | selection of Form | user-provided value |
|
||||
|
||||
@@ -115,5 +115,29 @@ func serveStdlib() {
|
||||
}
|
||||
})
|
||||
|
||||
http.HandleFunc("/ex8", func(w http.ResponseWriter, r *http.Request) {
|
||||
r.ParseForm()
|
||||
|
||||
target := r.Form.Get("target")
|
||||
// GOOD: a check is done on the URL
|
||||
if isValidRedirect(target) {
|
||||
http.Redirect(w, r, target, 302)
|
||||
} else {
|
||||
// ...
|
||||
}
|
||||
})
|
||||
|
||||
http.HandleFunc("/ex9", func(w http.ResponseWriter, r *http.Request) {
|
||||
r.ParseForm()
|
||||
|
||||
target := r.Form.Get("target")
|
||||
// GOOD, but we catch this anyway: a check is done on the URL
|
||||
if !isValidRedirect(target) {
|
||||
target = "/"
|
||||
}
|
||||
|
||||
http.Redirect(w, r, target, 302)
|
||||
})
|
||||
|
||||
http.ListenAndServe(":80", nil)
|
||||
}
|
||||
|
||||
@@ -3,3 +3,8 @@ package main
|
||||
const HASH = "#"
|
||||
|
||||
func someUrl() string { return "semmle.com" }
|
||||
|
||||
// placeholder
|
||||
func isValidRedirect(s string) {
|
||||
return true
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user