mirror of
https://github.com/github/codeql.git
synced 2026-07-21 03:08:25 +02:00
Merge pull request #19203 from owen-mc/review/egregius313/17905
Go: Add database source models for `uptrace/bun` and `gogf/gf/database/gdb`
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Local source models for APIs reading from databases have been added for `github.com/gogf/gf/database/gdb` and `github.com/uptrace/bun`.
|
||||
@@ -55,3 +55,76 @@ extensions:
|
||||
- ["github.com/gogf/gf/database/gdb", "Tx", True, "Prepare", "", "", "Argument[0]", "sql-injection", "manual"]
|
||||
- ["github.com/gogf/gf/database/gdb", "Tx", True, "Query", "", "", "Argument[0]", "sql-injection", "manual"]
|
||||
- ["github.com/gogf/gf/database/gdb", "Tx", True, "Raw", "", "", "Argument[0]", "sql-injection", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: sourceModel
|
||||
data:
|
||||
# These models are for v1. Some of them hold for v2, but we should model v2 properly.
|
||||
- ["github.com/gogf/gf/database/gdb", "Core", True, "DoGetAll", "", "", "ReturnValue[0]", "database", "manual"]
|
||||
- ["github.com/gogf/gf/database/gdb", "Core", True, "DoQuery", "", "", "ReturnValue[0]", "database", "manual"]
|
||||
- ["github.com/gogf/gf/database/gdb", "Core", True, "GetAll", "", "", "ReturnValue[0]", "database", "manual"]
|
||||
- ["github.com/gogf/gf/database/gdb", "Core", True, "GetArray", "", "", "ReturnValue[0]", "database", "manual"]
|
||||
- ["github.com/gogf/gf/database/gdb", "Core", True, "GetOne", "", "", "ReturnValue[0]", "database", "manual"]
|
||||
- ["github.com/gogf/gf/database/gdb", "Core", True, "GetScan", "", "", "Argument[0]", "database", "manual"]
|
||||
- ["github.com/gogf/gf/database/gdb", "Core", True, "GetStruct", "", "", "Argument[0]", "database", "manual"]
|
||||
- ["github.com/gogf/gf/database/gdb", "Core", True, "GetStructs", "", "", "Argument[0]", "database", "manual"]
|
||||
- ["github.com/gogf/gf/database/gdb", "Core", True, "GetValue", "", "", "ReturnValue[0]", "database", "manual"]
|
||||
- ["github.com/gogf/gf/database/gdb", "Core", True, "Query", "", "", "ReturnValue[0]", "database", "manual"]
|
||||
|
||||
- ["github.com/gogf/gf/database/gdb", "DB", True, "DoGetAll", "", "", "ReturnValue[0]", "database", "manual"]
|
||||
- ["github.com/gogf/gf/database/gdb", "DB", True, "DoQuery", "", "", "ReturnValue[0]", "database", "manual"]
|
||||
- ["github.com/gogf/gf/database/gdb", "DB", True, "GetAll", "", "", "ReturnValue[0]", "database", "manual"]
|
||||
- ["github.com/gogf/gf/database/gdb", "DB", True, "GetArray", "", "", "ReturnValue[0]", "database", "manual"]
|
||||
- ["github.com/gogf/gf/database/gdb", "DB", True, "GetOne", "", "", "ReturnValue[0]", "database", "manual"]
|
||||
- ["github.com/gogf/gf/database/gdb", "DB", True, "GetScan", "", "", "Argument[0]", "database", "manual"]
|
||||
- ["github.com/gogf/gf/database/gdb", "DB", True, "GetValue", "", "", "ReturnValue[0]", "database", "manual"]
|
||||
- ["github.com/gogf/gf/database/gdb", "DB", True, "Query", "", "", "ReturnValue[0]", "database", "manual"]
|
||||
|
||||
- ["github.com/gogf/gf/database/gdb", "Model", True, "All", "", "", "ReturnValue[0]", "database", "manual"]
|
||||
- ["github.com/gogf/gf/database/gdb", "Model", True, "Array", "", "", "ReturnValue[0]", "database", "manual"]
|
||||
- ["github.com/gogf/gf/database/gdb", "Model", True, "FindAll", "", "", "ReturnValue[0]", "database", "manual"]
|
||||
- ["github.com/gogf/gf/database/gdb", "Model", True, "FindArray", "", "", "ReturnValue[0]", "database", "manual"]
|
||||
- ["github.com/gogf/gf/database/gdb", "Model", True, "FindOne", "", "", "ReturnValue[0]", "database", "manual"]
|
||||
- ["github.com/gogf/gf/database/gdb", "Model", True, "FindScan", "", "", "Argument[0]", "database", "manual"]
|
||||
- ["github.com/gogf/gf/database/gdb", "Model", True, "FindValue", "", "", "ReturnValue[0]", "database", "manual"]
|
||||
- ["github.com/gogf/gf/database/gdb", "Model", True, "One", "", "", "ReturnValue[0]", "database", "manual"]
|
||||
- ["github.com/gogf/gf/database/gdb", "Model", True, "Scan", "", "", "Argument[0]", "database", "manual"]
|
||||
- ["github.com/gogf/gf/database/gdb", "Model", True, "ScanList", "", "", "Argument[0]", "database", "manual"]
|
||||
- ["github.com/gogf/gf/database/gdb", "Model", True, "Select", "", "", "ReturnValue[0]", "database", "manual"]
|
||||
- ["github.com/gogf/gf/database/gdb", "Model", True, "Struct", "", "", "Argument[0]", "database", "manual"]
|
||||
- ["github.com/gogf/gf/database/gdb", "Model", True, "Structs", "", "", "Argument[0]", "database", "manual"]
|
||||
- ["github.com/gogf/gf/database/gdb", "Model", True, "Value", "", "", "ReturnValue[0]", "database", "manual"]
|
||||
|
||||
- ["github.com/gogf/gf/database/gdb", "TX", True, "GetAll", "", "", "ReturnValue[0]", "database", "manual"]
|
||||
- ["github.com/gogf/gf/database/gdb", "TX", True, "GetOne", "", "", "ReturnValue[0]", "database", "manual"]
|
||||
- ["github.com/gogf/gf/database/gdb", "TX", True, "GetScan", "", "", "Argument[0]", "database", "manual"]
|
||||
- ["github.com/gogf/gf/database/gdb", "TX", True, "GetStruct", "", "", "Argument[0]", "database", "manual"]
|
||||
- ["github.com/gogf/gf/database/gdb", "TX", True, "GetStructs", "", "", "Argument[0]", "database", "manual"]
|
||||
- ["github.com/gogf/gf/database/gdb", "TX", True, "GetValue", "", "", "ReturnValue[0]", "database", "manual"]
|
||||
- ["github.com/gogf/gf/database/gdb", "TX", True, "Query", "", "", "ReturnValue[0]", "database", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: summaryModel
|
||||
data:
|
||||
- ["github.com/gogf/gf/database/gdb", "Record", True, "GMap", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"]
|
||||
- ["github.com/gogf/gf/database/gdb", "Record", True, "Interface", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"]
|
||||
- ["github.com/gogf/gf/database/gdb", "Record", True, "Json", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"]
|
||||
- ["github.com/gogf/gf/database/gdb", "Record", True, "Map", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"]
|
||||
- ["github.com/gogf/gf/database/gdb", "Record", True, "Struct", "", "", "Argument[receiver]", "Argument[0]", "taint", "manual"]
|
||||
- ["github.com/gogf/gf/database/gdb", "Record", True, "Xml", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"]
|
||||
|
||||
- ["github.com/gogf/gf/database/gdb", "Result", True, "Array", "", "", "Argument[receiver]", "ReturnValue.ArrayElement", "taint", "manual"]
|
||||
- ["github.com/gogf/gf/database/gdb", "Result", True, "Chunk", "", "", "Argument[receiver]", "ReturnValue.ArrayElement", "taint", "manual"]
|
||||
- ["github.com/gogf/gf/database/gdb", "Result", True, "Interface", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"]
|
||||
- ["github.com/gogf/gf/database/gdb", "Result", True, "Json", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"]
|
||||
- ["github.com/gogf/gf/database/gdb", "Result", True, "List", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"]
|
||||
- ["github.com/gogf/gf/database/gdb", "Result", True, "MapKeyInt", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"]
|
||||
- ["github.com/gogf/gf/database/gdb", "Result", True, "MapKeyStr", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"]
|
||||
- ["github.com/gogf/gf/database/gdb", "Result", True, "MapKeyUint", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"]
|
||||
- ["github.com/gogf/gf/database/gdb", "Result", True, "MapKeyValue", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"]
|
||||
- ["github.com/gogf/gf/database/gdb", "Result", True, "RecordKeyInt", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"]
|
||||
- ["github.com/gogf/gf/database/gdb", "Result", True, "RecordKeyStr", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"]
|
||||
- ["github.com/gogf/gf/database/gdb", "Result", True, "RecordKeyUint", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"]
|
||||
- ["github.com/gogf/gf/database/gdb", "Result", True, "ScanList", "", "", "Argument[receiver]", "Argument[0]", "taint", "manual"]
|
||||
- ["github.com/gogf/gf/database/gdb", "Result", True, "Structs", "", "", "Argument[receiver]", "Argument[0]", "taint", "manual"]
|
||||
- ["github.com/gogf/gf/database/gdb", "Result", True, "Xml", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"]
|
||||
|
||||
@@ -1,4 +1,21 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: sourceModel
|
||||
data:
|
||||
- ["github.com/uptrace/bun", "DB", True, "Query", "", "", "ReturnValue[0]", "database", "manual"]
|
||||
- ["github.com/uptrace/bun", "DB", True, "QueryRow", "", "", "ReturnValue", "database", "manual"]
|
||||
- ["github.com/uptrace/bun", "IDB", True, "QueryContext", "", "", "ReturnValue[0]", "database", "manual"]
|
||||
- ["github.com/uptrace/bun", "IDB", True, "QueryRowContext", "", "", "ReturnValue", "database", "manual"]
|
||||
# - ["github.com/uptrace/bun", "RawQuery", True, "Exec", "", "", "Argument[0]", "database", "manual"] # Implemented in QL because variadic arguments as sources aren't supported in this format yet
|
||||
# - ["github.com/uptrace/bun", "RawQuery", True, "Scan", "", "", "Argument[0]", "database", "manual"] # Implemented in QL because variadic arguments as sources aren't supported in this format yet
|
||||
# - ["github.com/uptrace/bun", "SelectQuery", True, "Exec", "", "", "Argument[0]", "database", "manual"] # Implemented in QL because variadic arguments as sources aren't supported in this format yet
|
||||
- ["github.com/uptrace/bun", "SelectQuery", True, "Model", "", "", "Argument[0]", "database", "manual"]
|
||||
- ["github.com/uptrace/bun", "SelectQuery", True, "Rows", "", "", "ReturnValue[0]", "database", "manual"]
|
||||
# - ["github.com/uptrace/bun", "SelectQuery", True, "Scan", "", "", "Argument[1]", "database", "manual"] # Implemented in QL because variadic arguments as sources aren't supported in this format yet
|
||||
# - ["github.com/uptrace/bun", "SelectQuery", True, "ScanAndCount", "", "", "Argument[1]", "database", "manual"] # Implemented in QL because variadic arguments as sources aren't supported in this format yet
|
||||
- ["github.com/uptrace/bun", "Tx", True, "Query", "", "", "ReturnValue[0]", "database", "manual"]
|
||||
- ["github.com/uptrace/bun", "Tx", True, "QueryRow", "", "", "ReturnValue", "database", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: sinkModel
|
||||
@@ -66,3 +83,9 @@ extensions:
|
||||
- ["github.com/uptrace/bun", "UpdateQuery", True, "TableExpr", "", "", "Argument[0]", "sql-injection", "manual"]
|
||||
- ["github.com/uptrace/bun", "UpdateQuery", True, "Where", "", "", "Argument[0]", "sql-injection", "manual"]
|
||||
- ["github.com/uptrace/bun", "UpdateQuery", True, "WhereOr", "", "", "Argument[0]", "sql-injection", "manual"]
|
||||
# - addsTo:
|
||||
# pack: codeql/go-all
|
||||
# extensible: summaryModel
|
||||
# data:
|
||||
# - ["github.com/uptrace/bun", "DB", True, "ScanRow", "", "", "Argument[1]", "Argument[2].ArrayElement", "taint", "manual"] # Implemented in QL because variadic arguments as outputs aren't supported in this format yet
|
||||
# - ["github.com/uptrace/bun", "DB", True, "ScanRows", "", "", "Argument[1]", "Argument[2].ArrayElement", "taint", "manual"] # Implemented in QL because variadic arguments as outputs aren't supported in this format yet
|
||||
|
||||
@@ -32,6 +32,7 @@ import semmle.go.frameworks.Afero
|
||||
import semmle.go.frameworks.AwsLambda
|
||||
import semmle.go.frameworks.Beego
|
||||
import semmle.go.frameworks.BeegoOrm
|
||||
import semmle.go.frameworks.Bun
|
||||
import semmle.go.frameworks.RsCors
|
||||
import semmle.go.frameworks.Couchbase
|
||||
import semmle.go.frameworks.Echo
|
||||
|
||||
62
go/ql/lib/semmle/go/frameworks/Bun.qll
Normal file
62
go/ql/lib/semmle/go/frameworks/Bun.qll
Normal file
@@ -0,0 +1,62 @@
|
||||
/**
|
||||
* Provides classes modeling security-relevant aspects of the `Bun` package.
|
||||
*/
|
||||
|
||||
import go
|
||||
|
||||
/**
|
||||
* Provides classes modeling security-relevant aspects of the `Bun` package.
|
||||
*/
|
||||
private module Bun {
|
||||
private string packagePath() { result = package("github.com/uptrace/bun", "") }
|
||||
|
||||
private class RawQuerySources extends SourceNode {
|
||||
RawQuerySources() {
|
||||
// func (q *RawQuery) Exec(ctx context.Context, dest ...interface{}) (sql.Result, error)
|
||||
// func (q *RawQuery) Scan(ctx context.Context, dest ...interface{}) error
|
||||
exists(DataFlow::CallNode cn, int i |
|
||||
cn.getTarget().(Method).hasQualifiedName(packagePath(), "RawQuery", ["Exec", "Scan"]) and
|
||||
i >= 1
|
||||
|
|
||||
this = cn.getSyntacticArgument(i)
|
||||
)
|
||||
}
|
||||
|
||||
override string getThreatModel() { result = "database" }
|
||||
}
|
||||
|
||||
private class SelectQuerySources extends SourceNode {
|
||||
SelectQuerySources() {
|
||||
// func (q *SelectQuery) Exec(ctx context.Context, dest ...interface{}) (res sql.Result, err error)
|
||||
// func (q *SelectQuery) Scan(ctx context.Context, dest ...interface{}) error
|
||||
// func (q *SelectQuery) ScanAndCount(ctx context.Context, dest ...interface{}) (int, error)
|
||||
exists(DataFlow::CallNode cn, int i |
|
||||
cn.getTarget()
|
||||
.(Method)
|
||||
.hasQualifiedName(packagePath(), "SelectQuery", ["Exec", "Scan", "ScanAndCount"]) and
|
||||
i >= 1
|
||||
|
|
||||
this = cn.getSyntacticArgument(i)
|
||||
)
|
||||
}
|
||||
|
||||
override string getThreatModel() { result = "database" }
|
||||
}
|
||||
|
||||
private class DBScanRows extends TaintTracking::FunctionModel, Method {
|
||||
FunctionInput inp;
|
||||
FunctionOutput outp;
|
||||
|
||||
DBScanRows() {
|
||||
// func (db *DB) ScanRow(ctx context.Context, rows *sql.Rows, dest ...interface{}) error
|
||||
// func (db *DB) ScanRows(ctx context.Context, rows *sql.Rows, dest ...interface{}) error
|
||||
this.hasQualifiedName(packagePath(), "DB", ["ScanRow", "ScanRows"]) and
|
||||
inp.isParameter(1) and
|
||||
outp.isParameter(any(int i | i >= 2))
|
||||
}
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
input = inp and output = outp
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,12 +7,13 @@ require (
|
||||
github.com/beego/beego/v2 v2.3.5
|
||||
github.com/couchbase/gocb v1.6.7
|
||||
github.com/couchbase/gocb/v2 v2.9.4
|
||||
github.com/gogf/gf v1.16.9
|
||||
github.com/jmoiron/sqlx v1.4.0
|
||||
github.com/Masterminds/squirrel v1.5.4
|
||||
github.com/rqlite/gorqlite v0.0.0-20250128004930-114c7828b55a
|
||||
github.com/uptrace/bun v1.2.11
|
||||
go.mongodb.org/mongo-driver v1.17.3
|
||||
gorm.io/gorm v1.25.12
|
||||
github.com/nonexistent/sources v0.0.0-20250300000000-000000000000
|
||||
)
|
||||
|
||||
require (
|
||||
|
||||
@@ -8,4 +8,4 @@ extensions:
|
||||
pack: codeql/go-all
|
||||
extensible: sourceModel
|
||||
data:
|
||||
- ["github.com/nonexistent/sources", "", False, "Source", "", "", "ReturnValue", "database", "manual"]
|
||||
- ["test", "", False, "Source", "", "", "ReturnValue", "database", "manual"]
|
||||
|
||||
@@ -10,4 +10,4 @@ extensions:
|
||||
pack: codeql/go-all
|
||||
extensible: sourceModel
|
||||
data:
|
||||
- ["github.com/nonexistent/sources", "", False, "Source", "", "", "ReturnValue", "database", "manual"]
|
||||
- ["test", "", False, "Source", "", "", "ReturnValue", "database", "manual"]
|
||||
|
||||
@@ -6,9 +6,12 @@ import (
|
||||
"context"
|
||||
|
||||
"github.com/Masterminds/squirrel"
|
||||
src "github.com/nonexistent/sources"
|
||||
)
|
||||
|
||||
func Source[T any]() T {
|
||||
return *new(T)
|
||||
}
|
||||
|
||||
func test_Masterminds_squirrel_QueryRower(ctx context.Context, db squirrel.QueryRower, sqlizer squirrel.Sqlizer) {
|
||||
scanner := db.QueryRow("") // $ source
|
||||
|
||||
@@ -136,7 +139,7 @@ func test_Masterminds_squirrel_DeleteBuilder(ctx context.Context, builder squirr
|
||||
sink(r32) // $ hasTaintFlow="r32"
|
||||
sink(r33) // $ hasTaintFlow="r33"
|
||||
|
||||
builder2 := src.Source[squirrel.DeleteBuilder]() // $ source
|
||||
builder2 := Source[squirrel.DeleteBuilder]() // $ source
|
||||
|
||||
var r41, r42, r43 string
|
||||
builder2.ScanContext(ctx, &r41, &r42, &r43)
|
||||
@@ -177,7 +180,7 @@ func test_Masterminds_squirrel_InsertBuilder(ctx context.Context, builder squirr
|
||||
sink(r42) // $ hasTaintFlow="r42"
|
||||
sink(r43) // $ hasTaintFlow="r43"
|
||||
|
||||
builder2 := src.Source[squirrel.InsertBuilder]() // $ source
|
||||
builder2 := Source[squirrel.InsertBuilder]() // $ source
|
||||
|
||||
var r51, r52, r53 string
|
||||
builder2.Scan(&r51, &r52, &r53)
|
||||
@@ -225,7 +228,7 @@ func test_Masterminds_squirrel_SelectBuilder(ctx context.Context, builder squirr
|
||||
sink(r42) // $ hasTaintFlow="r42"
|
||||
sink(r43) // $ hasTaintFlow="r43"
|
||||
|
||||
builder2 := src.Source[squirrel.SelectBuilder]() // $ source
|
||||
builder2 := Source[squirrel.SelectBuilder]() // $ source
|
||||
|
||||
var r51, r52, r53 string
|
||||
builder2.Scan(&r51, &r52, &r53)
|
||||
@@ -273,7 +276,7 @@ func test_Masterminds_squirrel_UpdateBuilder(ctx context.Context, builder squirr
|
||||
sink(r42) // $ hasTaintFlow="r42"
|
||||
sink(r43) // $ hasTaintFlow="r43"
|
||||
|
||||
builder2 := src.Source[squirrel.UpdateBuilder]() // $ source
|
||||
builder2 := Source[squirrel.UpdateBuilder]() // $ source
|
||||
|
||||
var r51, r52, r53 string
|
||||
builder2.Scan(&r51, &r52, &r53)
|
||||
|
||||
@@ -0,0 +1,242 @@
|
||||
package test
|
||||
|
||||
//go:generate depstubber -vendor github.com/gogf/gf/database/gdb Core,DB,Model,TX,Record,Result
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/database/gdb"
|
||||
)
|
||||
|
||||
func gogf_Core(g gdb.Core) {
|
||||
v1, _ := g.DoGetAll(nil, nil, "SELECT user from users") // $ source
|
||||
sink(v1) // $ hasTaintFlow="v1"
|
||||
|
||||
v2, _ := g.DoQuery(nil, nil, "SELECT user from users") // $ source
|
||||
sink(v2) // $ hasTaintFlow="v2"
|
||||
|
||||
v3, _ := g.GetAll("SELECT user from users") // $ source
|
||||
sink(v3) // $ hasTaintFlow="v3"
|
||||
|
||||
v4, _ := g.GetArray("SELECT user from users") // $ source
|
||||
sink(v4) // $ hasTaintFlow="v4"
|
||||
|
||||
v5, _ := g.GetOne("SELECT user from users") // $ source
|
||||
sink(v5) // $ hasTaintFlow="v5"
|
||||
|
||||
var v6 User
|
||||
g.GetScan(&v6, "SELECT user from users") // $ source
|
||||
sink(v6) // $ hasTaintFlow="v6"
|
||||
|
||||
var v7 User
|
||||
g.GetStruct(&v7, "SELECT user from users") // $ source
|
||||
sink(v7) // $ hasTaintFlow="v7"
|
||||
|
||||
var v8 []User // $ source
|
||||
g.GetStructs(v8, "SELECT user from users")
|
||||
sink(v8) // $ hasTaintFlow="v8"
|
||||
|
||||
v9, _ := g.GetValue("SELECT user from users") // $ source
|
||||
sink(v9) // $ hasTaintFlow="v9"
|
||||
|
||||
v10, _ := g.Query("SELECT user from users") // $ source
|
||||
sink(v10) // $ hasTaintFlow="v10"
|
||||
}
|
||||
|
||||
func gogf_DB(g gdb.DB) {
|
||||
v1, _ := g.DoGetAll(nil, nil, "SELECT user from users") // $ source
|
||||
sink(v1) // $ hasTaintFlow="v1"
|
||||
|
||||
v2, _ := g.DoQuery(nil, nil, "SELECT user from users") // $ source
|
||||
sink(v2) // $ hasTaintFlow="v2"
|
||||
|
||||
v3, _ := g.GetAll("SELECT user from users") // $ source
|
||||
sink(v3) // $ hasTaintFlow="v3"
|
||||
|
||||
v4, _ := g.GetArray("SELECT user from users") // $ source
|
||||
sink(v4) // $ hasTaintFlow="v4"
|
||||
|
||||
v5, _ := g.GetOne("SELECT user from users") // $ source
|
||||
sink(v5) // $ hasTaintFlow="v5"
|
||||
|
||||
var v6 User
|
||||
g.GetScan(&v6, "SELECT user from users") // $ source
|
||||
sink(v6) // $ hasTaintFlow="v6"
|
||||
|
||||
v7, _ := g.GetValue("SELECT user from users") // $ source
|
||||
sink(v7) // $ hasTaintFlow="v7"
|
||||
|
||||
v8, _ := g.Query("SELECT user from users") // $ source
|
||||
sink(v8) // $ hasTaintFlow="v8"
|
||||
}
|
||||
|
||||
func gogf_Model(g gdb.Model) {
|
||||
v1, _ := g.All() // $ source
|
||||
sink(v1) // $ hasTaintFlow="v1"
|
||||
|
||||
v2, _ := g.Array() // $ source
|
||||
sink(v2) // $ hasTaintFlow="v2"
|
||||
|
||||
v3, _ := g.FindAll() // $ source
|
||||
sink(v3) // $ hasTaintFlow="v3"
|
||||
|
||||
v4, _ := g.FindArray() // $ source
|
||||
sink(v4) // $ hasTaintFlow="v4"
|
||||
|
||||
v5, _ := g.FindOne() // $ source
|
||||
sink(v5) // $ hasTaintFlow="v5"
|
||||
|
||||
var v6 User
|
||||
g.FindScan(&v6) // $ source
|
||||
sink(v6) // $ hasTaintFlow="v6"
|
||||
|
||||
v7, _ := g.FindValue() // $ source
|
||||
sink(v7) // $ hasTaintFlow="v7"
|
||||
|
||||
v8, _ := g.One() // $ source
|
||||
sink(v8) // $ hasTaintFlow="v8"
|
||||
|
||||
var v9 User
|
||||
g.Scan(&v9) // $ source
|
||||
sink(v9) // $ hasTaintFlow="v9"
|
||||
|
||||
var v10 []User
|
||||
g.ScanList(&v10, "") // $ source
|
||||
sink(v10) // $ hasTaintFlow="v10"
|
||||
|
||||
v11, _ := g.Select() // $ source
|
||||
sink(v11) // $ hasTaintFlow="v11"
|
||||
|
||||
var v12 User
|
||||
g.Struct(&v12) // $ source
|
||||
sink(v12) // $ hasTaintFlow="v12"
|
||||
|
||||
var v13 []User
|
||||
g.Structs(&v13, "") // $ source
|
||||
sink(v13) // $ hasTaintFlow="v13"
|
||||
|
||||
v14, _ := g.Value() // $ source
|
||||
sink(v14) // $ hasTaintFlow="v14"
|
||||
}
|
||||
|
||||
func gogf_TX(g gdb.TX) {
|
||||
v1, _ := g.GetAll("SELECT user from users") // $ source
|
||||
sink(v1) // $ hasTaintFlow="v1"
|
||||
|
||||
v2, _ := g.GetOne("SELECT user from users") // $ source
|
||||
sink(v2) // $ hasTaintFlow="v2"
|
||||
|
||||
var v3 User
|
||||
g.GetScan(&v3, "SELECT user from users") // $ source
|
||||
sink(v3) // $ hasTaintFlow="v3"
|
||||
|
||||
var v4 User
|
||||
g.GetStruct(&v4, "SELECT user from users") // $ source
|
||||
sink(v4) // $ hasTaintFlow="v4"
|
||||
|
||||
var v5 []User // $ source
|
||||
g.GetStructs(v5, "SELECT user from users")
|
||||
sink(v5) // $ hasTaintFlow="v5"
|
||||
|
||||
v6, _ := g.GetValue("SELECT user from users") // $ source
|
||||
sink(v6) // $ hasTaintFlow="v6"
|
||||
|
||||
v7, _ := g.Query("SELECT user from users") // $ source
|
||||
sink(v7) // $ hasTaintFlow="v7"
|
||||
}
|
||||
|
||||
func gogf_Record_summary(g gdb.Core) {
|
||||
record1, _ := g.GetOne("SELECT summary from records") // $ source
|
||||
gmap := record1.GMap()
|
||||
sink(gmap) // $ hasTaintFlow="gmap"
|
||||
|
||||
record2, _ := g.GetOne("SELECT summary from records") // $ source
|
||||
interface_ := record2.Interface()
|
||||
sink(interface_) // $ hasTaintFlow="interface_"
|
||||
|
||||
record3, _ := g.GetOne("SELECT summary from records") // $ source
|
||||
json := record3.Json()
|
||||
sink(json) // $ hasTaintFlow="json"
|
||||
|
||||
record4, _ := g.GetOne("SELECT summary from records") // $ source
|
||||
map_ := record4.Map()
|
||||
sink(map_) // $ hasTaintFlow="map_"
|
||||
|
||||
record5, _ := g.GetOne("SELECT summary from records") // $ source
|
||||
var struct_ struct{}
|
||||
record5.Struct(&struct_)
|
||||
sink(struct_) // $ hasTaintFlow="struct_"
|
||||
|
||||
record6, _ := g.GetOne("SELECT summary from records") // $ source
|
||||
xml := record6.Xml()
|
||||
sink(xml) // $ hasTaintFlow="xml"
|
||||
|
||||
// Note: currently missing models for methods on return type of `GMap`,
|
||||
// which is `StrAnyMap` from package "github.com/gogf/gf/container/gmap".
|
||||
}
|
||||
|
||||
func gogf_Result_summary(g gdb.Core) {
|
||||
result1, _ := g.GetAll("SELECT summary from records") // $ source
|
||||
array := result1.Array()
|
||||
sink(array) // $ hasTaintFlow="array"
|
||||
|
||||
result2, _ := g.GetAll("SELECT summary from records") // $ source
|
||||
chunk := result2.Chunk(1)
|
||||
sink(chunk) // $ hasTaintFlow="chunk"
|
||||
|
||||
result3, _ := g.GetAll("SELECT summary from records") // $ source
|
||||
interface_ := result3.Interface()
|
||||
sink(interface_) // $ hasTaintFlow="interface_"
|
||||
|
||||
result4, _ := g.GetAll("SELECT summary from records") // $ source
|
||||
json := result4.Json()
|
||||
sink(json) // $ hasTaintFlow="json"
|
||||
|
||||
result5, _ := g.GetAll("SELECT summary from records") // $ source
|
||||
list := result5.List()
|
||||
sink(list) // $ hasTaintFlow="list"
|
||||
|
||||
result6, _ := g.GetAll("SELECT summary from records") // $ source
|
||||
mapkeyint := result6.MapKeyInt("")
|
||||
sink(mapkeyint) // $ hasTaintFlow="mapkeyint"
|
||||
|
||||
result7, _ := g.GetAll("SELECT summary from records") // $ source
|
||||
mapkeystr := result7.MapKeyStr("")
|
||||
sink(mapkeystr) // $ hasTaintFlow="mapkeystr"
|
||||
|
||||
result8, _ := g.GetAll("SELECT summary from records") // $ source
|
||||
mapkeyuint := result8.MapKeyUint("")
|
||||
sink(mapkeyuint) // $ hasTaintFlow="mapkeyuint"
|
||||
|
||||
result9, _ := g.GetAll("SELECT summary from records") // $ source
|
||||
mapkeyvalue := result9.MapKeyValue("")
|
||||
sink(mapkeyvalue) // $ hasTaintFlow="mapkeyvalue"
|
||||
|
||||
result10, _ := g.GetAll("SELECT summary from records") // $ source
|
||||
recordkeyint := result10.RecordKeyInt("")
|
||||
sink(recordkeyint) // $ hasTaintFlow="recordkeyint"
|
||||
|
||||
result11, _ := g.GetAll("SELECT summary from records") // $ source
|
||||
recordkeystr := result11.RecordKeyStr("")
|
||||
sink(recordkeystr) // $ hasTaintFlow="recordkeystr"
|
||||
|
||||
result12, _ := g.GetAll("SELECT summary from records") // $ source
|
||||
recordkeyuint := result12.RecordKeyUint("")
|
||||
sink(recordkeyuint) // $ hasTaintFlow="recordkeyuint"
|
||||
|
||||
result13, _ := g.GetAll("SELECT summary from records") // $ source
|
||||
var structslice1 []struct{}
|
||||
result13.ScanList(&structslice1, "")
|
||||
sink(structslice1) // $ hasTaintFlow="structslice1"
|
||||
|
||||
result14, _ := g.GetAll("SELECT summary from records") // $ source
|
||||
var structslice2 []struct{}
|
||||
result14.Structs(&structslice2)
|
||||
sink(structslice2) // $ hasTaintFlow="structslice2"
|
||||
|
||||
result15, _ := g.GetAll("SELECT summary from records") // $ source
|
||||
xml := result15.Xml()
|
||||
sink(xml) // $ hasTaintFlow="xml"
|
||||
|
||||
// Note: currently missing models for methods on the type `Var` from
|
||||
// package "github.com/gogf/gf/container/gvar", which is involved in the
|
||||
// return type of `Array` and `MapKeyValue`.
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package test
|
||||
|
||||
//go:generate depstubber -vendor github.com/uptrace/bun Conn,DB,RawQuery,SelectQuery,Tx
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/uptrace/bun"
|
||||
)
|
||||
|
||||
func Test_bun_conn(conn bun.Conn) {
|
||||
ctx := context.Background()
|
||||
|
||||
rows1, _ := conn.QueryContext(ctx, "SELECT * FROM users") // $ source
|
||||
conn.QueryRowContext(ctx, "SELECT * FROM users") // $ source
|
||||
|
||||
ignore(rows1)
|
||||
}
|
||||
|
||||
func Test_bun_db(db bun.DB) {
|
||||
ctx := context.Background()
|
||||
|
||||
rows1, _ := db.Query("SELECT * FROM users") // $ source
|
||||
|
||||
for rows1.Next() {
|
||||
var user User
|
||||
db.ScanRow(ctx, rows1, &user)
|
||||
sink(user) // $ hasTaintFlow="user"
|
||||
}
|
||||
|
||||
rows2, _ := db.QueryContext(ctx, "SELECT * FROM users") // $ source
|
||||
var users []User
|
||||
|
||||
db.ScanRows(ctx, rows2, &users)
|
||||
sink(users) // $ hasTaintFlow="users"
|
||||
|
||||
db.QueryRow("SELECT * FROM users") // $ source
|
||||
db.QueryRowContext(ctx, "SELECT * FROM users") // $ source
|
||||
}
|
||||
|
||||
func Test_bun_rawquery(q bun.RawQuery) {
|
||||
ctx := context.Background()
|
||||
|
||||
var u1 []User
|
||||
q.Exec(ctx, &u1) // $ source
|
||||
var u2 []User
|
||||
q.Scan(ctx, &u2) // $ source
|
||||
}
|
||||
|
||||
func Test_bun_selectquery(q bun.SelectQuery) {
|
||||
ctx := context.Background()
|
||||
|
||||
rows, _ := q.Rows(ctx) // $ source
|
||||
var u1 []User
|
||||
q.Exec(ctx, &u1) // $ source
|
||||
var u2 []User
|
||||
q.Model(&u2).Scan(ctx) // $ source
|
||||
var u3 map[string]interface{}
|
||||
q.Scan(ctx, &u3) // $ source
|
||||
var u4 []User
|
||||
q.Model(&u4).ScanAndCount(ctx) // $ source
|
||||
var u5 map[string]interface{}
|
||||
q.ScanAndCount(ctx, &u5) // $ source
|
||||
|
||||
ignore(rows)
|
||||
}
|
||||
|
||||
func Test_bun_tx(tx bun.Tx) {
|
||||
ctx := context.Background()
|
||||
|
||||
rows1, _ := tx.Query("SELECT * FROM users") // $ source
|
||||
rows2, _ := tx.QueryContext(ctx, "SELECT * FROM users") // $ source
|
||||
tx.QueryRow("SELECT * FROM users") // $ source
|
||||
tx.QueryRowContext(ctx, "SELECT * FROM users") // $ source
|
||||
|
||||
ignore(rows1, rows2)
|
||||
}
|
||||
1175
go/ql/test/library-tests/semmle/go/dataflow/flowsources/local/database/vendor/github.com/gogf/gf/database/gdb/stub.go
generated
vendored
Normal file
1175
go/ql/test/library-tests/semmle/go/dataflow/flowsources/local/database/vendor/github.com/gogf/gf/database/gdb/stub.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,5 +0,0 @@
|
||||
package sources
|
||||
|
||||
func Source[T any]() T {
|
||||
return *new(T)
|
||||
}
|
||||
2763
go/ql/test/library-tests/semmle/go/dataflow/flowsources/local/database/vendor/github.com/uptrace/bun/stub.go
generated
vendored
Normal file
2763
go/ql/test/library-tests/semmle/go/dataflow/flowsources/local/database/vendor/github.com/uptrace/bun/stub.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@@ -10,6 +10,9 @@ github.com/couchbase/gocb
|
||||
# github.com/couchbase/gocb/v2 v2.9.4
|
||||
## explicit
|
||||
github.com/couchbase/gocb/v2
|
||||
# github.com/gogf/gf v1.16.9
|
||||
## explicit
|
||||
github.com/gogf/gf/database/gdb
|
||||
# github.com/jmoiron/sqlx v1.4.0
|
||||
## explicit
|
||||
github.com/jmoiron/sqlx
|
||||
@@ -19,15 +22,15 @@ github.com/Masterminds/squirrel
|
||||
# github.com/rqlite/gorqlite v0.0.0-20250128004930-114c7828b55a
|
||||
## explicit
|
||||
github.com/rqlite/gorqlite
|
||||
# github.com/uptrace/bun v1.2.11
|
||||
## explicit
|
||||
github.com/uptrace/bun
|
||||
# go.mongodb.org/mongo-driver v1.17.3
|
||||
## explicit
|
||||
go.mongodb.org/mongo-driver/mongo
|
||||
# gorm.io/gorm v1.25.12
|
||||
## explicit
|
||||
gorm.io/gorm
|
||||
# github.com/nonexistent/sources v0.0.0-20250300000000-000000000000
|
||||
## explicit
|
||||
github.com/nonexistent/sources
|
||||
# github.com/couchbase/gocbcore/v10 v10.5.4
|
||||
## explicit
|
||||
github.com/couchbase/gocbcore/v10
|
||||
|
||||
Reference in New Issue
Block a user