Skip to content

Commit dc242da

Browse files
authored
Merge pull request github#19090 from owen-mc/review/egregius313/18902
Go: Add `database` source models for the `squirrel` package (#2)
2 parents 32369da + 8bc70be commit dc242da

File tree

11 files changed

+941
-1
lines changed

11 files changed

+941
-1
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* Added `database` source models for the `github.com/Masterminds/squirrel` ORM package.
5+

go/ql/lib/ext/github.com.mastermind.squirrel.model.yml renamed to go/ql/lib/ext/github.com.masterminds.squirrel.model.yml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,37 @@ extensions:
66
- ["squirrel", "github.com/Masterminds/squirrel"]
77
- ["squirrel", "gopkg.in/Masterminds/squirrel"]
88
- ["squirrel", "github.com/lann/squirrel"]
9+
- addsTo:
10+
pack: codeql/go-all
11+
extensible: sourceModel
12+
data:
13+
- ["group:squirrel", "", True, "QueryContextWith", "", "", "ReturnValue[0]", "database", "manual"]
14+
- ["group:squirrel", "", True, "QueryRowContextWith", "", "", "ReturnValue", "database", "manual"]
15+
- ["group:squirrel", "", True, "QueryRowWith", "", "", "ReturnValue", "database", "manual"]
16+
- ["group:squirrel", "", True, "QueryWith", "", "", "ReturnValue[0]", "database", "manual"]
17+
- ["group:squirrel", "DeleteBuilder", True, "Query", "", "", "ReturnValue[0]", "database", "manual"]
18+
- ["group:squirrel", "DeleteBuilder", True, "QueryContext", "", "", "ReturnValue[0]", "database", "manual"]
19+
- ["group:squirrel", "DeleteBuilder", True, "QueryRowContext", "", "", "ReturnValue[0]", "database", "manual"]
20+
- ["group:squirrel", "InsertBuilder", True, "Query", "", "", "ReturnValue[0]", "database", "manual"]
21+
- ["group:squirrel", "InsertBuilder", True, "QueryContext", "", "", "ReturnValue[0]", "database", "manual"]
22+
- ["group:squirrel", "InsertBuilder", True, "QueryRow", "", "", "ReturnValue[0]", "database", "manual"]
23+
- ["group:squirrel", "InsertBuilder", True, "QueryRowContext", "", "", "ReturnValue[0]", "database", "manual"]
24+
- ["group:squirrel", "QueryRower", True, "QueryRow", "", "", "ReturnValue[0]", "database", "manual"]
25+
- ["group:squirrel", "QueryRowerContext", True, "QueryRowContext", "", "", "ReturnValue[0]", "database", "manual"]
26+
- ["group:squirrel", "Queryer", True, "Query", "", "", "ReturnValue[0]", "database", "manual"]
27+
- ["group:squirrel", "QueryerContext", True, "QueryContext", "", "", "ReturnValue[0]", "database", "manual"]
28+
- ["group:squirrel", "SelectBuilder", True, "Query", "", "", "ReturnValue[0]", "database", "manual"]
29+
- ["group:squirrel", "SelectBuilder", True, "QueryContext", "", "", "ReturnValue[0]", "database", "manual"]
30+
- ["group:squirrel", "SelectBuilder", True, "QueryRow", "", "", "ReturnValue[0]", "database", "manual"]
31+
- ["group:squirrel", "SelectBuilder", True, "QueryRowContext", "", "", "ReturnValue[0]", "database", "manual"]
32+
- ["group:squirrel", "StdSql", True, "Query", "", "", "ReturnValue[0]", "database", "manual"]
33+
- ["group:squirrel", "StdSql", True, "QueryRow", "", "", "ReturnValue", "database", "manual"]
34+
- ["group:squirrel", "StdSqlCtx", True, "QueryContext", "", "", "ReturnValue[0]", "database", "manual"]
35+
- ["group:squirrel", "StdSqlCtx", True, "QueryRowContext", "", "", "ReturnValue", "database", "manual"]
36+
- ["group:squirrel", "UpdateBuilder", True, "Query", "", "", "ReturnValue[0]", "database", "manual"]
37+
- ["group:squirrel", "UpdateBuilder", True, "QueryContext", "", "", "ReturnValue[0]", "database", "manual"]
38+
- ["group:squirrel", "UpdateBuilder", True, "QueryRow", "", "", "ReturnValue[0]", "database", "manual"]
39+
- ["group:squirrel", "UpdateBuilder", True, "QueryRowContext", "", "", "ReturnValue[0]", "database", "manual"]
940
- addsTo:
1041
pack: codeql/go-all
1142
extensible: sinkModel
@@ -49,3 +80,5 @@ extensions:
4980
- ["group:squirrel", "UpdateBuilder", True, "Suffix", "", "", "Argument[0]", "sql-injection", "manual"]
5081
- ["group:squirrel", "UpdateBuilder", True, "Table", "", "", "Argument[0]", "sql-injection", "manual"]
5182
# UpdateBuilder.Where has to be modeled in QL to avoid FPs when a non-string argument is used
83+
84+
# There are summary models for Row.Scan, RowScanner.Scan, {Insert,Delete,Select,Update}Builder.Scan and {Insert,Delete,Select,Update}Builder.ScanContext modeled in QL

go/ql/lib/go.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ import semmle.go.frameworks.Protobuf
5757
import semmle.go.frameworks.Revel
5858
import semmle.go.frameworks.Spew
5959
import semmle.go.frameworks.SQL
60+
import semmle.go.frameworks.Squirrel
6061
import semmle.go.frameworks.Stdlib
6162
import semmle.go.frameworks.SystemCommandExecutors
6263
import semmle.go.frameworks.Testing
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/**
2+
* Provides classes modeling security-relevant aspects of the `squirrel` ORM package.
3+
*/
4+
5+
import go
6+
7+
/**
8+
* Provides classes modeling security-relevant aspects of the `squirrel` ORM package.
9+
*/
10+
module Squirrel {
11+
private string packagePath() {
12+
result =
13+
package([
14+
"github.com/Masterminds/squirrel",
15+
"github.com/lann/squirrel",
16+
"gopkg.in/Masterminds/squirrel",
17+
], "")
18+
}
19+
20+
private class RowScan extends TaintTracking::FunctionModel, Method {
21+
FunctionInput inp;
22+
FunctionOutput outp;
23+
24+
RowScan() {
25+
// signature: func (r *Row) Scan(dest ...interface{}) error
26+
this.hasQualifiedName(packagePath(), "Row", "Scan") and
27+
inp.isReceiver() and
28+
outp.isParameter(_)
29+
}
30+
31+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
32+
input = inp and output = outp
33+
}
34+
}
35+
36+
private class RowScannerScan extends TaintTracking::FunctionModel, Method {
37+
FunctionInput inp;
38+
FunctionOutput outp;
39+
40+
RowScannerScan() {
41+
// signature: func (rs *RowScanner) Scan(dest ...interface{}) error
42+
this.hasQualifiedName(packagePath(), "RowScanner", "Scan") and
43+
inp.isReceiver() and
44+
outp.isParameter(_)
45+
}
46+
47+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
48+
input = inp and output = outp
49+
}
50+
}
51+
52+
private class BuilderScan extends TaintTracking::FunctionModel, Method {
53+
FunctionInput inp;
54+
FunctionOutput outp;
55+
56+
BuilderScan() {
57+
// signature: func (b {Insert,Delete,Select,Update}Builder) Scan(dest ...interface{}) error
58+
this.hasQualifiedName(packagePath(),
59+
["DeleteBuilder", "InsertBuilder", "SelectBuilder", "UpdateBuilder"], "Scan") and
60+
inp.isReceiver() and
61+
outp.isParameter(_)
62+
}
63+
64+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
65+
input = inp and output = outp
66+
}
67+
}
68+
69+
private class BuilderScanContext extends TaintTracking::FunctionModel, Method {
70+
FunctionInput inp;
71+
FunctionOutput outp;
72+
73+
BuilderScanContext() {
74+
// signature: func (b {Insert,Delete,Select,Update}Builder) ScanContext(ctx context.Context, dest ...interface{}) error
75+
this.hasQualifiedName(packagePath(),
76+
["DeleteBuilder", "InsertBuilder", "SelectBuilder", "UpdateBuilder"], "ScanContext") and
77+
inp.isReceiver() and
78+
exists(int i | i > 0 | outp.isParameter(i))
79+
}
80+
81+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
82+
input = inp and output = outp
83+
}
84+
}
85+
}

go/ql/test/library-tests/semmle/go/dataflow/flowsources/local/database/go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@ require (
88
github.com/couchbase/gocb v1.6.7
99
github.com/couchbase/gocb/v2 v2.9.4
1010
github.com/jmoiron/sqlx v1.4.0
11+
github.com/Masterminds/squirrel v1.5.4
1112
github.com/rqlite/gorqlite v0.0.0-20250128004930-114c7828b55a
1213
go.mongodb.org/mongo-driver v1.17.3
1314
gorm.io/gorm v1.25.12
15+
github.com/nonexistent/sources v0.0.0-20250300000000-000000000000
1416
)
1517

1618
require (

go/ql/test/library-tests/semmle/go/dataflow/flowsources/local/database/source.ext.yml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,9 @@ extensions:
33
pack: codeql/threat-models
44
extensible: threatModelConfiguration
55
data:
6-
- ["database", true, 0]
6+
- ["database", true, 0]
7+
- addsTo:
8+
pack: codeql/go-all
9+
extensible: sourceModel
10+
data:
11+
- ["github.com/nonexistent/sources", "", False, "Source", "", "", "ReturnValue", "database", "manual"]

go/ql/test/library-tests/semmle/go/dataflow/flowsources/local/database/test.ext.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,9 @@ extensions:
55
extensible: threatModelConfiguration
66
data:
77
- ["database", true, 0]
8+
9+
- addsTo:
10+
pack: codeql/go-all
11+
extensible: sourceModel
12+
data:
13+
- ["github.com/nonexistent/sources", "", False, "Source", "", "", "ReturnValue", "database", "manual"]

0 commit comments

Comments
 (0)