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/ext/regexp.model.yml b/go/ql/lib/ext/regexp.model.yml index 281bd2e81704..ffb6205657a6 100644 --- a/go/ql/lib/ext/regexp.model.yml +++ b/go/ql/lib/ext/regexp.model.yml @@ -1,4 +1,18 @@ extensions: + - addsTo: + pack: codeql/go-all + extensible: sinkModel + data: + - ["regexp", "", True, "Compile", "", "", "Argument[0]", "regex-use[c]", "manual"] + - ["regexp", "", True, "CompilePOSIX", "", "", "Argument[0]", "regex-use[c]", "manual"] + - ["regexp", "", True, "MustCompile", "", "", "Argument[0]", "regex-use[c]", "manual"] + - ["regexp", "", True, "MustCompilePOSIX", "", "", "Argument[0]", "regex-use[c]", "manual"] + - ["regexp", "", True, "Match", "", "", "Argument[0]", "regex-use[1]", "manual"] + - ["regexp", "", True, "MatchReader", "", "", "Argument[0]", "regex-use[1]", "manual"] + - ["regexp", "", True, "MatchString", "", "", "Argument[0]", "regex-use[1]", "manual"] + - ["regexp", "Regexp", True, "Match", "", "", "Argument[receiver]", "regex-use[0]", "manual"] + - ["regexp", "Regexp", True, "MatchReader", "", "", "Argument[receiver]", "regex-use[0]", "manual"] + - ["regexp", "Regexp", True, "MatchString", "", "", "Argument[receiver]", "regex-use[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 570aa9d4e7bc..525eb73d5b96 100644 --- a/go/ql/lib/semmle/go/frameworks/stdlib/Regexp.qll +++ b/go/ql/lib/semmle/go/frameworks/stdlib/Regexp.qll @@ -6,13 +6,46 @@ import go /** Provides models of commonly used functions in the `regexp` package. */ module Regexp { - private class Pattern extends RegexpPattern::Range, DataFlow::ArgumentNode { - string fnName; + /** + * Holds if `kind` is an external sink kind that is relevant for regex flow. + * `strArg` is the index of the argument to methods with this sink kind that + * contain the string to be matched against, where "receiver" indicates the + * receiver; or -2 if no such argument exists and the function compiles the + * regex; or -3 if no such argument exists and the function does not compile + * the regex. + * + * So `regex-use[0]` indicates that argument 0 contains the string to matched + * against, `regex-use[c]` indicates that there is no string to be matched + * against and the return value of the function is a compiled regex, and + * `regex-use` means that there is no string to be matched against and the + * 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 | + strArg >= 0 and + strArgStr.toInt() = strArg + or + strArg = -1 and + strArgStr = "receiver" + or + strArg = -2 and + strArgStr = "c" + | + kind = "regex-use[" + strArgStr + "]" + ) + } + + private class DefaultRegexpPattern extends RegexpPattern::Range, DataFlow::ArgumentNode { + int strArg; - Pattern() { - exists(Function fn | fnName.matches("Match%") or fnName.matches("%Compile%") | - fn.hasQualifiedName("regexp", fnName) and - this = fn.getACall().getArgument(0) + DefaultRegexpPattern() { + exists(string kind | + regexSinkKindInfo(kind, strArg) and + sinkNode(this, kind) ) } @@ -21,38 +54,37 @@ module Regexp { override string getPattern() { result = this.asExpr().getStringValue() } override DataFlow::Node getAUse() { - fnName.matches("MustCompile%") and - result = this.getCall().getASuccessor*() - or - fnName.matches("Compile%") and + strArg = -2 and result = this.getCall().getResult(0).getASuccessor*() or result = this } } - private class MatchFunction extends RegexpMatchFunction::Range, Function { - MatchFunction() { - exists(string fn | fn.matches("Match%") | this.hasQualifiedName("regexp", fn)) + private class DefaultRegexpMatchFunction extends RegexpMatchFunction::Range, Function { + int patArg; + int strArg; + + DefaultRegexpMatchFunction() { + exists(DefaultRegexpPattern drp, string kind | + drp.getCall() = this.getACall() and + sinkNode(drp, kind) + | + patArg = drp.getPosition() and + regexSinkKindInfo(kind, strArg) and + strArg >= -1 + ) } - override FunctionInput getRegexpArg() { result.isParameter(0) } - - override FunctionInput getValue() { result.isParameter(1) } - - override FunctionOutput getResult() { result.isResult(0) } - } - - private class MatchMethod extends RegexpMatchFunction::Range, Method { - MatchMethod() { - exists(string fn | fn.matches("Match%") | this.hasQualifiedName("regexp", "Regexp", fn)) + override FunctionInput getRegexpArg() { + patArg = -1 and result.isReceiver() + or + patArg >= 0 and result.isParameter(patArg) } - override FunctionInput getRegexpArg() { result.isReceiver() } - - override FunctionInput getValue() { result.isParameter(0) } + override FunctionInput getValue() { result.isParameter(strArg) } - override FunctionOutput getResult() { result.isResult() } + override FunctionOutput getResult() { result.isResult(0) } } private class ReplaceFunction extends RegexpReplaceFunction::Range, Method { 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/concepts/Regexp/RegexpMatchFunction.expected b/go/ql/test/library-tests/semmle/go/concepts/Regexp/RegexpMatchFunction.expected index 7182e57a8628..21f2e0b72f41 100644 --- a/go/ql/test/library-tests/semmle/go/concepts/Regexp/RegexpMatchFunction.expected +++ b/go/ql/test/library-tests/semmle/go/concepts/Regexp/RegexpMatchFunction.expected @@ -1,3 +1,6 @@ | file://:0:0:0:0 | Match | stdlib.go:16:30:16:37 | "posix?" | stdlib.go:28:11:28:24 | type conversion | stdlib.go:28:2:28:25 | call to Match | +| file://:0:0:0:0 | Match | stdlib.go:28:2:28:3 | re | stdlib.go:28:11:28:24 | type conversion | stdlib.go:28:2:28:25 | call to Match | | file://:0:0:0:0 | MatchReader | stdlib.go:16:30:16:37 | "posix?" | stdlib.go:29:17:29:37 | call to NewReader | stdlib.go:29:2:29:38 | call to MatchReader | +| file://:0:0:0:0 | MatchReader | stdlib.go:29:2:29:3 | re | stdlib.go:29:17:29:37 | call to NewReader | stdlib.go:29:2:29:38 | call to MatchReader | | file://:0:0:0:0 | MatchString | stdlib.go:16:30:16:37 | "posix?" | stdlib.go:17:17:17:22 | "posi" | stdlib.go:17:2:17:23 | call to MatchString | +| file://:0:0:0:0 | MatchString | stdlib.go:17:2:17:3 | re | stdlib.go:17:17:17:22 | "posi" | stdlib.go:17:2:17:23 | call to MatchString | 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-020/IncompleteHostnameRegexp/IncompleteHostnameRegexp.expected b/go/ql/test/query-tests/Security/CWE-020/IncompleteHostnameRegexp/IncompleteHostnameRegexp.expected index c9ba782fd56b..650fb67ad953 100644 --- a/go/ql/test/query-tests/Security/CWE-020/IncompleteHostnameRegexp/IncompleteHostnameRegexp.expected +++ b/go/ql/test/query-tests/Security/CWE-020/IncompleteHostnameRegexp/IncompleteHostnameRegexp.expected @@ -1,7 +1,17 @@ +#select +| IncompleteHostnameRegexp.go:11:8:11:36 | "^((www\|beta).)?example.com/" | IncompleteHostnameRegexp.go:11:8:11:36 | "^((www\|beta).)?example.com/" | IncompleteHostnameRegexp.go:12:38:12:39 | re | This regular expression has an unescaped dot before ')?example.com', so it might match more hosts than expected when $@. | IncompleteHostnameRegexp.go:12:38:12:39 | re | the regular expression is used | +| main.go:40:60:40:79 | "^test2.github.com$" | main.go:40:60:40:79 | "^test2.github.com$" | main.go:40:60:40:79 | "^test2.github.com$" | This regular expression has an unescaped dot before 'github.com', so it might match more hosts than expected when $@. | main.go:40:60:40:79 | "^test2.github.com$" | the regular expression is used | +| main.go:45:15:45:39 | `https://www.example.com` | main.go:45:15:45:39 | `https://www.example.com` | main.go:45:15:45:39 | `https://www.example.com` | This regular expression has an unescaped dot before 'example.com', so it might match more hosts than expected when $@. | main.go:45:15:45:39 | `https://www.example.com` | the regular expression is used | +| main.go:49:21:49:45 | `https://www.example.com` | main.go:49:21:49:45 | `https://www.example.com` | main.go:65:15:65:23 | localVar3 | This regular expression has an unescaped dot before 'example.com', so it might match more hosts than expected when $@. | main.go:65:15:65:23 | localVar3 | the regular expression is used | +| main.go:56:15:56:34 | ...+... | main.go:56:15:56:34 | ...+... | main.go:56:15:56:34 | ...+... | This regular expression has an unescaped dot before 'example.com', so it might match more hosts than expected when $@. | main.go:56:15:56:34 | ...+... | the regular expression is used | +| main.go:58:15:58:42 | ...+... | main.go:58:15:58:42 | ...+... | main.go:58:15:58:42 | ...+... | This regular expression has an unescaped dot before 'example.com', so it might match more hosts than expected when $@. | main.go:58:15:58:42 | ...+... | the regular expression is used | edges -| IncompleteHostnameRegexp.go:11:8:11:36 | "^((www\|beta).)?example.com/" | IncompleteHostnameRegexp.go:12:38:12:39 | re | provenance | | +| IncompleteHostnameRegexp.go:11:8:11:36 | "^((www\|beta).)?example.com/" | IncompleteHostnameRegexp.go:12:38:12:39 | re | provenance | Sink:MaD:2 | | main.go:49:21:49:45 | `https://www.example.com` | main.go:62:15:62:25 | sourceConst | provenance | | -| main.go:62:15:62:25 | sourceConst | main.go:65:15:65:23 | localVar3 | provenance | | +| main.go:62:15:62:25 | sourceConst | main.go:65:15:65:23 | localVar3 | provenance | Sink:MaD:1 | +models +| 1 | Sink: regexp; ; true; Match; ; ; Argument[0]; regex-use[1]; manual | +| 2 | Sink: regexp; ; true; MatchString; ; ; Argument[0]; regex-use[1]; manual | nodes | IncompleteHostnameRegexp.go:11:8:11:36 | "^((www\|beta).)?example.com/" | semmle.label | "^((www\|beta).)?example.com/" | | IncompleteHostnameRegexp.go:12:38:12:39 | re | semmle.label | re | @@ -13,10 +23,3 @@ nodes | main.go:62:15:62:25 | sourceConst | semmle.label | sourceConst | | main.go:65:15:65:23 | localVar3 | semmle.label | localVar3 | subpaths -#select -| IncompleteHostnameRegexp.go:11:8:11:36 | "^((www\|beta).)?example.com/" | IncompleteHostnameRegexp.go:11:8:11:36 | "^((www\|beta).)?example.com/" | IncompleteHostnameRegexp.go:12:38:12:39 | re | This regular expression has an unescaped dot before ')?example.com', so it might match more hosts than expected when $@. | IncompleteHostnameRegexp.go:12:38:12:39 | re | the regular expression is used | -| main.go:40:60:40:79 | "^test2.github.com$" | main.go:40:60:40:79 | "^test2.github.com$" | main.go:40:60:40:79 | "^test2.github.com$" | This regular expression has an unescaped dot before 'github.com', so it might match more hosts than expected when $@. | main.go:40:60:40:79 | "^test2.github.com$" | the regular expression is used | -| main.go:45:15:45:39 | `https://www.example.com` | main.go:45:15:45:39 | `https://www.example.com` | main.go:45:15:45:39 | `https://www.example.com` | This regular expression has an unescaped dot before 'example.com', so it might match more hosts than expected when $@. | main.go:45:15:45:39 | `https://www.example.com` | the regular expression is used | -| main.go:49:21:49:45 | `https://www.example.com` | main.go:49:21:49:45 | `https://www.example.com` | main.go:65:15:65:23 | localVar3 | This regular expression has an unescaped dot before 'example.com', so it might match more hosts than expected when $@. | main.go:65:15:65:23 | localVar3 | the regular expression is used | -| main.go:56:15:56:34 | ...+... | main.go:56:15:56:34 | ...+... | main.go:56:15:56:34 | ...+... | This regular expression has an unescaped dot before 'example.com', so it might match more hosts than expected when $@. | main.go:56:15:56:34 | ...+... | the regular expression is used | -| main.go:58:15:58:42 | ...+... | main.go:58:15:58:42 | ...+... | main.go:58:15:58:42 | ...+... | This regular expression has an unescaped dot before 'example.com', so it might match more hosts than expected when $@. | main.go:58:15:58:42 | ...+... | the regular expression is used | diff --git a/go/ql/test/query-tests/Security/CWE-020/IncompleteHostnameRegexp/IncompleteHostnameRegexp.qlref b/go/ql/test/query-tests/Security/CWE-020/IncompleteHostnameRegexp/IncompleteHostnameRegexp.qlref index a79201052b99..fdf18ea380ad 100644 --- a/go/ql/test/query-tests/Security/CWE-020/IncompleteHostnameRegexp/IncompleteHostnameRegexp.qlref +++ b/go/ql/test/query-tests/Security/CWE-020/IncompleteHostnameRegexp/IncompleteHostnameRegexp.qlref @@ -1 +1,2 @@ -Security/CWE-020/IncompleteHostnameRegexp.ql +query: Security/CWE-020/IncompleteHostnameRegexp.ql +postprocess: TestUtilities/PrettyPrintModels.ql 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 | diff --git a/shared/mad/codeql/mad/ModelValidation.qll b/shared/mad/codeql/mad/ModelValidation.qll index 7bfdc69b5692..c28fc421d972 100644 --- a/shared/mad/codeql/mad/ModelValidation.qll +++ b/shared/mad/codeql/mad/ModelValidation.qll @@ -28,13 +28,13 @@ module KindValidation { // shared "code-injection", "command-injection", "environment-injection", "file-content-store", "html-injection", "js-injection", "ldap-injection", "log-injection", "path-injection", - "request-forgery", "sql-injection", "url-redirection", + "request-forgery", "sql-injection", "url-redirection", "xpath-injection", // Java-only currently, but may be shared in the future "bean-validation", "fragment-injection", "groovy-injection", "hostname-verification", "information-leak", "intent-redirection", "jexl-injection", "jndi-injection", "mvel-injection", "notification", "ognl-injection", "pending-intents", "response-splitting", "trust-boundary-violation", "template-injection", "url-forward", - "xpath-injection", "xslt-injection", + "xslt-injection", // JavaScript-only currently, but may be shared in the future "mongodb.sink", "nosql-injection", "unsafe-deserialization", // Swift-only currently, but may be shared in the future @@ -48,13 +48,11 @@ module KindValidation { or this.matches([ // shared - "credentials-%", "encryption-%", "qltest%", "test-%", - // Java-only currently, but may be shared in the future - "regex-use%", + "credentials-%", "encryption-%", "qltest%", "test-%", "regex-use%", // Swift-only currently, but may be shared in the future "%string-%length", "weak-hash-input-%", // Go-only currently, but may be shared in the future - "request-forgery%" + "request-forgery[%]", "url-redirection[%]" ]) } }