mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
Add Bun models and tests
This commit is contained in:
@@ -3,24 +3,19 @@ extensions:
|
||||
pack: codeql/go-all
|
||||
extensible: sourceModel
|
||||
data:
|
||||
- ["github.com/uptrace/bun", "AddColumnQuery", True, "Model", "", "", "Argument[0]", "database", "manual"]
|
||||
- ["github.com/uptrace/bun", "CreateIndexQuery", True, "Model", "", "", "Argument[0]", "database", "manual"]
|
||||
- ["github.com/uptrace/bun", "CreateTableQuery", True, "Model", "", "", "Argument[0]", "database", "manual"]
|
||||
- ["github.com/uptrace/bun", "DeleteQuery", True, "Model", "", "", "Argument[0]", "database", "manual"]
|
||||
- ["github.com/uptrace/bun", "DropIndexQuery", True, "Model", "", "", "Argument[0]", "database", "manual"]
|
||||
- ["github.com/uptrace/bun", "DropTableQuery", True, "Model", "", "", "Argument[0]", "database", "manual"]
|
||||
- ["github.com/uptrace/bun", "InsertQuery", True, "Model", "", "", "Argument[0]", "database", "manual"]
|
||||
- ["github.com/uptrace/bun", "MergeQuery", True, "Model", "", "", "Argument[0]", "database", "manual"]
|
||||
- ["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", "TruncateQuery", True, "Model", "", "", "Argument[0]", "database", "manual"]
|
||||
- ["github.com/uptrace/bun", "UpdateQuery", True, "Model", "", "", "Argument[0]", "database", "manual"]
|
||||
- ["github.com/uptrace/bun", "DeleteQuery", True, "Scan", "", "", "Argument[0]", "database", "manual"]
|
||||
- ["github.com/uptrace/bun", "InsertQuery", True, "Scan", "", "", "Argument[0]", "database", "manual"]
|
||||
- ["github.com/uptrace/bun", "MergeQuery", True, "Scan", "", "", "Argument[0]", "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"]
|
||||
- ["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
|
||||
@@ -88,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
|
||||
|
||||
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