Skip to content

Commit e7e4286

Browse files
authored
Merge pull request #19561 from owen-mc/go/mad/bigquery-sql-injection-sink
Go: Add BigQuery as a sink for SQLi queries #2
2 parents 0ef17ba + fb92999 commit e7e4286

File tree

11 files changed

+1400
-1
lines changed

11 files changed

+1400
-1
lines changed

go/documentation/library-coverage/frameworks.csv

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ Standard library,https://pkg.go.dev/std, archive/* bufio bytes cmp compress/* co
33
appleboy/gin-jwt,https://github.com/appleboy/gin-jwt,github.com/appleboy/gin-jwt*
44
Afero,https://github.com/spf13/afero,github.com/spf13/afero*
55
beego,https://beego.me/,github.com/astaxie/beego* github.com/beego/beego*
6+
bigquery,https://pkg.go.dev/cloud.google.com/go/bigquery,cloud.google.com/go/bigquery*
67
Bun,https://bun.uptrace.dev/,github.com/uptrace/bun*
78
CleverGo,https://github.com/clevergo/clevergo,clevergo.tech/clevergo* github.com/clevergo/clevergo*
89
Couchbase official client(gocb),https://github.com/couchbase/gocb,github.com/couchbase/gocb* gopkg.in/couchbase/gocb*
@@ -35,7 +36,7 @@ golang.org/x/net,https://pkg.go.dev/golang.org/x/net,golang.org/x/net*
3536
goproxy,https://github.com/elazarl/goproxy,github.com/elazarl/goproxy*
3637
gorilla/mux,https://github.com/gorilla/mux,github.com/gorilla/mux*
3738
gorilla/websocket,https://github.com/gorilla/websocket,github.com/gorilla/websocket*
38-
gorqlite,https://github.com/rqlite/gorqlite,github.com/raindog308/gorqlite* github.com/rqlite/gorqlite*
39+
gorqlite,https://github.com/rqlite/gorqlite,github.com/raindog308/gorqlite* github.com/rqlite/gorqlite* github.com/kanikanema/gorqlite*
3940
goxpath,https://github.com/ChrisTrenkamp/goxpath/wiki,github.com/ChrisTrenkamp/goxpath*
4041
htmlquery,https://github.com/antchfx/htmlquery,github.com/antchfx/htmlquery*
4142
Iris,https://www.iris-go.com/,github.com/kataras/iris*
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* The first argument of `Client.Query` in `cloud.google.com/go/bigquery` is now recognized as a SQL injection sink.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
extensions:
2+
- addsTo:
3+
pack: codeql/go-all
4+
extensible: sinkModel
5+
data:
6+
- ["cloud.google.com/go/bigquery", "Client", True, "Query", "", "", "Argument[0]", "sql-injection", "manual"]
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
invalidModelRow
2+
testFailures
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import go
2+
import semmle.go.dataflow.ExternalFlow
3+
import ModelValidation
4+
import utils.test.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.getLocation() = location and
13+
element = q.toString() and
14+
value = qs.toString()
15+
)
16+
}
17+
}
18+
19+
module QueryString implements TestSig {
20+
string getARelevantTag() { result = "querystring" }
21+
22+
predicate hasActualResult(Location location, string element, string tag, string value) {
23+
tag = "querystring" and
24+
element = "" and
25+
exists(SQL::QueryString qs | not exists(SQL::Query q | qs = q.getAQueryString()) |
26+
qs.getLocation() = location and
27+
value = qs.toString()
28+
)
29+
}
30+
}
31+
32+
module Config implements DataFlow::ConfigSig {
33+
predicate isSource(DataFlow::Node n) { n.asExpr() instanceof StringLit }
34+
35+
predicate isSink(DataFlow::Node n) {
36+
n = any(DataFlow::CallNode cn | cn.getTarget().getName() = "sink").getAnArgument()
37+
}
38+
}
39+
40+
module Flow = TaintTracking::Global<Config>;
41+
42+
module TaintFlow implements TestSig {
43+
string getARelevantTag() { result = "flowfrom" }
44+
45+
predicate hasActualResult(Location location, string element, string tag, string value) {
46+
tag = "flowfrom" and
47+
element = "" and
48+
exists(DataFlow::Node fromNode, DataFlow::Node toNode |
49+
toNode.getLocation() = location and
50+
Flow::flow(fromNode, toNode) and
51+
value = fromNode.asExpr().(StringLit).getValue()
52+
)
53+
}
54+
}
55+
56+
import MakeTest<MergeTests3<SqlTest, QueryString, TaintFlow>>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
| bigquery.go:17:15:17:23 | untrusted | cloud.google.com/go/bigquery.Client | Query |
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package main
2+
3+
//go:generate depstubber -vendor cloud.google.com/go/bigquery Client
4+
5+
import (
6+
"cloud.google.com/go/bigquery"
7+
)
8+
9+
func getUntrustedString() string {
10+
return "trouble"
11+
}
12+
13+
func main() {
14+
untrusted := getUntrustedString()
15+
var client *bigquery.Client
16+
17+
client.Query(untrusted) // $ querystring=untrusted
18+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import go
2+
3+
from SQL::QueryString qs, Function func, string a, string b
4+
where
5+
func.hasQualifiedName(a, b) and
6+
qs = func.getACall().getSyntacticArgument(_)
7+
select qs, a, b
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
module bigquerytest
2+
3+
go 1.24
4+
5+
require cloud.google.com/go/bigquery v1.68.0
6+
7+
require (
8+
cloud.google.com/go v0.121.0 // indirect
9+
cloud.google.com/go/auth v0.16.1 // indirect
10+
cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
11+
cloud.google.com/go/compute/metadata v0.6.0 // indirect
12+
cloud.google.com/go/iam v1.5.2 // indirect
13+
github.com/apache/arrow/go/v15 v15.0.2 // indirect
14+
github.com/felixge/httpsnoop v1.0.4 // indirect
15+
github.com/go-logr/logr v1.4.2 // indirect
16+
github.com/go-logr/stdr v1.2.2 // indirect
17+
github.com/goccy/go-json v0.10.2 // indirect
18+
github.com/google/flatbuffers v23.5.26+incompatible // indirect
19+
github.com/google/s2a-go v0.1.9 // indirect
20+
github.com/google/uuid v1.6.0 // indirect
21+
github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect
22+
github.com/googleapis/gax-go/v2 v2.14.1 // indirect
23+
github.com/klauspost/compress v1.16.7 // indirect
24+
github.com/klauspost/cpuid/v2 v2.2.5 // indirect
25+
github.com/pierrec/lz4/v4 v4.1.18 // indirect
26+
github.com/zeebo/xxh3 v1.0.2 // indirect
27+
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
28+
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 // indirect
29+
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 // indirect
30+
go.opentelemetry.io/otel v1.35.0 // indirect
31+
go.opentelemetry.io/otel/metric v1.35.0 // indirect
32+
go.opentelemetry.io/otel/trace v1.35.0 // indirect
33+
golang.org/x/crypto v0.37.0 // indirect
34+
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect
35+
golang.org/x/mod v0.23.0 // indirect
36+
golang.org/x/net v0.39.0 // indirect
37+
golang.org/x/oauth2 v0.29.0 // indirect
38+
golang.org/x/sync v0.14.0 // indirect
39+
golang.org/x/sys v0.32.0 // indirect
40+
golang.org/x/text v0.24.0 // indirect
41+
golang.org/x/time v0.11.0 // indirect
42+
golang.org/x/tools v0.30.0 // indirect
43+
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect
44+
google.golang.org/api v0.231.0 // indirect
45+
google.golang.org/genproto v0.0.0-20250303144028-a0af3efb3deb // indirect
46+
google.golang.org/genproto/googleapis/api v0.0.0-20250428153025-10db94c68c34 // indirect
47+
google.golang.org/genproto/googleapis/rpc v0.0.0-20250428153025-10db94c68c34 // indirect
48+
google.golang.org/grpc v1.72.0 // indirect
49+
google.golang.org/protobuf v1.36.6 // indirect
50+
)

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy