diff --git a/ql/src/semmle/go/dataflow/BarrierGuardUtil.qll b/ql/src/semmle/go/dataflow/BarrierGuardUtil.qll index 1f2977d33d3..89f7cb29555 100644 --- a/ql/src/semmle/go/dataflow/BarrierGuardUtil.qll +++ b/ql/src/semmle/go/dataflow/BarrierGuardUtil.qll @@ -10,7 +10,7 @@ import go */ class RedirectCheckBarrierGuard extends DataFlow::BarrierGuard, DataFlow::CallNode { RedirectCheckBarrierGuard() { - this.getCalleeName().regexpMatch("(?i)(is_?)?(local_?url|valid_?redir(ect)?)") + this.getCalleeName().regexpMatch("(?i)(is_?)?(local_?url|valid_?redir(ect)?)(ur[li])?") } override predicate checks(Expr e, boolean outcome) { diff --git a/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/OpenUrlRedirect.expected b/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/OpenUrlRedirect.expected index 67aa2575c29..cd1dcbd3a52 100644 --- a/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/OpenUrlRedirect.expected +++ b/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/OpenUrlRedirect.expected @@ -8,20 +8,20 @@ edges | stdlib.go:89:13:89:18 | selection of Form : Values | stdlib.go:92:23:92:28 | target | | stdlib.go:113:24:113:28 | selection of URL : pointer type | stdlib.go:113:24:113:37 | call to String | | stdlib.go:113:24:113:28 | selection of URL : pointer type | stdlib.go:113:24:113:37 | call to String | -| stdlib.go:134:13:134:18 | selection of Form : Values | stdlib.go:140:23:140:28 | target | -| stdlib.go:147:11:147:15 | selection of URL : pointer type | stdlib.go:147:11:147:15 | selection of URL : pointer type | -| stdlib.go:147:11:147:15 | selection of URL : pointer type | stdlib.go:147:11:147:15 | selection of URL : pointer type | -| stdlib.go:147:11:147:15 | selection of URL : pointer type | stdlib.go:150:24:150:35 | call to String | -| stdlib.go:147:11:147:15 | selection of URL : pointer type | stdlib.go:150:24:150:35 | call to String | -| stdlib.go:161:35:161:39 | selection of URL : pointer type | stdlib.go:161:24:161:52 | ...+... | -| stdlib.go:161:35:161:39 | selection of URL : pointer type | stdlib.go:161:24:161:52 | ...+... | -| stdlib.go:170:13:170:33 | call to FormValue : string | stdlib.go:172:23:172:28 | target | -| stdlib.go:178:36:178:56 | call to FormValue : string | stdlib.go:180:23:180:28 | implicit dereference : URL | -| stdlib.go:178:36:178:56 | call to FormValue : string | stdlib.go:180:23:180:33 | selection of Path | -| stdlib.go:178:36:178:56 | call to FormValue : string | stdlib.go:182:23:182:42 | call to EscapedPath | -| stdlib.go:180:23:180:28 | implicit dereference : URL | stdlib.go:180:23:180:28 | implicit dereference : URL | -| stdlib.go:180:23:180:28 | implicit dereference : URL | stdlib.go:180:23:180:33 | selection of Path | -| stdlib.go:180:23:180:28 | implicit dereference : URL | stdlib.go:182:23:182:42 | call to EscapedPath | +| stdlib.go:146:13:146:18 | selection of Form : Values | stdlib.go:152:23:152:28 | target | +| stdlib.go:159:11:159:15 | selection of URL : pointer type | stdlib.go:159:11:159:15 | selection of URL : pointer type | +| stdlib.go:159:11:159:15 | selection of URL : pointer type | stdlib.go:159:11:159:15 | selection of URL : pointer type | +| stdlib.go:159:11:159:15 | selection of URL : pointer type | stdlib.go:162:24:162:35 | call to String | +| stdlib.go:159:11:159:15 | selection of URL : pointer type | stdlib.go:162:24:162:35 | call to String | +| stdlib.go:173:35:173:39 | selection of URL : pointer type | stdlib.go:173:24:173:52 | ...+... | +| stdlib.go:173:35:173:39 | selection of URL : pointer type | stdlib.go:173:24:173:52 | ...+... | +| stdlib.go:182:13:182:33 | call to FormValue : string | stdlib.go:184:23:184:28 | target | +| stdlib.go:190:36:190:56 | call to FormValue : string | stdlib.go:192:23:192:28 | implicit dereference : URL | +| stdlib.go:190:36:190:56 | call to FormValue : string | stdlib.go:192:23:192:33 | selection of Path | +| stdlib.go:190:36:190:56 | call to FormValue : string | stdlib.go:194:23:194:42 | call to EscapedPath | +| stdlib.go:192:23:192:28 | implicit dereference : URL | stdlib.go:192:23:192:28 | implicit dereference : URL | +| stdlib.go:192:23:192:28 | implicit dereference : URL | stdlib.go:192:23:192:33 | selection of Path | +| stdlib.go:192:23:192:28 | implicit dereference : URL | stdlib.go:194:23:194:42 | call to EscapedPath | 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 | @@ -41,22 +41,22 @@ nodes | stdlib.go:113:24:113:28 | selection of URL : pointer type | semmle.label | selection of URL : pointer type | | stdlib.go:113:24:113:37 | call to String | semmle.label | call to String | | stdlib.go:113:24:113:37 | call to String | semmle.label | call to String | -| stdlib.go:134:13:134:18 | selection of Form : Values | semmle.label | selection of Form : Values | -| stdlib.go:140:23:140:28 | target | semmle.label | target | -| stdlib.go:147:11:147:15 | selection of URL : pointer type | semmle.label | selection of URL : pointer type | -| stdlib.go:147:11:147:15 | selection of URL : pointer type | semmle.label | selection of URL : pointer type | -| stdlib.go:150:24:150:35 | call to String | semmle.label | call to String | -| stdlib.go:150:24:150:35 | call to String | semmle.label | call to String | -| stdlib.go:161:24:161:52 | ...+... | semmle.label | ...+... | -| stdlib.go:161:24:161:52 | ...+... | semmle.label | ...+... | -| stdlib.go:161:35:161:39 | selection of URL : pointer type | semmle.label | selection of URL : pointer type | -| stdlib.go:161:35:161:39 | selection of URL : pointer type | semmle.label | selection of URL : pointer type | -| stdlib.go:170:13:170:33 | call to FormValue : string | semmle.label | call to FormValue : string | -| stdlib.go:172:23:172:28 | target | semmle.label | target | -| stdlib.go:178:36:178:56 | call to FormValue : string | semmle.label | call to FormValue : string | -| stdlib.go:180:23:180:28 | implicit dereference : URL | semmle.label | implicit dereference : URL | -| stdlib.go:180:23:180:33 | selection of Path | semmle.label | selection of Path | -| stdlib.go:182:23:182:42 | call to EscapedPath | semmle.label | call to EscapedPath | +| stdlib.go:146:13:146:18 | selection of Form : Values | semmle.label | selection of Form : Values | +| stdlib.go:152:23:152:28 | target | semmle.label | target | +| stdlib.go:159:11:159:15 | selection of URL : pointer type | semmle.label | selection of URL : pointer type | +| stdlib.go:159:11:159:15 | selection of URL : pointer type | semmle.label | selection of URL : pointer type | +| stdlib.go:162:24:162:35 | call to String | semmle.label | call to String | +| stdlib.go:162:24:162:35 | call to String | semmle.label | call to String | +| stdlib.go:173:24:173:52 | ...+... | semmle.label | ...+... | +| stdlib.go:173:24:173:52 | ...+... | semmle.label | ...+... | +| stdlib.go:173:35:173:39 | selection of URL : pointer type | semmle.label | selection of URL : pointer type | +| stdlib.go:173:35:173:39 | selection of URL : pointer type | semmle.label | selection of URL : pointer type | +| stdlib.go:182:13:182:33 | call to FormValue : string | semmle.label | call to FormValue : string | +| stdlib.go:184:23:184:28 | target | semmle.label | target | +| stdlib.go:190:36:190:56 | call to FormValue : string | semmle.label | call to FormValue : string | +| stdlib.go:192:23:192:28 | implicit dereference : URL | semmle.label | implicit dereference : URL | +| stdlib.go:192:23:192:33 | selection of Path | semmle.label | selection of Path | +| stdlib.go:194:23:194:42 | call to EscapedPath | semmle.label | call to EscapedPath | #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:15:30:15:35 | target | stdlib.go:13:13:13:18 | selection of Form : Values | stdlib.go:15:30:15:35 | target | Untrusted URL redirection due to $@. | stdlib.go:13:13:13:18 | selection of Form | user-provided value | @@ -65,7 +65,7 @@ nodes | stdlib.go:46:23:46:28 | target | stdlib.go:44:13:44:18 | selection of Form : Values | stdlib.go:46:23:46:28 | target | Untrusted URL redirection due to $@. | stdlib.go:44:13:44:18 | selection of Form | user-provided value | | stdlib.go:67:23:67:40 | ...+... | stdlib.go:64:13:64:18 | selection of Form : Values | stdlib.go:67:23:67:40 | ...+... | Untrusted URL redirection due to $@. | stdlib.go:64:13:64:18 | selection of Form | user-provided value | | stdlib.go:92:23:92:28 | target | stdlib.go:89:13:89:18 | selection of Form : Values | stdlib.go:92:23:92:28 | target | Untrusted URL redirection due to $@. | stdlib.go:89:13:89:18 | selection of Form | user-provided value | -| stdlib.go:140:23:140:28 | target | stdlib.go:134:13:134:18 | selection of Form : Values | stdlib.go:140:23:140:28 | target | Untrusted URL redirection due to $@. | stdlib.go:134:13:134:18 | selection of Form | user-provided value | -| stdlib.go:172:23:172:28 | target | stdlib.go:170:13:170:33 | call to FormValue : string | stdlib.go:172:23:172:28 | target | Untrusted URL redirection due to $@. | stdlib.go:170:13:170:33 | call to FormValue | user-provided value | -| stdlib.go:180:23:180:33 | selection of Path | stdlib.go:178:36:178:56 | call to FormValue : string | stdlib.go:180:23:180:33 | selection of Path | Untrusted URL redirection due to $@. | stdlib.go:178:36:178:56 | call to FormValue | user-provided value | -| stdlib.go:182:23:182:42 | call to EscapedPath | stdlib.go:178:36:178:56 | call to FormValue : string | stdlib.go:182:23:182:42 | call to EscapedPath | Untrusted URL redirection due to $@. | stdlib.go:178:36:178:56 | call to FormValue | user-provided value | +| stdlib.go:152:23:152:28 | target | stdlib.go:146:13:146:18 | selection of Form : Values | stdlib.go:152:23:152:28 | target | Untrusted URL redirection due to $@. | stdlib.go:146:13:146:18 | selection of Form | user-provided value | +| stdlib.go:184:23:184:28 | target | stdlib.go:182:13:182:33 | call to FormValue : string | stdlib.go:184:23:184:28 | target | Untrusted URL redirection due to $@. | stdlib.go:182:13:182:33 | call to FormValue | user-provided value | +| stdlib.go:192:23:192:33 | selection of Path | stdlib.go:190:36:190:56 | call to FormValue : string | stdlib.go:192:23:192:33 | selection of Path | Untrusted URL redirection due to $@. | stdlib.go:190:36:190:56 | call to FormValue | user-provided value | +| stdlib.go:194:23:194:42 | call to EscapedPath | stdlib.go:190:36:190:56 | call to FormValue : string | stdlib.go:194:23:194:42 | call to EscapedPath | Untrusted URL redirection due to $@. | stdlib.go:190:36:190:56 | call to FormValue | user-provided value | diff --git a/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/stdlib.go b/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/stdlib.go index 9416a2a5da6..e54b6b8b803 100644 --- a/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/stdlib.go +++ b/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/stdlib.go @@ -128,6 +128,18 @@ func serveStdlib() { } }) + http.HandleFunc("/ex", func(w http.ResponseWriter, r *http.Request) { + r.ParseForm() + + target := r.Form.Get("target") + // GOOD: a check is done on the URL + if isValidRedirectUri(target) { + http.Redirect(w, r, target, 302) + } else { + // ... + } + }) + http.HandleFunc("/ex9", func(w http.ResponseWriter, r *http.Request) { r.ParseForm()