From bb2d5ea6b5b4f54d962a510408bf51dc7b7710a5 Mon Sep 17 00:00:00 2001 From: Ricter Z Date: Tue, 9 Jun 2020 14:54:31 +0800 Subject: [PATCH] add some sinks in commonly-used SQL libraries --- ql/src/go.qll | 3 ++ ql/src/semmle/go/frameworks/HTTP.qll | 1 + .../go/frameworks/thirdpartlib/Encoding.qll | 25 ++++++++++ .../go/frameworks/thirdpartlib/HTTP.qll | 27 +++++++++++ .../semmle/go/frameworks/thirdpartlib/SQL.qll | 48 +++++++++++++++++++ 5 files changed, 104 insertions(+) create mode 100644 ql/src/semmle/go/frameworks/thirdpartlib/Encoding.qll create mode 100644 ql/src/semmle/go/frameworks/thirdpartlib/HTTP.qll create mode 100644 ql/src/semmle/go/frameworks/thirdpartlib/SQL.qll diff --git a/ql/src/go.qll b/ql/src/go.qll index 512fd06d05c..5016eb5c242 100644 --- a/ql/src/go.qll +++ b/ql/src/go.qll @@ -37,4 +37,7 @@ import semmle.go.frameworks.SystemCommandExecutors import semmle.go.frameworks.Testing import semmle.go.frameworks.WebSocket import semmle.go.frameworks.XPath +import semmle.go.frameworks.thirdpartlib.HTTP +import semmle.go.frameworks.thirdpartlib.SQL +import semmle.go.frameworks.thirdpartlib.Encoding import semmle.go.security.FlowSources diff --git a/ql/src/semmle/go/frameworks/HTTP.qll b/ql/src/semmle/go/frameworks/HTTP.qll index a159d75db7b..8a27dbf0b10 100644 --- a/ql/src/semmle/go/frameworks/HTTP.qll +++ b/ql/src/semmle/go/frameworks/HTTP.qll @@ -231,3 +231,4 @@ private module StdlibHttp { } } } + diff --git a/ql/src/semmle/go/frameworks/thirdpartlib/Encoding.qll b/ql/src/semmle/go/frameworks/thirdpartlib/Encoding.qll new file mode 100644 index 00000000000..ebc329dad13 --- /dev/null +++ b/ql/src/semmle/go/frameworks/thirdpartlib/Encoding.qll @@ -0,0 +1,25 @@ +/** + * Provides classes modeling security-relevant aspects of the third-part libraries. + */ + +import go + +module ThirdPartEncodingJson { + /** Provides models of some functions in the `github.com/json-iterator/go` package. */ + class JsoniterUnmarshalingFunction extends TaintTracking::FunctionModel, UnmarshalingFunction::Range { + + JsoniterUnmarshalingFunction() { + this.hasQualifiedName("github.com/json-iterator/go", "Unmarshal") + } + + override DataFlow::FunctionInput getAnInput() { result.isParameter(0) } + override DataFlow::FunctionOutput getOutput() { result.isParameter(1) } + + override string getFormat() { result = "JSON" } + + override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) { + inp = getAnInput() and outp = getOutput() + } + } +} + diff --git a/ql/src/semmle/go/frameworks/thirdpartlib/HTTP.qll b/ql/src/semmle/go/frameworks/thirdpartlib/HTTP.qll new file mode 100644 index 00000000000..fbc2a7a1c92 --- /dev/null +++ b/ql/src/semmle/go/frameworks/thirdpartlib/HTTP.qll @@ -0,0 +1,27 @@ +/** + * Provides classes for working with HTTP-related concepts such as requests and responses. + */ + +import go + +module ThirdPartHttpLib { + /** + * Source from go-resultful + * Document: https://github.com/emicklei/go-restful + */ + class GoRestfulSource extends DataFlow::Node, UntrustedFlowSource::Range { + GoRestfulSource() { + exists( + Method meth, string name | + meth.hasQualifiedName("github.com/emicklei/go-restful", "Request", name) and + asExpr() = meth.getACall().asExpr() and + ( + name = "QueryParameters" or name = "QueryParameter" or + name = "BodyParamater" or name = "HeaderParameter" or + name = "PathParameter" or name = "PathParameters" + ) + ) + } + } +} + diff --git a/ql/src/semmle/go/frameworks/thirdpartlib/SQL.qll b/ql/src/semmle/go/frameworks/thirdpartlib/SQL.qll new file mode 100644 index 00000000000..438646a5ac5 --- /dev/null +++ b/ql/src/semmle/go/frameworks/thirdpartlib/SQL.qll @@ -0,0 +1,48 @@ +/** + * Provides classes for working with SQL-related concepts such as queries. + */ + +import go + +module ThirdPartSQL { + + /** Sinks of github.com/jinzhu/gorm */ + class GormSink extends DataFlow::Node, SQL::QueryString::Range { + GormSink() { + exists( + Method meth, string name | + meth.hasQualifiedName("github.com/jinzhu/gorm", "DB", name) and + asExpr() = meth.getACall().getArgument(0).asExpr() and + ( + name = "Where" or name = "Raw" or name = "Order" or name = "Not" or name = "Or" or + name = "Select" or name = "Table" or name = "Group" or name = "Having" or name = "Joins" + ) + ) + } + } + + /** Sinks of github.com/jmoiron/sqlx */ + class SqlxSink extends DataFlow::Node, SQL::QueryString::Range { + SqlxSink() { + exists( + Method meth, string name, int n | + ( + meth.hasQualifiedName("github.com/jmoiron/sqlx", "DB", name) or + meth.hasQualifiedName("github.com/jmoiron/sqlx", "Tx", name) + ) and this = meth.getACall().getArgument(n) | + ( + (name = "Select" or name = "Get") and n = 1 + ) + or + ( + ( + name = "MustExec" or name = "Queryx" or + name = "NamedExec" or name = "NamedQuery" + ) + and n = 0 + ) + ) + } + } + +}