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

Commit a094ddb

Browse files
authored
Merge pull request #349 from gagliardetto/stdlib-339-340-342-346-347
Merge #339 #340 #342 #346 #347
2 parents 1a3589a + 364b681 commit a094ddb

32 files changed

+2295
-347
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.

0 commit comments

Comments
 (0)