Skip to content

Commit 5bb1319

Browse files
authored
Merge pull request github#9779 from porcupineyhairs/goSqlInjection
Golang : Add SQL sinks for `gorqlite` and `GoFrame` frameworks
2 parents 8897f5b + 7883bff commit 5bb1319

File tree

15 files changed

+1604
-0
lines changed

15 files changed

+1604
-0
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* Queries that care about SQL, such as `go/sql-injection`, now recognise SQL-consuming functions belonging to the `gorqlite` and `GoFrame` packages.

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

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,14 @@ module SQL {
103103
/** A string that might identify package `go-pg/pg/orm` or a specific version of it. */
104104
private string gopgorm() { result = package("github.com/go-pg/pg", "orm") }
105105

106+
/** A string that might identify package `github.com/rqlite/gorqlite` or `github.com/raindog308/gorqlite` or a specific version of it. */
107+
private string gorqlite() {
108+
result = package(["github.com/rqlite/gorqlite", "github.com/raindog308/gorqlite"], "")
109+
}
110+
111+
/** A string that might identify package `github.com/gogf/gf/database/gdb` or a specific version of it. */
112+
private string gogf() { result = package("github.com/gogf/gf", "database/gdb") }
113+
106114
/**
107115
* A string argument to an API of `go-pg/pg` that is directly interpreted as SQL without
108116
* taking syntactic structure into account.
@@ -152,6 +160,65 @@ module SQL {
152160
}
153161
}
154162

163+
/**
164+
* A string argument to an API of `github.com/rqlite/gorqlite`, or a specific version of it, that is directly interpreted as SQL without
165+
* taking syntactic structure into account.
166+
*/
167+
private class GorqliteQueryString extends Range {
168+
GorqliteQueryString() {
169+
// func (conn *Connection) Query(sqlStatements []string) (results []QueryResult, err error)
170+
// func (conn *Connection) QueryOne(sqlStatement string) (qr QueryResult, err error)
171+
// func (conn *Connection) Queue(sqlStatements []string) (seq int64, err error)
172+
// func (conn *Connection) QueueOne(sqlStatement string) (seq int64, err error)
173+
// func (conn *Connection) Write(sqlStatements []string) (results []WriteResult, err error)
174+
// func (conn *Connection) WriteOne(sqlStatement string) (wr WriteResult, err error)
175+
exists(Method m, string name | m.hasQualifiedName(gorqlite(), "Connection", name) |
176+
name = ["Query", "QueryOne", "Queue", "QueueOne", "Write", "WriteOne"] and
177+
this = m.getACall().getArgument(0)
178+
)
179+
}
180+
}
181+
182+
/**
183+
* A string argument to an API of `github.com/gogf/gf/database/gdb`, or a specific version of it, that is directly interpreted as SQL without
184+
* taking syntactic structure into account.
185+
*/
186+
private class GogfQueryString extends Range {
187+
GogfQueryString() {
188+
exists(Method m, string name | m.implements(gogf(), ["DB", "Core", "TX"], name) |
189+
// func (c *Core) Exec(sql string, args ...interface{}) (result sql.Result, err error)
190+
// func (c *Core) GetAll(sql string, args ...interface{}) (Result, error)
191+
// func (c *Core) GetArray(sql string, args ...interface{}) ([]Value, error)
192+
// func (c *Core) GetCount(sql string, args ...interface{}) (int, error)
193+
// func (c *Core) GetOne(sql string, args ...interface{}) (Record, error)
194+
// func (c *Core) GetValue(sql string, args ...interface{}) (Value, error)
195+
// func (c *Core) Prepare(sql string, execOnMaster ...bool) (*Stmt, error)
196+
// func (c *Core) Query(sql string, args ...interface{}) (rows *sql.Rows, err error)
197+
// func (c *Core) Raw(rawSql string, args ...interface{}) *Model
198+
name =
199+
[
200+
"Query", "Exec", "Prepare", "GetAll", "GetOne", "GetValue", "GetArray", "GetCount",
201+
"Raw"
202+
] and
203+
this = m.getACall().getArgument(0)
204+
or
205+
// func (c *Core) GetScan(pointer interface{}, sql string, args ...interface{}) error
206+
// func (c *Core) GetStruct(pointer interface{}, sql string, args ...interface{}) error
207+
// func (c *Core) GetStructs(pointer interface{}, sql string, args ...interface{}) error
208+
name = ["GetScan", "GetStruct", "GetStructs"] and
209+
this = m.getACall().getArgument(1)
210+
or
211+
// func (c *Core) DoCommit(ctx context.Context, link Link, sql string, args []interface{}) (newSql string, newArgs []interface{}, err error)
212+
// func (c *Core) DoExec(ctx context.Context, link Link, sql string, args ...interface{}) (result sql.Result, err error)
213+
// func (c *Core) DoGetAll(ctx context.Context, link Link, sql string, args ...interface{}) (result Result, err error)
214+
// func (c *Core) DoPrepare(ctx context.Context, link Link, sql string) (*Stmt, error)
215+
// func (c *Core) DoQuery(ctx context.Context, link Link, sql string, args ...interface{}) (rows *sql.Rows, err error)
216+
name = ["DoGetAll", "DoQuery", "DoExec", "DoCommit", "DoPrepare"] and
217+
this = m.getACall().getArgument(2)
218+
)
219+
}
220+
}
221+
155222
/** A taint model for various methods on the struct `Formatter` of `go-pg/pg/orm`. */
156223
private class PgOrmFormatterFunction extends TaintTracking::FunctionModel, Method {
157224
FunctionInput i;
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
module main
2+
3+
go 1.19
4+
5+
require github.com/gogf/gf v1.16.9
6+
7+
require (
8+
github.com/BurntSushi/toml v0.3.1 // indirect
9+
github.com/clbanning/mxj v1.8.5-0.20200714211355-ff02cfb8ea28 // indirect
10+
github.com/fatih/color v1.12.0 // indirect
11+
github.com/fsnotify/fsnotify v1.4.9 // indirect
12+
github.com/go-sql-driver/mysql v1.6.0 // indirect
13+
github.com/gomodule/redigo v1.8.5 // indirect
14+
github.com/gorilla/websocket v1.4.2 // indirect
15+
github.com/grokify/html-strip-tags-go v0.0.1 // indirect
16+
github.com/mattn/go-colorable v0.1.8 // indirect
17+
github.com/mattn/go-isatty v0.0.12 // indirect
18+
github.com/mattn/go-runewidth v0.0.9 // indirect
19+
github.com/olekukonko/tablewriter v0.0.5 // indirect
20+
go.opentelemetry.io/otel v1.0.0 // indirect
21+
go.opentelemetry.io/otel/trace v1.0.0 // indirect
22+
golang.org/x/net v0.0.0-20210520170846-37e1c6afe023 // indirect
23+
golang.org/x/sys v0.0.0-20210423082822-04245dca01da // indirect
24+
golang.org/x/text v0.3.6 // indirect
25+
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
26+
)
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
| gogf.go:12:9:12:11 | sql |
2+
| gogf.go:13:11:13:13 | sql |
3+
| gogf.go:14:13:14:15 | sql |
4+
| gogf.go:15:13:15:15 | sql |
5+
| gogf.go:16:11:16:13 | sql |
6+
| gogf.go:17:13:17:15 | sql |
7+
| gogf.go:18:12:18:14 | sql |
8+
| gogf.go:19:10:19:12 | sql |
9+
| gogf.go:20:8:20:10 | sql |
10+
| gogf.go:21:17:21:19 | sql |
11+
| gogf.go:22:19:22:21 | sql |
12+
| gogf.go:23:20:23:22 | sql |
13+
| gogf.go:24:23:24:25 | sql |
14+
| gogf.go:25:21:25:23 | sql |
15+
| gogf.go:26:23:26:25 | sql |
16+
| gogf.go:27:22:27:24 | sql |
17+
| gogf.go:28:24:28:26 | sql |
18+
| gogf.go:32:9:32:11 | sql |
19+
| gogf.go:33:11:33:13 | sql |
20+
| gogf.go:34:13:34:15 | sql |
21+
| gogf.go:35:13:35:15 | sql |
22+
| gogf.go:36:11:36:13 | sql |
23+
| gogf.go:37:13:37:15 | sql |
24+
| gogf.go:38:12:38:14 | sql |
25+
| gogf.go:39:10:39:12 | sql |
26+
| gogf.go:40:8:40:10 | sql |
27+
| gogf.go:41:17:41:19 | sql |
28+
| gogf.go:42:23:42:25 | sql |
29+
| gogf.go:43:21:43:23 | sql |
30+
| gogf.go:44:23:44:25 | sql |
31+
| gogf.go:45:22:45:24 | sql |
32+
| gogf.go:46:24:46:26 | sql |
33+
| gogf.go:51:9:51:11 | sql |
34+
| gogf.go:52:11:52:13 | sql |
35+
| gogf.go:53:13:53:15 | sql |
36+
| gogf.go:54:13:54:15 | sql |
37+
| gogf.go:55:11:55:13 | sql |
38+
| gogf.go:56:13:56:15 | sql |
39+
| gogf.go:57:12:57:14 | sql |
40+
| gogf.go:58:10:58:12 | sql |
41+
| gogf.go:59:8:59:10 | sql |
42+
| gogf.go:60:17:60:19 | sql |
43+
| gogf.go:61:23:61:25 | sql |
44+
| gogf.go:62:21:62:23 | sql |
45+
| gogf.go:63:23:63:25 | sql |
46+
| gogf.go:64:22:64:24 | sql |
47+
| gogf.go:65:24:65:26 | sql |
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package main
2+
3+
//go:generate depstubber -vendor github.com/gogf/gf/frame/g "" DB
4+
//go:generate depstubber -vendor github.com/gogf/gf/database/gdb DB,Core,TX ""
5+
6+
import (
7+
"github.com/gogf/gf/database/gdb"
8+
"github.com/gogf/gf/frame/g"
9+
)
10+
11+
func gogfCoreTest(sql string, c *gdb.Core) {
12+
c.Exec(sql, nil) // $ querystring=sql
13+
c.GetAll(sql, nil) // $ querystring=sql
14+
c.GetArray(sql, nil) // $ querystring=sql
15+
c.GetCount(sql, nil) // $ querystring=sql
16+
c.GetOne(sql, nil) // $ querystring=sql
17+
c.GetValue(sql, nil) // $ querystring=sql
18+
c.Prepare(sql, true) // $ querystring=sql
19+
c.Query(sql, nil) // $ querystring=sql
20+
c.Raw(sql, nil) // $ querystring=sql
21+
c.GetScan(nil, sql, nil) // $ querystring=sql
22+
c.GetStruct(nil, sql, nil) // $ querystring=sql
23+
c.GetStructs(nil, sql, nil) // $ querystring=sql
24+
c.DoCommit(nil, nil, sql, nil) // $ querystring=sql
25+
c.DoExec(nil, nil, sql, nil) // $ querystring=sql
26+
c.DoGetAll(nil, nil, sql, nil) // $ querystring=sql
27+
c.DoQuery(nil, nil, sql, nil) // $ querystring=sql
28+
c.DoPrepare(nil, nil, sql) // $ querystring=sql
29+
}
30+
31+
func gogfDbtest(sql string, c gdb.DB) {
32+
c.Exec(sql, nil) // $ querystring=sql
33+
c.GetAll(sql, nil) // $ querystring=sql
34+
c.GetArray(sql, nil) // $ querystring=sql
35+
c.GetCount(sql, nil) // $ querystring=sql
36+
c.GetOne(sql, nil) // $ querystring=sql
37+
c.GetValue(sql, nil) // $ querystring=sql
38+
c.Prepare(sql, true) // $ querystring=sql
39+
c.Query(sql, nil) // $ querystring=sql
40+
c.Raw(sql, nil) // $ querystring=sql
41+
c.GetScan(nil, sql, nil) // $ querystring=sql
42+
c.DoCommit(nil, nil, sql, nil) // $ querystring=sql
43+
c.DoExec(nil, nil, sql, nil) // $ querystring=sql
44+
c.DoGetAll(nil, nil, sql, nil) // $ querystring=sql
45+
c.DoQuery(nil, nil, sql, nil) // $ querystring=sql
46+
c.DoPrepare(nil, nil, sql) // $ querystring=sql
47+
}
48+
49+
func gogfGTest(sql string) {
50+
c := g.DB("ad")
51+
c.Exec(sql, nil) // $ querystring=sql
52+
c.GetAll(sql, nil) // $ querystring=sql
53+
c.GetArray(sql, nil) // $ querystring=sql
54+
c.GetCount(sql, nil) // $ querystring=sql
55+
c.GetOne(sql, nil) // $ querystring=sql
56+
c.GetValue(sql, nil) // $ querystring=sql
57+
c.Prepare(sql, true) // $ querystring=sql
58+
c.Query(sql, nil) // $ querystring=sql
59+
c.Raw(sql, nil) // $ querystring=sql
60+
c.GetScan(nil, sql, nil) // $ querystring=sql
61+
c.DoCommit(nil, nil, sql, nil) // $ querystring=sql
62+
c.DoExec(nil, nil, sql, nil) // $ querystring=sql
63+
c.DoGetAll(nil, nil, sql, nil) // $ querystring=sql
64+
c.DoQuery(nil, nil, sql, nil) // $ querystring=sql
65+
c.DoPrepare(nil, nil, sql) // $ querystring=sql
66+
}
67+
68+
func main() {
69+
return
70+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import go
2+
3+
from SQL::QueryString qs
4+
select qs

0 commit comments

Comments
 (0)