mirror of
https://github.com/github/codeql.git
synced 2025-12-17 01:03:14 +01:00
Add Bun models and tests
This commit is contained in:
@@ -3,24 +3,19 @@ extensions:
|
|||||||
pack: codeql/go-all
|
pack: codeql/go-all
|
||||||
extensible: sourceModel
|
extensible: sourceModel
|
||||||
data:
|
data:
|
||||||
- ["github.com/uptrace/bun", "AddColumnQuery", True, "Model", "", "", "Argument[0]", "database", "manual"]
|
- ["github.com/uptrace/bun", "DB", True, "Query", "", "", "ReturnValue[0]", "database", "manual"]
|
||||||
- ["github.com/uptrace/bun", "CreateIndexQuery", True, "Model", "", "", "Argument[0]", "database", "manual"]
|
- ["github.com/uptrace/bun", "DB", True, "QueryRow", "", "", "ReturnValue", "database", "manual"]
|
||||||
- ["github.com/uptrace/bun", "CreateTableQuery", True, "Model", "", "", "Argument[0]", "database", "manual"]
|
- ["github.com/uptrace/bun", "IDB", True, "QueryContext", "", "", "ReturnValue[0]", "database", "manual"]
|
||||||
- ["github.com/uptrace/bun", "DeleteQuery", True, "Model", "", "", "Argument[0]", "database", "manual"]
|
- ["github.com/uptrace/bun", "IDB", True, "QueryRowContext", "", "", "ReturnValue", "database", "manual"]
|
||||||
- ["github.com/uptrace/bun", "DropIndexQuery", True, "Model", "", "", "Argument[0]", "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", "DropTableQuery", True, "Model", "", "", "Argument[0]", "database", "manual"]
|
# - ["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", "InsertQuery", True, "Model", "", "", "Argument[0]", "database", "manual"]
|
# - ["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", "MergeQuery", True, "Model", "", "", "Argument[0]", "database", "manual"]
|
|
||||||
- ["github.com/uptrace/bun", "SelectQuery", True, "Model", "", "", "Argument[0]", "database", "manual"]
|
- ["github.com/uptrace/bun", "SelectQuery", True, "Model", "", "", "Argument[0]", "database", "manual"]
|
||||||
- ["github.com/uptrace/bun", "TruncateQuery", True, "Model", "", "", "Argument[0]", "database", "manual"]
|
- ["github.com/uptrace/bun", "SelectQuery", True, "Rows", "", "", "ReturnValue[0]", "database", "manual"]
|
||||||
- ["github.com/uptrace/bun", "UpdateQuery", True, "Model", "", "", "Argument[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", "DeleteQuery", True, "Scan", "", "", "Argument[0]", "database", "manual"]
|
# - ["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", "InsertQuery", True, "Scan", "", "", "Argument[0]", "database", "manual"]
|
- ["github.com/uptrace/bun", "Tx", True, "Query", "", "", "ReturnValue[0]", "database", "manual"]
|
||||||
- ["github.com/uptrace/bun", "MergeQuery", True, "Scan", "", "", "Argument[0]", "database", "manual"]
|
- ["github.com/uptrace/bun", "Tx", True, "QueryRow", "", "", "ReturnValue", "database", "manual"]
|
||||||
- ["github.com/uptrace/bun", "RawQuery", True, "Scan", "", "", "Argument[0]", "database", "manual"]
|
|
||||||
- ["github.com/uptrace/bun", "SelectQuery", True, "Scan", "", "", "Argument[0]", "database", "manual"]
|
|
||||||
- ["github.com/uptrace/bun", "TruncateQuery", True, "Scan", "", "", "Argument[0]", "database", "manual"]
|
|
||||||
- ["github.com/uptrace/bun", "UpdateQuery", True, "Scan", "", "", "Argument[0]", "database", "manual"]
|
|
||||||
- addsTo:
|
- addsTo:
|
||||||
pack: codeql/go-all
|
pack: codeql/go-all
|
||||||
extensible: sinkModel
|
extensible: sinkModel
|
||||||
@@ -88,3 +83,9 @@ extensions:
|
|||||||
- ["github.com/uptrace/bun", "UpdateQuery", True, "TableExpr", "", "", "Argument[0]", "sql-injection", "manual"]
|
- ["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, "Where", "", "", "Argument[0]", "sql-injection", "manual"]
|
||||||
- ["github.com/uptrace/bun", "UpdateQuery", True, "WhereOr", "", "", "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.AwsLambda
|
||||||
import semmle.go.frameworks.Beego
|
import semmle.go.frameworks.Beego
|
||||||
import semmle.go.frameworks.BeegoOrm
|
import semmle.go.frameworks.BeegoOrm
|
||||||
|
import semmle.go.frameworks.Bun
|
||||||
import semmle.go.frameworks.RsCors
|
import semmle.go.frameworks.RsCors
|
||||||
import semmle.go.frameworks.Couchbase
|
import semmle.go.frameworks.Couchbase
|
||||||
import semmle.go.frameworks.Echo
|
import semmle.go.frameworks.Echo
|
||||||
|
|||||||
90
go/ql/lib/semmle/go/frameworks/Bun.qll
Normal file
90
go/ql/lib/semmle/go/frameworks/Bun.qll
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
/**
|
||||||
|
* 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// private class BuilderScan extends TaintTracking::FunctionModel, Method {
|
||||||
|
// FunctionInput inp;
|
||||||
|
// FunctionOutput outp;
|
||||||
|
// BuilderScan() {
|
||||||
|
// // signature: func (b {Insert,Delete,Select,Update}Builder) Scan(dest ...interface{}) error
|
||||||
|
// this.hasQualifiedName(packagePath(),
|
||||||
|
// ["DeleteBuilder", "InsertBuilder", "SelectBuilder", "UpdateBuilder"], "Scan") and
|
||||||
|
// inp.isReceiver() and
|
||||||
|
// outp.isParameter(_)
|
||||||
|
// }
|
||||||
|
// override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||||
|
// input = inp and output = outp
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// private class BuilderScanContext extends TaintTracking::FunctionModel, Method {
|
||||||
|
// FunctionInput inp;
|
||||||
|
// FunctionOutput outp;
|
||||||
|
// BuilderScanContext() {
|
||||||
|
// // signature: func (b {Insert,Delete,Select,Update}Builder) ScanContext(ctx context.Context, dest ...interface{}) error
|
||||||
|
// this.hasQualifiedName(packagePath(),
|
||||||
|
// ["DeleteBuilder", "InsertBuilder", "SelectBuilder", "UpdateBuilder"], "ScanContext") and
|
||||||
|
// inp.isReceiver() and
|
||||||
|
// exists(int i | i > 0 | outp.isParameter(i))
|
||||||
|
// }
|
||||||
|
// override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||||
|
// input = inp and output = outp
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
||||||
@@ -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)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user