diff --git a/ql/src/semmle/go/Packages.qll b/ql/src/semmle/go/Packages.qll index a88cc2a7368..0b134110ae1 100644 --- a/ql/src/semmle/go/Packages.qll +++ b/ql/src/semmle/go/Packages.qll @@ -34,5 +34,7 @@ class Package extends @package { */ bindingset[result, mod, path] string package(string mod, string path) { + // "\Q" and "\E" start and end a quoted section of a regular expression. Anything like "." or "*" that + // "*" that comes between them is not interpreted as it would normally be in a regular expression. result.regexpMatch("\\Q" + mod + "\\E([/.]v[^/]+)?($|/)\\Q" + path + "\\E") } diff --git a/ql/src/semmle/go/frameworks/Encoding.qll b/ql/src/semmle/go/frameworks/Encoding.qll index 5d91253971b..e575c046a75 100644 --- a/ql/src/semmle/go/frameworks/Encoding.qll +++ b/ql/src/semmle/go/frameworks/Encoding.qll @@ -10,10 +10,8 @@ private class JsonIteratorUnmarshalFunction extends TaintTracking::FunctionModel JsonIteratorUnmarshalFunction() { this.hasQualifiedName("github.com/json-iterator/go", ["Unmarshal", "UnmarshalFromString"]) or - exists(Method m | - m.hasQualifiedName("github.com/json-iterator/go", "API", ["Unmarshal", "UnmarshalFromString"]) and - this.(Method).implements(m) - ) + this.(Method) + .implements("github.com/json-iterator/go", "API", ["Unmarshal", "UnmarshalFromString"]) } override DataFlow::FunctionInput getAnInput() { result.isParameter(0) } diff --git a/ql/src/semmle/go/frameworks/Gin.qll b/ql/src/semmle/go/frameworks/Gin.qll index 99bd01190fe..107ab0fa47c 100644 --- a/ql/src/semmle/go/frameworks/Gin.qll +++ b/ql/src/semmle/go/frameworks/Gin.qll @@ -13,72 +13,24 @@ private module Gin { */ private class GithubComGinGonicGinContextSource extends UntrustedFlowSource::Range { GithubComGinGonicGinContextSource() { - exists(string typeName | typeName = "Context" | - // Method calls: - exists(DataFlow::MethodCallNode call, string methodName | - call.getTarget().hasQualifiedName(packagePath(), typeName, methodName) and - ( - methodName = "FullPath" - or - methodName = "GetHeader" - or - methodName = "QueryArray" - or - methodName = "Query" - or - methodName = "PostFormArray" - or - methodName = "PostForm" - or - methodName = "Param" - or - methodName = "GetStringSlice" - or - methodName = "GetString" - or - methodName = "GetRawData" - or - methodName = "ClientIP" - or - methodName = "ContentType" - or - methodName = "Cookie" - or - methodName = "GetQueryArray" - or - methodName = "GetQuery" - or - methodName = "GetPostFormArray" - or - methodName = "GetPostForm" - or - methodName = "DefaultPostForm" - or - methodName = "DefaultQuery" - or - methodName = "GetPostFormMap" - or - methodName = "GetQueryMap" - or - methodName = "GetStringMap" - or - methodName = "GetStringMapString" - or - methodName = "GetStringMapStringSlice" - or - methodName = "PostFormMap" - or - methodName = "QueryMap" - ) - | - this = call.getResult(0) - ) - or - // Field reads: - exists(DataFlow::Field fld | - fld.hasQualifiedName(packagePath(), typeName, ["Accepted", "Params"]) and - this = fld.getARead() - ) + // Method calls: + exists(DataFlow::MethodCallNode call, string methodName | + call.getTarget().hasQualifiedName(packagePath(), "Context", methodName) and + methodName in [ + "FullPath", "GetHeader", "QueryArray", "Query", "PostFormArray", "PostForm", "Param", + "GetStringSlice", "GetString", "GetRawData", "ClientIP", "ContentType", "Cookie", + "GetQueryArray", "GetQuery", "GetPostFormArray", "GetPostForm", "DefaultPostForm", + "DefaultQuery", "GetPostFormMap", "GetQueryMap", "GetStringMap", "GetStringMapString", + "GetStringMapStringSlice", "PostFormMap", "QueryMap" + ] + | + this = call.getResult(0) + ) + or + // Field reads: + exists(DataFlow::Field fld | + fld.hasQualifiedName(packagePath(), "Context", ["Accepted", "Params"]) and + this = fld.getARead() ) } } @@ -104,32 +56,16 @@ private module Gin { */ private class GithubComGinGonicGinContextBindSource extends UntrustedFlowSource::Range { GithubComGinGonicGinContextBindSource() { - exists(string typeName | typeName = "Context" | - exists(DataFlow::MethodCallNode call, string methodName | - call.getTarget().hasQualifiedName(packagePath(), typeName, methodName) and - ( - methodName = "BindJSON" or - methodName = "BindYAML" or - methodName = "BindXML" or - methodName = "BindUri" or - methodName = "BindQuery" or - methodName = "BindWith" or - methodName = "BindHeader" or - methodName = "MustBindWith" or - methodName = "Bind" or - methodName = "ShouldBind" or - methodName = "ShouldBindBodyWith" or - methodName = "ShouldBindJSON" or - methodName = "ShouldBindQuery" or - methodName = "ShouldBindUri" or - methodName = "ShouldBindHeader" or - methodName = "ShouldBindWith" or - methodName = "ShouldBindXML" or - methodName = "ShouldBindYAML" - ) - | - this = FunctionOutput::parameter(0).getExitNode(call) - ) + exists(DataFlow::MethodCallNode call, string methodName | + call.getTarget().hasQualifiedName(packagePath(), "Context", methodName) and + methodName in [ + "BindJSON", "BindYAML", "BindXML", "BindUri", "BindQuery", "BindWith", "BindHeader", + "MustBindWith", "Bind", "ShouldBind", "ShouldBindBodyWith", "ShouldBindJSON", + "ShouldBindQuery", "ShouldBindUri", "ShouldBindHeader", "ShouldBindWith", + "ShouldBindXML", "ShouldBindYAML" + ] + | + this = FunctionOutput::parameter(0).getExitNode(call) ) } } diff --git a/ql/src/semmle/go/frameworks/stdlib/EncodingJson.qll b/ql/src/semmle/go/frameworks/stdlib/EncodingJson.qll index b2cf57e0799..d05cc73c25f 100644 --- a/ql/src/semmle/go/frameworks/stdlib/EncodingJson.qll +++ b/ql/src/semmle/go/frameworks/stdlib/EncodingJson.qll @@ -14,10 +14,7 @@ module EncodingJson { /** The `Marshal` or `MarshalIndent` function in the `encoding/json` package. */ class MarshalFunction extends MarshalingFunction::Range { - MarshalFunction() { - this.hasQualifiedName("encoding/json", "Marshal") or - this.hasQualifiedName("encoding/json", "MarshalIndent") - } + MarshalFunction() { this.hasQualifiedName("encoding/json", ["Marshal", "MarshalIndent"]) } override FunctionInput getAnInput() { result.isParameter(0) } @@ -104,14 +101,6 @@ module EncodingJson { hasQualifiedName("encoding/json", "Encoder", "SetIndent") and (inp.isParameter(_) and outp.isReceiver()) or - // signature: func (RawMessage).MarshalJSON() ([]byte, error) - hasQualifiedName("encoding/json", "RawMessage", "MarshalJSON") and - (inp.isReceiver() and outp.isResult(0)) - or - // signature: func (*RawMessage).UnmarshalJSON(data []byte) error - hasQualifiedName("encoding/json", "RawMessage", "UnmarshalJSON") and - (inp.isParameter(0) and outp.isReceiver()) - or // signature: func (Marshaler).MarshalJSON() ([]byte, error) implements("encoding/json", "Marshaler", "MarshalJSON") and (inp.isReceiver() and outp.isResult(0))