diff --git a/go/ql/lib/ext/clevergo.tech.clevergo.model.yml b/go/ql/lib/ext/clevergo.tech.clevergo.model.yml new file mode 100644 index 000000000000..fdf8b082ca9c --- /dev/null +++ b/go/ql/lib/ext/clevergo.tech.clevergo.model.yml @@ -0,0 +1,12 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: packageGrouping + data: + - ["clever-go", "clevergo.tech/clevergo"] + - ["clever-go", "github.com/clevergo/clevergo"] + - addsTo: + pack: codeql/go-all + extensible: sinkModel + data: + - ["group:clever-go", "Context", True, "Redirect", "", "", "Argument[1]", "url-redirection[receiver]", "manual"] diff --git a/go/ql/lib/ext/github.com.beego.beego.server.web.context.model.yml b/go/ql/lib/ext/github.com.beego.beego.server.web.context.model.yml index 6da9308208ca..e2c856af7e5a 100644 --- a/go/ql/lib/ext/github.com.beego.beego.server.web.context.model.yml +++ b/go/ql/lib/ext/github.com.beego.beego.server.web.context.model.yml @@ -10,7 +10,10 @@ extensions: pack: codeql/go-all extensible: sinkModel data: + # path-injection - ["group:beego-context", "BeegoOutput", False, "Download", "", "", "Argument[0]", "path-injection", "manual"] + # url-redirection + - ["group:beego-context", "Context", True, "Redirect", "", "", "Argument[1]", "url-redirection", "manual"] - addsTo: pack: codeql/go-all extensible: summaryModel diff --git a/go/ql/lib/ext/github.com.beego.beego.server.web.model.yml b/go/ql/lib/ext/github.com.beego.beego.server.web.model.yml index d02fb628127f..c55d620c2e4c 100644 --- a/go/ql/lib/ext/github.com.beego.beego.server.web.model.yml +++ b/go/ql/lib/ext/github.com.beego.beego.server.web.model.yml @@ -27,6 +27,8 @@ extensions: - ["group:beego", "Controller", False, "SaveToFile", "", "", "Argument[1]", "path-injection", "manual"] - ["group:beego", "Controller", False, "SaveToFileWithBuffer", "", "", "Argument[1]", "path-injection", "manual"] # only exists in v2 - ["group:beego", "FileSystem", False, "Open", "", "", "Argument[0]", "path-injection", "manual"] + # url-redirection + - ["group:beego", "Controller", True, "Redirect", "", "", "Argument[0]", "url-redirection", "manual"] - addsTo: pack: codeql/go-all extensible: summaryModel diff --git a/go/ql/lib/ext/github.com.gofiber.fiber.model.yml b/go/ql/lib/ext/github.com.gofiber.fiber.model.yml index 3a5c0ef56ae7..7e553b2156de 100644 --- a/go/ql/lib/ext/github.com.gofiber.fiber.model.yml +++ b/go/ql/lib/ext/github.com.gofiber.fiber.model.yml @@ -3,7 +3,10 @@ extensions: pack: codeql/go-all extensible: sinkModel data: + # path-injection - ["github.com/gofiber/fiber", "Ctx", False, "SendFile", "", "", "Argument[0]", "path-injection", "manual"] - ["github.com/gofiber/fiber", "Ctx", False, "Download", "", "", "Argument[0]", "path-injection", "manual"] - ["github.com/gofiber/fiber", "Ctx", False, "SaveFile", "", "", "Argument[1]", "path-injection", "manual"] - ["github.com/gofiber/fiber", "Ctx", False, "SaveFileToStorage", "", "", "Argument[1]", "path-injection", "manual"] # does not exist in v1 + # url-redirection + - ["github.com/gofiber/fiber", "Ctx", True, "Redirect", "", "", "Argument[0]", "url-redirection[receiver]", "manual"] diff --git a/go/ql/lib/ext/github.com.labstack.echo.model.yml b/go/ql/lib/ext/github.com.labstack.echo.model.yml index 48e5ccd33b58..b497cc133918 100644 --- a/go/ql/lib/ext/github.com.labstack.echo.model.yml +++ b/go/ql/lib/ext/github.com.labstack.echo.model.yml @@ -3,8 +3,11 @@ extensions: pack: codeql/go-all extensible: sinkModel data: + # path-injection - ["github.com/labstack/echo", "Context", False, "Attachment", "", "", "Argument[0]", "path-injection", "manual"] - ["github.com/labstack/echo", "Context", False, "File", "", "", "Argument[0]", "path-injection", "manual"] + # url-redirection + - ["github.com/labstack/echo", "Context", True, "Redirect", "", "", "Argument[1]", "url-redirection", "manual"] - addsTo: pack: codeql/go-all extensible: summaryModel diff --git a/go/ql/lib/ext/github.com.revel.revel.model.yml b/go/ql/lib/ext/github.com.revel.revel.model.yml index 41b5397466cf..acd12f42b1e0 100644 --- a/go/ql/lib/ext/github.com.revel.revel.model.yml +++ b/go/ql/lib/ext/github.com.revel.revel.model.yml @@ -5,6 +5,11 @@ extensions: data: - ["revel", "github.com/revel/revel"] - ["revel", "github.com/robfig/revel"] + - addsTo: + pack: codeql/go-all + extensible: sinkModel + data: + - ["group:revel", "Controller", True, "Redirect", "", "", "Argument[0]", "url-redirection", "manual"] # It is currently assumed that a tainted `value` in `Redirect(url, value)`, which calls `Sprintf(url, value)` internally, cannot lead to an open redirect vulnerability. - addsTo: pack: codeql/go-all extensible: sourceModel diff --git a/go/ql/lib/ext/github.com.valyala.fasthttp.model.yml b/go/ql/lib/ext/github.com.valyala.fasthttp.model.yml index ea6c117f8539..feafceb364df 100644 --- a/go/ql/lib/ext/github.com.valyala.fasthttp.model.yml +++ b/go/ql/lib/ext/github.com.valyala.fasthttp.model.yml @@ -38,6 +38,9 @@ extensions: - ["github.com/valyala/fasthttp", "RequestCtx", False, "SendFile", "", "", "Argument[0]", "path-injection", "manual"] - ["github.com/valyala/fasthttp", "RequestCtx", False, "SendFileBytes", "", "", "Argument[0]", "path-injection", "manual"] - ["github.com/valyala/fasthttp", "Response", False, "SendFile", "", "", "Argument[0]", "path-injection", "manual"] + # url-redirection + - ["github.com/valyala/fasthttp", "RequestCtx", True, "Redirect", "", "", "Argument[0]", "url-redirection", "manual"] + - ["github.com/valyala/fasthttp", "RequestCtx", True, "RedirectBytes", "", "", "Argument[0]", "url-redirection", "manual"] - addsTo: pack: codeql/go-all extensible: summaryModel diff --git a/go/ql/lib/ext/gopkg.in.macaron.model.yml b/go/ql/lib/ext/gopkg.in.macaron.model.yml index fdea494972e9..d0c0a82a462a 100644 --- a/go/ql/lib/ext/gopkg.in.macaron.model.yml +++ b/go/ql/lib/ext/gopkg.in.macaron.model.yml @@ -1,4 +1,9 @@ extensions: + - addsTo: + pack: codeql/go-all + extensible: sinkModel + data: + - ["gopkg.in/macaron", "Context", True, "Redirect", "", "", "Argument[0]", "url-redirection[receiver]", "manual"] - addsTo: pack: codeql/go-all extensible: sourceModel diff --git a/go/ql/lib/ext/net.http.model.yml b/go/ql/lib/ext/net.http.model.yml index 931c56db8048..f67ed795c4cb 100644 --- a/go/ql/lib/ext/net.http.model.yml +++ b/go/ql/lib/ext/net.http.model.yml @@ -3,7 +3,10 @@ extensions: pack: codeql/go-all extensible: sinkModel data: + # path-injection - ["net/http", "", False, "ServeFile", "", "", "Argument[2]", "path-injection", "manual"] + # url-redirection + - ["net/http", "", True, "Redirect", "", "", "Argument[2]", "url-redirection[0]", "manual"] - addsTo: pack: codeql/go-all extensible: summaryModel diff --git a/go/ql/lib/semmle/go/concepts/HTTP.qll b/go/ql/lib/semmle/go/concepts/HTTP.qll index 8337f2ca0d01..50ded3fb59c5 100644 --- a/go/ql/lib/semmle/go/concepts/HTTP.qll +++ b/go/ql/lib/semmle/go/concepts/HTTP.qll @@ -305,6 +305,47 @@ module Http { * open redirect exploits; for example, a form field submitted in a POST request. */ abstract class UnexploitableSource extends DataFlow::Node { } + + private predicate sinkKindInfo(string kind, int rw) { + kind = "url-redirection" and + rw = -2 + or + kind = "url-redirection[receiver]" and + rw = -1 + or + sinkModel(_, _, _, _, _, _, _, kind, _, _) and + exists(string rwStr | + rwStr.toInt() = rw and + kind = "url-redirection[" + rwStr + "]" + ) + } + + private class DefaultHttpRedirect extends Range, DataFlow::CallNode { + DataFlow::ArgumentNode url; + int rw; + + DefaultHttpRedirect() { + this = url.getCall() and + exists(string kind | + sinkKindInfo(kind, rw) and + sinkNode(url, kind) + ) + } + + override DataFlow::Node getUrl() { + not url instanceof DataFlow::ImplicitVarargsSlice and + result = url + or + url instanceof DataFlow::ImplicitVarargsSlice and + result = this.getAnImplicitVarargsArgument() + } + + override Http::ResponseWriter getResponseWriter() { + rw = -1 and result.getANode() = this.getReceiver() + or + rw >= 0 and result.getANode() = this.getArgument(rw) + } + } } /** diff --git a/go/ql/lib/semmle/go/frameworks/Beego.qll b/go/ql/lib/semmle/go/frameworks/Beego.qll index 7a16e0911516..a9e296a1f973 100644 --- a/go/ql/lib/semmle/go/frameworks/Beego.qll +++ b/go/ql/lib/semmle/go/frameworks/Beego.qll @@ -173,29 +173,6 @@ module Beego { } } - private class RedirectMethods extends Http::Redirect::Range, DataFlow::CallNode { - string className; - - RedirectMethods() { - exists(string package | - ( - package = packagePath() and className = "Controller" - or - package = contextPackagePath() and className = "Context" - ) and - this = any(Method m | m.hasQualifiedName(package, className, "Redirect")).getACall() - ) - } - - override DataFlow::Node getUrl() { - className = "Controller" and result = this.getArgument(0) - or - className = "Context" and result = this.getArgument(1) - } - - override Http::ResponseWriter getResponseWriter() { none() } - } - private class UtilsTaintPropagators extends TaintTracking::FunctionModel { UtilsTaintPropagators() { this.hasQualifiedName(utilsPackagePath(), "GetDisplayString") } diff --git a/go/ql/lib/semmle/go/frameworks/Echo.qll b/go/ql/lib/semmle/go/frameworks/Echo.qll index 4c05f0fd6927..a2a6e7d846af 100644 --- a/go/ql/lib/semmle/go/frameworks/Echo.qll +++ b/go/ql/lib/semmle/go/frameworks/Echo.qll @@ -54,21 +54,6 @@ private module Echo { override DataFlow::Node getAContentTypeNode() { result = callNode.getArgument(1) } } - /** - * The `echo.Context.Redirect` method. - */ - private class EchoRedirectMethod extends Http::Redirect::Range, DataFlow::CallNode { - EchoRedirectMethod() { - exists(Method m | m.hasQualifiedName(packagePath(), "Context", "Redirect") | - this = m.getACall() - ) - } - - override DataFlow::Node getUrl() { result = this.getArgument(1) } - - override Http::ResponseWriter getResponseWriter() { none() } - } - /** * DEPRECATED: Use `FileSystemAccess::Range` instead. * diff --git a/go/ql/lib/semmle/go/frameworks/Fasthttp.qll b/go/ql/lib/semmle/go/frameworks/Fasthttp.qll index 8ac4f709fa2d..941e6b44945b 100644 --- a/go/ql/lib/semmle/go/frameworks/Fasthttp.qll +++ b/go/ql/lib/semmle/go/frameworks/Fasthttp.qll @@ -496,22 +496,6 @@ module Fasthttp { override DataFlow::Node getAPathArgument() { result = this.getArgument(0) } } - /** - * The Methods that can be dangerous if they take user controlled URL as their first argument. - */ - class Redirect extends Http::Redirect::Range, DataFlow::CallNode { - Redirect() { - exists(Method m | - m.hasQualifiedName(packagePath(), "RequestCtx", ["Redirect", "RedirectBytes"]) and - this = m.getACall() - ) - } - - override DataFlow::Node getUrl() { result = this.getArgument(0) } - - override Http::ResponseWriter getResponseWriter() { none() } - } - /** * DEPRECATED: Use `RemoteFlowSource` instead. */ diff --git a/go/ql/lib/semmle/go/frameworks/Macaron.qll b/go/ql/lib/semmle/go/frameworks/Macaron.qll index f107ec208ee4..41e95095aa27 100644 --- a/go/ql/lib/semmle/go/frameworks/Macaron.qll +++ b/go/ql/lib/semmle/go/frameworks/Macaron.qll @@ -17,14 +17,4 @@ private module Macaron { override DataFlow::Node getANode() { result = v.similar().getAUse().getASuccessor*() } } - - private class RedirectCall extends Http::Redirect::Range, DataFlow::MethodCallNode { - RedirectCall() { - this.getTarget().hasQualifiedName("gopkg.in/macaron.v1", "Context", "Redirect") - } - - override DataFlow::Node getUrl() { result = this.getArgument(0) } - - override Http::ResponseWriter getResponseWriter() { result.getANode() = this.getReceiver() } - } } diff --git a/go/ql/lib/semmle/go/frameworks/Revel.qll b/go/ql/lib/semmle/go/frameworks/Revel.qll index 874d46bc8380..547c7c6bdac8 100644 --- a/go/ql/lib/semmle/go/frameworks/Revel.qll +++ b/go/ql/lib/semmle/go/frameworks/Revel.qll @@ -87,24 +87,6 @@ module Revel { override string getAContentType() { result = contentType } } - /** - * The `revel.Controller.Redirect` method. - * - * It is currently assumed that a tainted `value` in `Redirect(url, value)`, which calls `Sprintf(url, value)` - * internally, cannot lead to an open redirect vulnerability. - */ - private class ControllerRedirectMethod extends Http::Redirect::Range, DataFlow::CallNode { - ControllerRedirectMethod() { - exists(Method m | m.hasQualifiedName(packagePath(), "Controller", "Redirect") | - this = m.getACall() - ) - } - - override DataFlow::Node getUrl() { result = this.getArgument(0) } - - override Http::ResponseWriter getResponseWriter() { none() } - } - /** * A read in a Revel template that uses Revel's `raw` function. */ diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/NetHttp.qll b/go/ql/lib/semmle/go/frameworks/stdlib/NetHttp.qll index 73991e334f32..deb366b4cdaa 100644 --- a/go/ql/lib/semmle/go/frameworks/stdlib/NetHttp.qll +++ b/go/ql/lib/semmle/go/frameworks/stdlib/NetHttp.qll @@ -175,14 +175,6 @@ module NetHttp { override Http::ResponseWriter getResponseWriter() { result.getANode() = responseWriter } } - private class RedirectCall extends Http::Redirect::Range, DataFlow::CallNode { - RedirectCall() { this.getTarget().hasQualifiedName("net/http", "Redirect") } - - override DataFlow::Node getUrl() { result = this.getArgument(2) } - - override Http::ResponseWriter getResponseWriter() { result.getANode() = this.getArgument(0) } - } - /** A call to a function in the `net/http` package that performs an HTTP request to a URL. */ private class RequestCall extends Http::ClientRequest::Range, DataFlow::CallNode { RequestCall() { diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/Regexp.qll b/go/ql/lib/semmle/go/frameworks/stdlib/Regexp.qll index e3e73c82e6e8..2486bbfe0d34 100644 --- a/go/ql/lib/semmle/go/frameworks/stdlib/Regexp.qll +++ b/go/ql/lib/semmle/go/frameworks/stdlib/Regexp.qll @@ -20,20 +20,18 @@ module Regexp { * function does not compile the regex. */ private predicate regexSinkKindInfo(string kind, int strArg) { + strArg = -3 and + kind = "regex-use" + or sinkModel(_, _, _, _, _, _, _, kind, _, _) and exists(string strArgStr | - ( - strArgStr.toInt() = strArg - or - strArg = -2 and - strArgStr = "c" - ) + strArgStr.toInt() = strArg + or + strArg = -2 and + strArgStr = "c" | kind = "regex-use[" + strArgStr + "]" ) - or - strArg = -3 and - kind = "regex-use" } private class DefaultRegexpPattern extends RegexpPattern::Range, DataFlow::ArgumentNode { diff --git a/go/ql/src/experimental/frameworks/CleverGo.qll b/go/ql/src/experimental/frameworks/CleverGo.qll index b5e269678cdb..c1173186bfd3 100644 --- a/go/ql/src/experimental/frameworks/CleverGo.qll +++ b/go/ql/src/experimental/frameworks/CleverGo.qll @@ -171,25 +171,6 @@ private module CleverGo { } } - /** - * Models HTTP redirects. - */ - private class HttpRedirect extends Http::Redirect::Range, DataFlow::CallNode { - DataFlow::Node urlNode; - - HttpRedirect() { - // HTTP redirect models for package: clevergo.tech/clevergo@v0.5.2 - // Receiver type: Context - // signature: func (*Context) Redirect(code int, url string) error - this = any(Method m | m.hasQualifiedName(packagePath(), "Context", "Redirect")).getACall() and - urlNode = this.getArgument(1) - } - - override DataFlow::Node getUrl() { result = urlNode } - - override Http::ResponseWriter getResponseWriter() { result.getANode() = this.getReceiver() } - } - /** * Models HTTP ResponseBody where the content-type is static and non-modifiable. */ diff --git a/go/ql/src/experimental/frameworks/Fiber.qll b/go/ql/src/experimental/frameworks/Fiber.qll index 72ea1e37c5a0..0d6d27ebd798 100644 --- a/go/ql/src/experimental/frameworks/Fiber.qll +++ b/go/ql/src/experimental/frameworks/Fiber.qll @@ -126,25 +126,6 @@ private module Fiber { } } - /** - * Models HTTP redirects. - */ - private class Redirect extends Http::Redirect::Range, DataFlow::CallNode { - DataFlow::Node urlNode; - - Redirect() { - // HTTP redirect models for package: github.com/gofiber/fiber@v1.14.6 - // Receiver type: Ctx - // signature: func (*Ctx) Redirect(location string, status ...int) - this = any(Method m | m.hasQualifiedName(fiberPackagePath(), "Ctx", "Redirect")).getACall() and - urlNode = this.getArgument(0) - } - - override DataFlow::Node getUrl() { result = urlNode } - - override Http::ResponseWriter getResponseWriter() { result.getANode() = this.getReceiver() } - } - /** * Models HTTP header writers. * The write is done with a call where you can set both the key and the value of the header. diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Echo/OpenRedirect.expected b/go/ql/test/library-tests/semmle/go/frameworks/Echo/OpenRedirect.expected index a80c22d9d603..13ed51b6bd19 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Echo/OpenRedirect.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Echo/OpenRedirect.expected @@ -2,16 +2,17 @@ | test.go:173:20:173:24 | param | test.go:172:11:172:32 | call to Param | test.go:173:20:173:24 | param | This path to an untrusted URL redirection depends on a $@. | test.go:172:11:172:32 | call to Param | user-provided value | | test.go:182:20:182:28 | ...+... | test.go:178:11:178:32 | call to Param | test.go:182:20:182:28 | ...+... | This path to an untrusted URL redirection depends on a $@. | test.go:178:11:178:32 | call to Param | user-provided value | edges -| test.go:172:11:172:32 | call to Param | test.go:173:20:173:24 | param | provenance | Src:MaD:1 | -| test.go:178:11:178:32 | call to Param | test.go:182:24:182:28 | param | provenance | Src:MaD:1 | -| test.go:182:24:182:28 | param | test.go:182:20:182:28 | ...+... | provenance | Config | +| test.go:172:11:172:32 | call to Param | test.go:173:20:173:24 | param | provenance | Src:MaD:2 Sink:MaD:1 | +| test.go:178:11:178:32 | call to Param | test.go:182:24:182:28 | param | provenance | Src:MaD:2 | +| test.go:182:24:182:28 | param | test.go:182:20:182:28 | ...+... | provenance | Config Sink:MaD:1 | | test.go:190:9:190:26 | star expression | test.go:190:10:190:26 | selection of URL | provenance | Config | | test.go:190:9:190:26 | star expression | test.go:193:21:193:23 | url | provenance | | -| test.go:190:10:190:26 | selection of URL | test.go:190:9:190:26 | star expression | provenance | Src:MaD:2 Config | -| test.go:193:21:193:23 | url | test.go:193:21:193:32 | call to String | provenance | Config | +| test.go:190:10:190:26 | selection of URL | test.go:190:9:190:26 | star expression | provenance | Src:MaD:3 Config | +| test.go:193:21:193:23 | url | test.go:193:21:193:32 | call to String | provenance | Config Sink:MaD:1 | models -| 1 | Source: github.com/labstack/echo; Context; true; Param; ; ; ReturnValue[0]; remote; manual | -| 2 | Source: net/http; Request; true; URL; ; ; ; remote; manual | +| 1 | Sink: github.com/labstack/echo; Context; true; Redirect; ; ; Argument[1]; url-redirection; manual | +| 2 | Source: github.com/labstack/echo; Context; true; Param; ; ; ReturnValue[0]; remote; manual | +| 3 | Source: net/http; Request; true; URL; ; ; ; remote; manual | nodes | test.go:172:11:172:32 | call to Param | semmle.label | call to Param | | test.go:173:20:173:24 | param | semmle.label | param | diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Revel/OpenRedirect.expected b/go/ql/test/library-tests/semmle/go/frameworks/Revel/OpenRedirect.expected index 41ec583b6e0c..6e20fd5699ca 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Revel/OpenRedirect.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/Revel/OpenRedirect.expected @@ -3,11 +3,12 @@ edges | EndToEnd.go:94:20:94:27 | implicit dereference | EndToEnd.go:94:20:94:27 | selection of Params | provenance | Config | | EndToEnd.go:94:20:94:27 | implicit dereference | EndToEnd.go:94:20:94:32 | selection of Form | provenance | Config | -| EndToEnd.go:94:20:94:27 | selection of Params | EndToEnd.go:94:20:94:27 | implicit dereference | provenance | Src:MaD:1 Config | -| EndToEnd.go:94:20:94:27 | selection of Params | EndToEnd.go:94:20:94:32 | selection of Form | provenance | Src:MaD:1 Config | -| EndToEnd.go:94:20:94:32 | selection of Form | EndToEnd.go:94:20:94:49 | call to Get | provenance | Config | +| EndToEnd.go:94:20:94:27 | selection of Params | EndToEnd.go:94:20:94:27 | implicit dereference | provenance | Src:MaD:2 Config | +| EndToEnd.go:94:20:94:27 | selection of Params | EndToEnd.go:94:20:94:32 | selection of Form | provenance | Src:MaD:2 Config | +| EndToEnd.go:94:20:94:32 | selection of Form | EndToEnd.go:94:20:94:49 | call to Get | provenance | Config Sink:MaD:1 | models -| 1 | Source: group:revel; Controller; true; Params; ; ; ; remote; manual | +| 1 | Sink: group:revel; Controller; true; Redirect; ; ; Argument[0]; url-redirection; manual | +| 2 | Source: group:revel; Controller; true; Params; ; ; ; remote; manual | nodes | EndToEnd.go:94:20:94:27 | implicit dereference | semmle.label | implicit dereference | | EndToEnd.go:94:20:94:27 | selection of Params | semmle.label | selection of Params | diff --git a/go/ql/test/query-tests/Security/CWE-601/BadRedirectCheck/BadRedirectCheck.expected b/go/ql/test/query-tests/Security/CWE-601/BadRedirectCheck/BadRedirectCheck.expected index 0a02a1ee91a6..b82496d5e38c 100644 --- a/go/ql/test/query-tests/Security/CWE-601/BadRedirectCheck/BadRedirectCheck.expected +++ b/go/ql/test/query-tests/Security/CWE-601/BadRedirectCheck/BadRedirectCheck.expected @@ -11,25 +11,26 @@ edges | BadRedirectCheck.go:3:18:3:22 | argument corresponding to redir | BadRedirectCheck.go:5:10:5:14 | redir | provenance | | | BadRedirectCheck.go:3:18:3:22 | definition of redir | BadRedirectCheck.go:5:10:5:14 | redir | provenance | | -| BadRedirectCheck.go:5:10:5:14 | redir | main.go:11:25:11:45 | call to sanitizeUrl | provenance | | -| cves.go:14:23:14:25 | argument corresponding to url | cves.go:16:26:16:28 | url | provenance | | -| cves.go:33:14:33:34 | call to Get | cves.go:37:25:37:32 | redirect | provenance | | -| cves.go:41:14:41:34 | call to Get | cves.go:45:25:45:32 | redirect | provenance | | +| BadRedirectCheck.go:5:10:5:14 | redir | main.go:11:25:11:45 | call to sanitizeUrl | provenance | Sink:MaD:1 | +| cves.go:14:23:14:25 | argument corresponding to url | cves.go:16:26:16:28 | url | provenance | Sink:MaD:1 | +| cves.go:33:14:33:34 | call to Get | cves.go:37:25:37:32 | redirect | provenance | Sink:MaD:1 | +| cves.go:41:14:41:34 | call to Get | cves.go:45:25:45:32 | redirect | provenance | Sink:MaD:1 | | main.go:10:18:10:25 | argument corresponding to redirect | main.go:11:37:11:44 | redirect | provenance | | | main.go:11:37:11:44 | redirect | BadRedirectCheck.go:3:18:3:22 | definition of redir | provenance | | -| main.go:11:37:11:44 | redirect | main.go:11:25:11:45 | call to sanitizeUrl | provenance | | -| main.go:32:24:32:26 | argument corresponding to url | main.go:34:26:34:28 | url | provenance | | +| main.go:11:37:11:44 | redirect | main.go:11:25:11:45 | call to sanitizeUrl | provenance | Sink:MaD:1 | +| main.go:32:24:32:26 | argument corresponding to url | main.go:34:26:34:28 | url | provenance | Sink:MaD:1 | | main.go:68:17:68:24 | argument corresponding to redirect | main.go:73:20:73:27 | redirect | provenance | | | main.go:68:17:68:24 | definition of redirect | main.go:73:20:73:27 | redirect | provenance | | -| main.go:73:9:73:28 | call to Clean | main.go:77:25:77:39 | call to getTarget1 | provenance | | -| main.go:73:20:73:27 | redirect | main.go:73:9:73:28 | call to Clean | provenance | MaD:1 | -| main.go:73:20:73:27 | redirect | main.go:73:9:73:28 | call to Clean | provenance | MaD:1 | +| main.go:73:9:73:28 | call to Clean | main.go:77:25:77:39 | call to getTarget1 | provenance | Sink:MaD:1 | +| main.go:73:20:73:27 | redirect | main.go:73:9:73:28 | call to Clean | provenance | MaD:2 | +| main.go:73:20:73:27 | redirect | main.go:73:9:73:28 | call to Clean | provenance | MaD:2 | | main.go:76:19:76:21 | argument corresponding to url | main.go:77:36:77:38 | url | provenance | | | main.go:77:36:77:38 | url | main.go:68:17:68:24 | definition of redirect | provenance | | -| main.go:77:36:77:38 | url | main.go:77:25:77:39 | call to getTarget1 | provenance | MaD:1 | -| main.go:87:9:87:14 | selection of Path | main.go:91:25:91:39 | call to getTarget2 | provenance | | +| main.go:77:36:77:38 | url | main.go:77:25:77:39 | call to getTarget1 | provenance | MaD:2 Sink:MaD:1 | +| main.go:87:9:87:14 | selection of Path | main.go:91:25:91:39 | call to getTarget2 | provenance | Sink:MaD:1 | models -| 1 | Summary: path; ; false; Clean; ; ; Argument[0]; ReturnValue; taint; manual | +| 1 | Sink: net/http; ; true; Redirect; ; ; Argument[2]; url-redirection[0]; manual | +| 2 | Summary: path; ; false; Clean; ; ; Argument[0]; ReturnValue; taint; manual | nodes | BadRedirectCheck.go:3:18:3:22 | argument corresponding to redir | semmle.label | argument corresponding to redir | | BadRedirectCheck.go:3:18:3:22 | definition of redir | semmle.label | definition of redir | diff --git a/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/OpenUrlRedirect.expected b/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/OpenUrlRedirect.expected index 02f015514b8c..7c7acaa3f850 100644 --- a/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/OpenUrlRedirect.expected +++ b/go/ql/test/query-tests/Security/CWE-601/OpenUrlRedirect/OpenUrlRedirect.expected @@ -11,24 +11,24 @@ | stdlib.go:192:23:192:33 | selection of Path | stdlib.go:190:36:190:56 | call to FormValue | stdlib.go:192:23:192:33 | selection of Path | This path to an untrusted URL redirection depends on a $@. | 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 | stdlib.go:194:23:194:42 | call to EscapedPath | This path to an untrusted URL redirection depends on a $@. | stdlib.go:190:36:190:56 | call to FormValue | user-provided value | edges -| OpenUrlRedirect.go:10:23:10:28 | selection of Form | OpenUrlRedirect.go:10:23:10:42 | call to Get | provenance | Src:MaD:2 Config | -| stdlib.go:13:13:13:18 | selection of Form | stdlib.go:13:13:13:32 | call to Get | provenance | Src:MaD:2 Config | +| OpenUrlRedirect.go:10:23:10:28 | selection of Form | OpenUrlRedirect.go:10:23:10:42 | call to Get | provenance | Src:MaD:3 Config Sink:MaD:1 | +| stdlib.go:13:13:13:18 | selection of Form | stdlib.go:13:13:13:32 | call to Get | provenance | Src:MaD:3 Config | | stdlib.go:13:13:13:32 | call to Get | stdlib.go:15:30:15:35 | target | provenance | | -| stdlib.go:22:13:22:18 | selection of Form | stdlib.go:22:13:22:32 | call to Get | provenance | Src:MaD:2 Config | +| stdlib.go:22:13:22:18 | selection of Form | stdlib.go:22:13:22:32 | call to Get | provenance | Src:MaD:3 Config | | stdlib.go:22:13:22:32 | call to Get | stdlib.go:24:30:24:35 | target | provenance | | -| stdlib.go:31:13:31:18 | selection of Form | stdlib.go:31:13:31:32 | call to Get | provenance | Src:MaD:2 Config | +| stdlib.go:31:13:31:18 | selection of Form | stdlib.go:31:13:31:32 | call to Get | provenance | Src:MaD:3 Config | | stdlib.go:31:13:31:32 | call to Get | stdlib.go:35:34:35:39 | target | provenance | | | stdlib.go:35:34:35:39 | target | stdlib.go:35:30:35:39 | ...+... | provenance | Config | -| stdlib.go:44:13:44:18 | selection of Form | stdlib.go:44:13:44:32 | call to Get | provenance | Src:MaD:2 Config | -| stdlib.go:44:13:44:32 | call to Get | stdlib.go:46:23:46:28 | target | provenance | | -| stdlib.go:64:13:64:18 | selection of Form | stdlib.go:64:13:64:32 | call to Get | provenance | Src:MaD:2 Config | +| stdlib.go:44:13:44:18 | selection of Form | stdlib.go:44:13:44:32 | call to Get | provenance | Src:MaD:3 Config | +| stdlib.go:44:13:44:32 | call to Get | stdlib.go:46:23:46:28 | target | provenance | Sink:MaD:1 | +| stdlib.go:64:13:64:18 | selection of Form | stdlib.go:64:13:64:32 | call to Get | provenance | Src:MaD:3 Config | | stdlib.go:64:13:64:32 | call to Get | stdlib.go:67:23:67:28 | target | provenance | | | stdlib.go:67:23:67:28 | target | stdlib.go:67:23:67:37 | ...+... | provenance | Config | -| stdlib.go:67:23:67:37 | ...+... | stdlib.go:67:23:67:40 | ...+... | provenance | Config | -| stdlib.go:89:13:89:18 | selection of Form | stdlib.go:89:13:89:32 | call to Get | provenance | Src:MaD:2 Config | +| stdlib.go:67:23:67:37 | ...+... | stdlib.go:67:23:67:40 | ...+... | provenance | Config Sink:MaD:1 | +| stdlib.go:89:13:89:18 | selection of Form | stdlib.go:89:13:89:32 | call to Get | provenance | Src:MaD:3 Config | | stdlib.go:89:13:89:32 | call to Get | stdlib.go:90:3:90:8 | target | provenance | | | stdlib.go:90:3:90:8 | target | stdlib.go:90:3:90:25 | ... += ... | provenance | Config | -| stdlib.go:90:3:90:25 | ... += ... | stdlib.go:92:23:92:28 | target | provenance | | +| stdlib.go:90:3:90:25 | ... += ... | stdlib.go:92:23:92:28 | target | provenance | Sink:MaD:1 | | stdlib.go:107:54:107:54 | definition of r [pointer, URL, pointer] | stdlib.go:112:4:112:4 | r [pointer, URL, pointer] | provenance | | | stdlib.go:107:54:107:54 | definition of r [pointer, URL] | stdlib.go:112:4:112:4 | r [pointer, URL] | provenance | | | stdlib.go:107:54:107:54 | definition of r [pointer, URL] | stdlib.go:113:24:113:24 | r [pointer, URL] | provenance | | @@ -40,35 +40,36 @@ edges | stdlib.go:112:4:112:4 | r [pointer, URL] | stdlib.go:112:4:112:4 | implicit dereference [URL] | provenance | | | stdlib.go:112:4:112:8 | implicit dereference | stdlib.go:112:4:112:8 | selection of URL | provenance | Config | | stdlib.go:112:4:112:8 | implicit dereference | stdlib.go:112:4:112:8 | selection of URL [pointer] | provenance | | -| stdlib.go:112:4:112:8 | selection of URL | stdlib.go:112:4:112:4 | implicit dereference [URL] | provenance | Src:MaD:3 | -| stdlib.go:112:4:112:8 | selection of URL | stdlib.go:112:4:112:8 | implicit dereference | provenance | Src:MaD:3 Config | +| stdlib.go:112:4:112:8 | selection of URL | stdlib.go:112:4:112:4 | implicit dereference [URL] | provenance | Src:MaD:4 | +| stdlib.go:112:4:112:8 | selection of URL | stdlib.go:112:4:112:8 | implicit dereference | provenance | Src:MaD:4 Config | | stdlib.go:112:4:112:8 | selection of URL [pointer] | stdlib.go:112:4:112:4 | implicit dereference [URL, pointer] | provenance | | | stdlib.go:112:4:112:8 | selection of URL [pointer] | stdlib.go:112:4:112:8 | implicit dereference | provenance | | | stdlib.go:113:24:113:24 | implicit dereference [URL] | stdlib.go:113:24:113:28 | selection of URL | provenance | | | stdlib.go:113:24:113:24 | r [pointer, URL] | stdlib.go:113:24:113:24 | implicit dereference [URL] | provenance | | -| stdlib.go:113:24:113:28 | selection of URL | stdlib.go:113:24:113:37 | call to String | provenance | Src:MaD:3 Config | -| stdlib.go:146:13:146:18 | selection of Form | stdlib.go:146:13:146:32 | call to Get | provenance | Src:MaD:2 Config | -| stdlib.go:146:13:146:32 | call to Get | stdlib.go:152:23:152:28 | target | provenance | | +| stdlib.go:113:24:113:28 | selection of URL | stdlib.go:113:24:113:37 | call to String | provenance | Src:MaD:4 Config Sink:MaD:1 | +| stdlib.go:146:13:146:18 | selection of Form | stdlib.go:146:13:146:32 | call to Get | provenance | Src:MaD:3 Config | +| stdlib.go:146:13:146:32 | call to Get | stdlib.go:152:23:152:28 | target | provenance | Sink:MaD:1 | | stdlib.go:159:10:159:15 | star expression | stdlib.go:159:11:159:15 | selection of URL | provenance | Config | | stdlib.go:159:10:159:15 | star expression | stdlib.go:162:24:162:26 | url | provenance | | -| stdlib.go:159:11:159:15 | selection of URL | stdlib.go:159:10:159:15 | star expression | provenance | Src:MaD:3 Config | -| stdlib.go:162:24:162:26 | url | stdlib.go:162:24:162:35 | call to String | provenance | Config | -| stdlib.go:173:35:173:39 | selection of URL | stdlib.go:173:35:173:52 | call to RequestURI | provenance | Src:MaD:3 Config | -| stdlib.go:173:35:173:52 | call to RequestURI | stdlib.go:173:24:173:52 | ...+... | provenance | Config | -| stdlib.go:182:13:182:33 | call to FormValue | stdlib.go:184:23:184:28 | target | provenance | Src:MaD:1 | +| stdlib.go:159:11:159:15 | selection of URL | stdlib.go:159:10:159:15 | star expression | provenance | Src:MaD:4 Config | +| stdlib.go:162:24:162:26 | url | stdlib.go:162:24:162:35 | call to String | provenance | Config Sink:MaD:1 | +| stdlib.go:173:35:173:39 | selection of URL | stdlib.go:173:35:173:52 | call to RequestURI | provenance | Src:MaD:4 Config | +| stdlib.go:173:35:173:52 | call to RequestURI | stdlib.go:173:24:173:52 | ...+... | provenance | Config Sink:MaD:1 | +| stdlib.go:182:13:182:33 | call to FormValue | stdlib.go:184:23:184:28 | target | provenance | Src:MaD:2 Sink:MaD:1 | | stdlib.go:190:3:190:8 | definition of target | stdlib.go:192:23:192:28 | target | provenance | | | stdlib.go:190:3:190:8 | definition of target | stdlib.go:194:23:194:28 | target | provenance | | | stdlib.go:190:3:190:57 | ... := ...[0] | stdlib.go:190:3:190:8 | definition of target | provenance | | -| stdlib.go:190:36:190:56 | call to FormValue | stdlib.go:190:3:190:57 | ... := ...[0] | provenance | Src:MaD:1 Config | +| stdlib.go:190:36:190:56 | call to FormValue | stdlib.go:190:3:190:57 | ... := ...[0] | provenance | Src:MaD:2 Config | | stdlib.go:192:23:192:28 | implicit dereference | stdlib.go:190:3:190:8 | definition of target | provenance | Config | -| stdlib.go:192:23:192:28 | implicit dereference | stdlib.go:192:23:192:33 | selection of Path | provenance | Config | +| stdlib.go:192:23:192:28 | implicit dereference | stdlib.go:192:23:192:33 | selection of Path | provenance | Config Sink:MaD:1 | | stdlib.go:192:23:192:28 | target | stdlib.go:192:23:192:28 | implicit dereference | provenance | Config | -| stdlib.go:192:23:192:28 | target | stdlib.go:192:23:192:33 | selection of Path | provenance | Config | -| stdlib.go:194:23:194:28 | target | stdlib.go:194:23:194:42 | call to EscapedPath | provenance | Config | +| stdlib.go:192:23:192:28 | target | stdlib.go:192:23:192:33 | selection of Path | provenance | Config Sink:MaD:1 | +| stdlib.go:194:23:194:28 | target | stdlib.go:194:23:194:42 | call to EscapedPath | provenance | Config Sink:MaD:1 | models -| 1 | Source: net/http; Request; true; FormValue; ; ; ReturnValue; remote; manual | -| 2 | Source: net/http; Request; true; Form; ; ; ; remote; manual | -| 3 | Source: net/http; Request; true; URL; ; ; ; remote; manual | +| 1 | Sink: net/http; ; true; Redirect; ; ; Argument[2]; url-redirection[0]; manual | +| 2 | Source: net/http; Request; true; FormValue; ; ; ReturnValue; remote; manual | +| 3 | Source: net/http; Request; true; Form; ; ; ; remote; manual | +| 4 | Source: net/http; Request; true; URL; ; ; ; remote; manual | nodes | OpenUrlRedirect.go:10:23:10:28 | selection of Form | semmle.label | selection of Form | | OpenUrlRedirect.go:10:23:10:42 | call to Get | semmle.label | call to Get |