Skip to content
This repository was archived by the owner on Jan 5, 2023. It is now read-only.

Commit 3155140

Browse files
committed
Merge branch 'standard-lib-pt-9' into stdlib-339-340-342-346-347
2 parents 0510404 + 5e7b279 commit 3155140

File tree

8 files changed

+491
-1
lines changed

8 files changed

+491
-1
lines changed

ql/src/semmle/go/frameworks/SQL.qll

Lines changed: 98 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,79 @@ import go
66

77
/** Provides classes for working with SQL-related APIs. */
88
module SQL {
9+
private class SqlFunctionModels extends TaintTracking::FunctionModel {
10+
FunctionInput inp;
11+
FunctionOutput outp;
12+
13+
SqlFunctionModels() {
14+
// signature: func Named(name string, value interface{}) NamedArg
15+
hasQualifiedName("database/sql", "Named") and
16+
(inp.isParameter(_) and outp.isResult())
17+
}
18+
19+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
20+
input = inp and output = outp
21+
}
22+
}
23+
24+
private class SqlMethodModels extends TaintTracking::FunctionModel, Method {
25+
FunctionInput inp;
26+
FunctionOutput outp;
27+
28+
SqlMethodModels() {
29+
// signature: func (*Row).Scan(dest ...interface{}) error
30+
this.hasQualifiedName("database/sql", "Row", "Scan") and
31+
(inp.isReceiver() and outp.isParameter(_))
32+
or
33+
// signature: func (*Rows).Scan(dest ...interface{}) error
34+
this.hasQualifiedName("database/sql", "Rows", "Scan") and
35+
(inp.isReceiver() and outp.isParameter(_))
36+
or
37+
// signature: func (Scanner).Scan(src interface{}) error
38+
this.implements("database/sql", "Scanner", "Scan") and
39+
(inp.isParameter(0) and outp.isReceiver())
40+
}
41+
42+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
43+
input = inp and output = outp
44+
}
45+
}
46+
47+
private class SqlDriverMethodModels extends TaintTracking::FunctionModel, Method {
48+
FunctionInput inp;
49+
FunctionOutput outp;
50+
51+
SqlDriverMethodModels() {
52+
// signature: func (NotNull).ConvertValue(v interface{}) (Value, error)
53+
this.hasQualifiedName("database/sql/driver", "NotNull", "ConvertValue") and
54+
(inp.isParameter(0) and outp.isResult(0))
55+
or
56+
// signature: func (Null).ConvertValue(v interface{}) (Value, error)
57+
this.hasQualifiedName("database/sql/driver", "Null", "ConvertValue") and
58+
(inp.isParameter(0) and outp.isResult(0))
59+
or
60+
// signature: func (ValueConverter).ConvertValue(v interface{}) (Value, error)
61+
this.implements("database/sql/driver", "ValueConverter", "ConvertValue") and
62+
(inp.isParameter(0) and outp.isResult(0))
63+
or
64+
// signature: func (Conn).Prepare(query string) (Stmt, error)
65+
this.implements("database/sql/driver", "Conn", "Prepare") and
66+
(inp.isParameter(0) and outp.isResult(0))
67+
or
68+
// signature: func (ConnPrepareContext).PrepareContext(ctx context.Context, query string) (Stmt, error)
69+
this.implements("database/sql/driver", "ConnPrepareContext", "PrepareContext") and
70+
(inp.isParameter(1) and outp.isResult(0))
71+
or
72+
// signature: func (Valuer).Value() (Value, error)
73+
this.implements("database/sql/driver", "Valuer", "Value") and
74+
(inp.isReceiver() and outp.isResult(0))
75+
}
76+
77+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
78+
input = inp and output = outp
79+
}
80+
}
81+
982
/**
1083
* A data-flow node whose string value is interpreted as (part of) a SQL query.
1184
*
@@ -34,7 +107,8 @@ module SQL {
34107
exists(Method meth, string base, string m, int n |
35108
(
36109
meth.hasQualifiedName("database/sql", "DB", m) or
37-
meth.hasQualifiedName("database/sql", "Tx", m)
110+
meth.hasQualifiedName("database/sql", "Tx", m) or
111+
meth.hasQualifiedName("database/sql", "Conn", m)
38112
) and
39113
this = meth.getACall().getArgument(n)
40114
|
@@ -48,6 +122,29 @@ module SQL {
48122
}
49123
}
50124

125+
/** A query string used in an API function of the standard `database/sql/driver` package. */
126+
private class DriverQueryString extends Range {
127+
DriverQueryString() {
128+
exists(Method meth, int n |
129+
(
130+
meth.hasQualifiedName("database/sql/driver", "Execer", "Exec") and n = 0
131+
or
132+
meth.hasQualifiedName("database/sql/driver", "ExecerContext", "ExecContext") and n = 1
133+
or
134+
meth.hasQualifiedName("database/sql/driver", "Conn", "Prepare") and n = 0
135+
or
136+
meth.hasQualifiedName("database/sql/driver", "ConnPrepareContext", "PrepareContext") and
137+
n = 1
138+
or
139+
meth.hasQualifiedName("database/sql/driver", "Queryer", "Query") and n = 0
140+
or
141+
meth.hasQualifiedName("database/sql/driver", "QueryerContext", "QueryContext") and n = 1
142+
) and
143+
this = meth.getACall().getArgument(n)
144+
)
145+
}
146+
}
147+
51148
/**
52149
* An argument to an API of the squirrel library that is directly interpreted as SQL without
53150
* taking syntactic structure into account.

ql/src/semmle/go/frameworks/Stdlib.qll

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ import semmle.go.frameworks.stdlib.NetTextproto
4040
import semmle.go.frameworks.stdlib.Log
4141
import semmle.go.frameworks.stdlib.Io
4242
import semmle.go.frameworks.stdlib.IoIoutil
43+
import semmle.go.frameworks.stdlib.Errors
44+
import semmle.go.frameworks.stdlib.Expvar
4345
import semmle.go.frameworks.stdlib.Path
4446
import semmle.go.frameworks.stdlib.PathFilepath
4547
import semmle.go.frameworks.stdlib.Reflect
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/**
2+
* Provides classes modeling security-relevant aspects of the `errors` package.
3+
*/
4+
5+
import go
6+
7+
/** Provides models of commonly used functions in the `errors` package. */
8+
module Errors {
9+
private class FunctionModels extends TaintTracking::FunctionModel {
10+
FunctionInput inp;
11+
FunctionOutput outp;
12+
13+
FunctionModels() {
14+
// signature: func As(err error, target interface{}) bool
15+
hasQualifiedName("errors", "As") and
16+
(inp.isParameter(0) and outp.isParameter(1))
17+
or
18+
// signature: func New(text string) error
19+
hasQualifiedName("errors", "New") and
20+
(inp.isParameter(0) and outp.isResult())
21+
or
22+
// signature: func Unwrap(err error) error
23+
hasQualifiedName("errors", "Unwrap") and
24+
(inp.isParameter(0) and outp.isResult())
25+
}
26+
27+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
28+
input = inp and output = outp
29+
}
30+
}
31+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/**
2+
* Provides classes modeling security-relevant aspects of the `expvar` package.
3+
*/
4+
5+
import go
6+
7+
/** Provides models of commonly used functions in the `expvar` package. */
8+
module Expvar {
9+
private class MethodModels extends TaintTracking::FunctionModel, Method {
10+
FunctionInput inp;
11+
FunctionOutput outp;
12+
13+
MethodModels() {
14+
// signature: func (Func).Value() interface{}
15+
this.hasQualifiedName("expvar", "Func", "Value") and
16+
(inp.isReceiver() and outp.isResult())
17+
or
18+
// signature: func (*Map).Get(key string) Var
19+
this.hasQualifiedName("expvar", "Map", "Get") and
20+
(inp.isReceiver() and outp.isResult())
21+
or
22+
// signature: func (*Map).Set(key string, av Var)
23+
this.hasQualifiedName("expvar", "Map", "Set") and
24+
(inp.isParameter(_) and outp.isReceiver())
25+
or
26+
// signature: func (*Map).String() string
27+
this.hasQualifiedName("expvar", "Map", "String") and
28+
(inp.isReceiver() and outp.isResult())
29+
or
30+
// signature: func (*String).Set(value string)
31+
this.hasQualifiedName("expvar", "String", "Set") and
32+
(inp.isParameter(0) and outp.isReceiver())
33+
or
34+
// signature: func (*String).String() string
35+
this.hasQualifiedName("expvar", "String", "String") and
36+
(inp.isReceiver() and outp.isResult())
37+
or
38+
// signature: func (*String).Value() string
39+
this.hasQualifiedName("expvar", "String", "Value") and
40+
(inp.isReceiver() and outp.isResult())
41+
or
42+
// signature: func (Var).String() string
43+
this.implements("expvar", "Var", "String") and
44+
(inp.isReceiver() and outp.isResult())
45+
}
46+
47+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
48+
input = inp and output = outp
49+
}
50+
}
51+
}

ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/DatabaseSql.go

Lines changed: 78 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/DatabaseSqlDriver.go

Lines changed: 79 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)