@@ -6,6 +6,79 @@ import go
6
6
7
7
/** Provides classes for working with SQL-related APIs. */
8
8
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
+
9
82
/**
10
83
* A data-flow node whose string value is interpreted as (part of) a SQL query.
11
84
*
@@ -34,7 +107,8 @@ module SQL {
34
107
exists ( Method meth , string base , string m , int n |
35
108
(
36
109
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 )
38
112
) and
39
113
this = meth .getACall ( ) .getArgument ( n )
40
114
|
@@ -48,6 +122,29 @@ module SQL {
48
122
}
49
123
}
50
124
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
+
51
148
/**
52
149
* An argument to an API of the squirrel library that is directly interpreted as SQL without
53
150
* taking syntactic structure into account.
0 commit comments