Skip to content

Commit ba31041

Browse files
committed
Convert Gorm sql-injection sinks to MaD
1 parent 7ad63fc commit ba31041

File tree

7 files changed

+113
-71
lines changed

7 files changed

+113
-71
lines changed

go/ql/lib/ext/gorm.io.gorm.model.yml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
extensions:
2+
- addsTo:
3+
pack: codeql/go-all
4+
extensible: packageGrouping
5+
data:
6+
- ["gorm", "gorm.io/gorm"]
7+
- ["gorm", "github.com/jinzhu/gorm"]
8+
- ["gorm", "github.com/go-gorm/gorm"]
9+
- addsTo:
10+
pack: codeql/go-all
11+
extensible: sinkModel
12+
data:
13+
- ["group:gorm", "DB", True, "Where", "", "", "Argument[0]", "sql-injection", "manual"]
14+
- ["group:gorm", "DB", True, "Raw", "", "", "Argument[0]", "sql-injection", "manual"]
15+
- ["group:gorm", "DB", True, "Order", "", "", "Argument[0]", "sql-injection", "manual"]
16+
- ["group:gorm", "DB", True, "Not", "", "", "Argument[0]", "sql-injection", "manual"]
17+
- ["group:gorm", "DB", True, "Or", "", "", "Argument[0]", "sql-injection", "manual"]
18+
- ["group:gorm", "DB", True, "Select", "", "", "Argument[0]", "sql-injection", "manual"]
19+
- ["group:gorm", "DB", True, "Table", "", "", "Argument[0]", "sql-injection", "manual"]
20+
- ["group:gorm", "DB", True, "Group", "", "", "Argument[0]", "sql-injection", "manual"]
21+
- ["group:gorm", "DB", True, "Having", "", "", "Argument[0]", "sql-injection", "manual"]
22+
- ["group:gorm", "DB", True, "Joins", "", "", "Argument[0]", "sql-injection", "manual"]
23+
- ["group:gorm", "DB", True, "Exec", "", "", "Argument[0]", "sql-injection", "manual"]
24+
- ["group:gorm", "DB", True, "Distinct", "", "", "Argument[0]", "sql-injection", "manual"]
25+
- ["group:gorm", "DB", True, "Pluck", "", "", "Argument[0]", "sql-injection", "manual"]

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

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -150,21 +150,6 @@ module SQL {
150150
}
151151
}
152152
}
153-
154-
/** A model for sinks of GORM. */
155-
private class GormSink extends SQL::QueryString::Range {
156-
GormSink() {
157-
exists(Method meth, string package, string name |
158-
meth.hasQualifiedName(package, "DB", name) and
159-
this = meth.getACall().getSyntacticArgument(0) and
160-
package = Gorm::packagePath() and
161-
name in [
162-
"Where", "Raw", "Order", "Not", "Or", "Select", "Table", "Group", "Having", "Joins",
163-
"Exec", "Distinct", "Pluck"
164-
]
165-
)
166-
}
167-
}
168153
}
169154

170155
/**
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
testFailures
2+
invalidModelRow
3+
failures
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import go
2+
import semmle.go.dataflow.ExternalFlow
3+
import ModelValidation
4+
import TestUtilities.InlineExpectationsTest
5+
6+
module SqlTest implements TestSig {
7+
string getARelevantTag() { result = "query" }
8+
9+
predicate hasActualResult(Location location, string element, string tag, string value) {
10+
tag = "query" and
11+
exists(SQL::Query q, SQL::QueryString qs | qs = q.getAQueryString() |
12+
q.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(),
13+
location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and
14+
element = q.toString() and
15+
value = qs.toString()
16+
)
17+
}
18+
}
19+
20+
module QueryString implements TestSig {
21+
string getARelevantTag() { result = "querystring" }
22+
23+
predicate hasActualResult(Location location, string element, string tag, string value) {
24+
tag = "querystring" and
25+
element = "" and
26+
exists(SQL::QueryString qs | not exists(SQL::Query q | qs = q.getAQueryString()) |
27+
qs.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(),
28+
location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and
29+
value = qs.toString()
30+
)
31+
}
32+
}
33+
34+
module Config implements DataFlow::ConfigSig {
35+
predicate isSource(DataFlow::Node n) { n.asExpr() instanceof StringLit }
36+
37+
predicate isSink(DataFlow::Node n) {
38+
n = any(DataFlow::CallNode cn | cn.getTarget().getName() = "sink").getAnArgument()
39+
}
40+
}
41+
42+
module Flow = TaintTracking::Global<Config>;
43+
44+
module TaintFlow implements TestSig {
45+
string getARelevantTag() { result = "flowfrom" }
46+
47+
predicate hasActualResult(Location location, string element, string tag, string value) {
48+
tag = "flowfrom" and
49+
element = "" and
50+
exists(DataFlow::Node fromNode, DataFlow::Node toNode |
51+
toNode
52+
.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(),
53+
location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and
54+
Flow::flow(fromNode, toNode) and
55+
value = fromNode.asExpr().(StringLit).getValue()
56+
)
57+
}
58+
}
59+
60+
import MakeTest<MergeTests3<SqlTest, QueryString, TaintFlow>>

go/ql/test/library-tests/semmle/go/frameworks/SQL/Gorm/gorm.expected

Lines changed: 0 additions & 25 deletions
This file was deleted.

go/ql/test/library-tests/semmle/go/frameworks/SQL/Gorm/gorm.go

Lines changed: 25 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -13,36 +13,35 @@ func getUntrustedString() string {
1313
}
1414

1515
func main() {
16-
1716
untrusted := getUntrustedString()
1817

1918
db1 := gorm1.DB{}
20-
db1.Where(untrusted)
21-
db1.Raw(untrusted)
22-
db1.Not(untrusted)
23-
db1.Order(untrusted)
24-
db1.Or(untrusted)
25-
db1.Select(untrusted)
26-
db1.Table(untrusted)
27-
db1.Group(untrusted)
28-
db1.Having(untrusted)
29-
db1.Joins(untrusted)
30-
db1.Exec(untrusted)
31-
db1.Pluck(untrusted, nil)
19+
db1.Where(untrusted) // $ querystring=untrusted
20+
db1.Raw(untrusted) // $ querystring=untrusted
21+
db1.Not(untrusted) // $ querystring=untrusted
22+
db1.Order(untrusted) // $ querystring=untrusted
23+
db1.Or(untrusted) // $ querystring=untrusted
24+
db1.Select(untrusted) // $ querystring=untrusted
25+
db1.Table(untrusted) // $ querystring=untrusted
26+
db1.Group(untrusted) // $ querystring=untrusted
27+
db1.Having(untrusted) // $ querystring=untrusted
28+
db1.Joins(untrusted) // $ querystring=untrusted
29+
db1.Exec(untrusted) // $ querystring=untrusted
30+
db1.Pluck(untrusted, nil) // $ querystring=untrusted
3231

3332
db2 := gorm2.DB{}
34-
db2.Where(untrusted)
35-
db2.Raw(untrusted)
36-
db2.Not(untrusted)
37-
db2.Order(untrusted)
38-
db2.Or(untrusted)
39-
db2.Select(untrusted)
40-
db2.Table(untrusted)
41-
db2.Group(untrusted)
42-
db2.Having(untrusted)
43-
db2.Joins(untrusted)
44-
db2.Exec(untrusted)
45-
db2.Distinct(untrusted)
46-
db2.Pluck(untrusted, nil)
33+
db2.Where(untrusted) // $ querystring=untrusted
34+
db2.Raw(untrusted) // $ querystring=untrusted
35+
db2.Not(untrusted) // $ querystring=untrusted
36+
db2.Order(untrusted) // $ querystring=untrusted
37+
db2.Or(untrusted) // $ querystring=untrusted
38+
db2.Select(untrusted) // $ querystring=untrusted
39+
db2.Table(untrusted) // $ querystring=untrusted
40+
db2.Group(untrusted) // $ querystring=untrusted
41+
db2.Having(untrusted) // $ querystring=untrusted
42+
db2.Joins(untrusted) // $ querystring=untrusted
43+
db2.Exec(untrusted) // $ querystring=untrusted
44+
db2.Distinct(untrusted) // $ querystring=untrusted
45+
db2.Pluck(untrusted, nil) // $ querystring=untrusted
4746

4847
}

go/ql/test/library-tests/semmle/go/frameworks/SQL/Gorm/gorm.ql

Lines changed: 0 additions & 5 deletions
This file was deleted.

0 commit comments

Comments
 (0)