Skip to content

Commit

Permalink
Merge pull request #18426 from egregius313/egregius313/go/mad/databas…
Browse files Browse the repository at this point in the history
…e/sqlx

Go: Add `database` source models for the `jmoiron/sqlx` package
  • Loading branch information
egregius313 authored Jan 8, 2025
2 parents 5cc34a1 + 8e4939e commit af15eba
Show file tree
Hide file tree
Showing 13 changed files with 729 additions and 1 deletion.
4 changes: 4 additions & 0 deletions go/ql/lib/change-notes/2025-01-07-sqlx-source-models.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* `database` local source models have been added for the `github.com/jmoiron/sqlx` package.
68 changes: 68 additions & 0 deletions go/ql/lib/ext/github.conef.uk.jmoiron.sqlx.model.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,57 @@
extensions:
- addsTo:
pack: codeql/go-all
extensible: sourceModel
data:
- ["github.com/jmoiron/sqlx", "", True, "Get", "", "", "Argument[1]", "database", "manual"]
- ["github.com/jmoiron/sqlx", "", True, "GetContext", "", "", "Argument[2]", "database", "manual"]
- ["github.com/jmoiron/sqlx", "", True, "NamedQuery", "", "", "ReturnValue[0]", "database", "manual"]
- ["github.com/jmoiron/sqlx", "", True, "NamedQueryContext", "", "", "ReturnValue[0]", "database", "manual"]
- ["github.com/jmoiron/sqlx", "", True, "Select", "", "", "Argument[1]", "database", "manual"]
- ["github.com/jmoiron/sqlx", "", True, "SelectContext", "", "", "Argument[2]", "database", "manual"]
- ["github.com/jmoiron/sqlx", "Conn", True, "GetContext", "", "", "Argument[1]", "database", "manual"]
- ["github.com/jmoiron/sqlx", "Conn", True, "QueryRowxContext", "", "", "ReturnValue", "database", "manual"]
- ["github.com/jmoiron/sqlx", "Conn", True, "QueryxContext", "", "", "ReturnValue[0]", "database", "manual"]
- ["github.com/jmoiron/sqlx", "Conn", True, "SelectContext", "", "", "Argument[1]", "database", "manual"]
- ["github.com/jmoiron/sqlx", "DB", True, "Get", "", "", "Argument[0]", "database", "manual"]
- ["github.com/jmoiron/sqlx", "DB", True, "GetContext", "", "", "Argument[1]", "database", "manual"]
- ["github.com/jmoiron/sqlx", "DB", True, "NamedQuery", "", "", "ReturnValue[0]", "database", "manual"]
- ["github.com/jmoiron/sqlx", "DB", True, "NamedQueryContext", "", "", "ReturnValue[0]", "database", "manual"]
- ["github.com/jmoiron/sqlx", "DB", True, "QueryRowx", "", "", "ReturnValue[0]", "database", "manual"]
- ["github.com/jmoiron/sqlx", "DB", True, "QueryRowxContext", "", "", "ReturnValue[0]", "database", "manual"]
- ["github.com/jmoiron/sqlx", "DB", True, "Queryx", "", "", "ReturnValue[0]", "database", "manual"]
- ["github.com/jmoiron/sqlx", "DB", True, "QueryxContext", "", "", "ReturnValue[0]", "database", "manual"]
- ["github.com/jmoiron/sqlx", "DB", True, "Select", "", "", "Argument[0]", "database", "manual"]
- ["github.com/jmoiron/sqlx", "DB", True, "SelectContext", "", "", "Argument[1]", "database", "manual"]
- ["github.com/jmoiron/sqlx", "NamedStmt", True, "Get", "", "", "Argument[0]", "database", "manual"]
- ["github.com/jmoiron/sqlx", "NamedStmt", True, "GetContext", "", "", "Argument[1]", "database", "manual"]
- ["github.com/jmoiron/sqlx", "NamedStmt", True, "QueryRow", "", "", "ReturnValue[0]", "database", "manual"]
- ["github.com/jmoiron/sqlx", "NamedStmt", True, "QueryRowContext", "", "", "ReturnValue[0]", "database", "manual"]
- ["github.com/jmoiron/sqlx", "NamedStmt", True, "Query", "", "", "ReturnValue[0]", "database", "manual"]
- ["github.com/jmoiron/sqlx", "NamedStmt", True, "QueryContext", "", "", "ReturnValue[0]", "database", "manual"]
- ["github.com/jmoiron/sqlx", "NamedStmt", True, "QueryRowx", "", "", "ReturnValue[0]", "database", "manual"]
- ["github.com/jmoiron/sqlx", "NamedStmt", True, "QueryRowxContext", "", "", "ReturnValue[0]", "database", "manual"]
- ["github.com/jmoiron/sqlx", "NamedStmt", True, "Queryx", "", "", "ReturnValue[0]", "database", "manual"]
- ["github.com/jmoiron/sqlx", "NamedStmt", True, "QueryxContext", "", "", "ReturnValue[0]", "database", "manual"]
- ["github.com/jmoiron/sqlx", "NamedStmt", True, "Select", "", "", "Argument[0]", "database", "manual"]
- ["github.com/jmoiron/sqlx", "NamedStmt", True, "SelectContext", "", "", "Argument[1]", "database", "manual"]
- ["github.com/jmoiron/sqlx", "Stmt", True, "Get", "", "", "Argument[0]", "database", "manual"]
- ["github.com/jmoiron/sqlx", "Stmt", True, "GetContext", "", "", "Argument[1]", "database", "manual"]
- ["github.com/jmoiron/sqlx", "Stmt", True, "QueryRowx", "", "", "ReturnValue[0]", "database", "manual"]
- ["github.com/jmoiron/sqlx", "Stmt", True, "QueryRowxContext", "", "", "ReturnValue[0]", "database", "manual"]
- ["github.com/jmoiron/sqlx", "Stmt", True, "Queryx", "", "", "ReturnValue[0]", "database", "manual"]
- ["github.com/jmoiron/sqlx", "Stmt", True, "QueryxContext", "", "", "ReturnValue[0]", "database", "manual"]
- ["github.com/jmoiron/sqlx", "Stmt", True, "Select", "", "", "Argument[0]", "database", "manual"]
- ["github.com/jmoiron/sqlx", "Stmt", True, "SelectContext", "", "", "Argument[1]", "database", "manual"]
- ["github.com/jmoiron/sqlx", "Tx", True, "Get", "", "", "Argument[0]", "database", "manual"]
- ["github.com/jmoiron/sqlx", "Tx", True, "GetContext", "", "", "Argument[1]", "database", "manual"]
- ["github.com/jmoiron/sqlx", "Tx", True, "NamedQuery", "", "", "ReturnValue[0]", "database", "manual"]
- ["github.com/jmoiron/sqlx", "Tx", True, "QueryRowx", "", "", "ReturnValue[0]", "database", "manual"]
- ["github.com/jmoiron/sqlx", "Tx", True, "QueryRowxContext", "", "", "ReturnValue[0]", "database", "manual"]
- ["github.com/jmoiron/sqlx", "Tx", True, "Queryx", "", "", "ReturnValue[0]", "database", "manual"]
- ["github.com/jmoiron/sqlx", "Tx", True, "QueryxContext", "", "", "ReturnValue[0]", "database", "manual"]
- ["github.com/jmoiron/sqlx", "Tx", True, "Select", "", "", "Argument[0]", "database", "manual"]
- ["github.com/jmoiron/sqlx", "Tx", True, "SelectContext", "", "", "Argument[1]", "database", "manual"]
- addsTo:
pack: codeql/go-all
extensible: sinkModel
Expand All @@ -15,3 +68,18 @@ extensions:
- ["github.com/jmoiron/sqlx", "Tx", True, "NamedQuery", "", "", "Argument[0]", "sql-injection", "manual"]
- ["github.com/jmoiron/sqlx", "Tx", True, "Queryx", "", "", "Argument[0]", "sql-injection", "manual"]
- ["github.com/jmoiron/sqlx", "Tx", True, "Select", "", "", "Argument[1]", "sql-injection", "manual"]
- addsTo:
pack: codeql/go-all
extensible: summaryModel
data:
- ["github.com/jmoiron/sqlx", "", True, "MapScan", "", "", "Argument[0]", "Argument[1]", "taint", "manual"]
- ["github.com/jmoiron/sqlx", "", True, "SliceScan", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"]
- ["github.com/jmoiron/sqlx", "", True, "StructScan", "", "", "Argument[0]", "Argument[1]", "taint", "manual"]
- ["github.com/jmoiron/sqlx", "ColScanner", True, "Scan", "", "", "Argument[receiver]", "Argument[0]", "taint", "manual"]
- ["github.com/jmoiron/sqlx", "Row", True, "MapScan", "", "", "Argument[receiver]", "Argument[0]", "taint", "manual"]
- ["github.com/jmoiron/sqlx", "Row", True, "Scan", "", "", "Argument[receiver]", "Argument[0]", "taint", "manual"]
- ["github.com/jmoiron/sqlx", "Row", True, "SliceScan", "", "", "Argument[receiver]", "ReturnValue[0]", "taint", "manual"]
- ["github.com/jmoiron/sqlx", "Row", True, "StructScan", "", "", "Argument[receiver]", "Argument[0]", "taint", "manual"]
- ["github.com/jmoiron/sqlx", "Rows", True, "MapScan", "", "", "Argument[receiver]", "Argument[0]", "taint", "manual"]
- ["github.com/jmoiron/sqlx", "Rows", True, "SliceScan", "", "", "Argument[receiver]", "ReturnValue[0]", "taint", "manual"]
- ["github.com/jmoiron/sqlx", "Rows", True, "StructScan", "", "", "Argument[receiver]", "Argument[0]", "taint", "manual"]
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ go 1.22.5

require (
gorm.io/gorm v1.23.0
github.com/jmoiron/sqlx v1.4.0
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,311 @@
package test

import (
"context"

"github.com/jmoiron/sqlx"
)

func test_sqlx(q sqlx.Ext) {
var user User

err := sqlx.Get(q, &user, "SELECT * FROM users WHERE id = 1") // $ source
ignore(err)

err = sqlx.Select(q, &user, "SELECT * FROM users WHERE id = 1") // $ source
ignore(err)

rows, err := sqlx.NamedQuery(q, "SELECT * FROM users WHERE id = :id", map[string]any{"id": 1}) // $ source
ignore(err)

var user2 User

rows.StructScan(&user2)

sink(user2) // $ hasTaintFlow="user2"
}

func test_sqlx_ctx(ctx context.Context, q sqlx.ExtContext) {
var user User

err := sqlx.GetContext(ctx, q, &user, "SELECT * FROM users WHERE id = 1") // $ source
ignore(err)

err = sqlx.SelectContext(ctx, q, &user, "SELECT * FROM users WHERE id = 1") // $ source
ignore(err)

rows, err := sqlx.NamedQueryContext(ctx, q, "SELECT * FROM users WHERE id = :id", map[string]any{"id": 1}) // $ source
ignore(err)

var user2 User

rows.StructScan(&user2)

sink(user2) // $ hasTaintFlow="user2"
}

func test_sqlx_Conn(conn *sqlx.Conn) {
var user User
conn.GetContext(nil, &user, "SELECT * FROM users WHERE id = 1") // $ source

var user2 User
conn.SelectContext(nil, &user2, "SELECT * FROM users WHERE id = 1") // $ source

row := conn.QueryRowxContext(nil, "SELECT * FROM users WHERE id = 1") // $ source

userMap := make(map[string]interface{})
row.MapScan(userMap)
id := userMap["id"].(int)
sink(id) // $ hasTaintFlow="id"

rows, err := conn.QueryxContext(nil, "SELECT * FROM users WHERE id = 1") // $ source
ignore(err)

for rows.Next() {
var id int
var name string
err = rows.Scan(&id, &name)

if err != nil {
return
}

sink(id, name) // $ hasTaintFlow="id" hasTaintFlow="name"
}
}

func test_sqlx_DB(db *sqlx.DB) {
example, err := db.Query("SELECT * FROM users") // $ source
ignore(example, err)

rows, err := db.Queryx("SELECT * FROM users") // $ source

if err != nil {
return
}

defer rows.Close()

for rows.Next() {
var id int
var name string
err = rows.Scan(&id, &name)

if err != nil {
return
}

sink(id, name) // $ hasTaintFlow="id" hasTaintFlow="name"

valmap := make(map[string]interface{})
rows.MapScan(valmap)

id = valmap["id"].(int)
sink(id) // $ hasTaintFlow="id"

var user User
rows.StructScan(&user)
sink(user) // $ hasTaintFlow="user"
}

row := db.QueryRowx("SELECT * FROM users WHERE id = 1") // $ source

userMap := make(map[string]interface{})
row.MapScan(userMap)

id := userMap["id"].(int)
sink(id) // $ hasTaintFlow="id"

var user User
row.StructScan(&user)
sink(user) // $ hasTaintFlow="user"

var user2 User
db.Get(&user2, "SELECT * FROM users WHERE id = 1") // $ source

var user3 User
db.GetContext(nil, &user3, "SELECT * FROM users WHERE id = 1") // $ source

var user4 User
rows, err = db.NamedQueryContext(nil, "SELECT * FROM users WHERE id = :id", map[string]any{"id": 1}) // $ source
ignore(err)
rows.StructScan(&user4)
sink(user4) // $ hasTaintFlow="user4"

var user5 User
db.Select(&user5, "SELECT * FROM users WHERE id = 1") // $ source
}

func test_sqlx_NamedStmt(stmt *sqlx.NamedStmt) {
example, err := stmt.Query("SELECT * FROM users") // $ source
ignore(example, err)

rows, err := stmt.Queryx("SELECT * FROM users") // $ source

if err != nil {
return
}

defer rows.Close()

for rows.Next() {
var id int
var name string
err = rows.Scan(&id, &name)

if err != nil {
return
}

sink(id, name) // $ hasTaintFlow="id" hasTaintFlow="name"

valmap := make(map[string]interface{})
rows.MapScan(valmap)

id = valmap["id"].(int)
sink(id) // $ hasTaintFlow="id"

var user User
rows.StructScan(&user)
sink(user) // $ hasTaintFlow="user"
}

row := stmt.QueryRowx("SELECT * FROM users WHERE id = 1") // $ source

userMap := make(map[string]interface{})
row.MapScan(userMap)

id := userMap["id"].(int)
sink(id) // $ hasTaintFlow="id"

var user User
row.StructScan(&user)
sink(user) // $ hasTaintFlow="user"

var user2 User
stmt.Get(&user2, "SELECT * FROM users WHERE id = 1") // $ source

var user3 User
stmt.GetContext(nil, &user3, "SELECT * FROM users WHERE id = 1") // $ source

var user4 User
stmt.Select(&user4, "SELECT * FROM users WHERE id = 1") // $ source
}

func test_sqlx_Stmt(stmt *sqlx.Stmt) {
example, err := stmt.Query("SELECT * FROM users") // $ source
ignore(example, err)

rows, err := stmt.Queryx("SELECT * FROM users") // $ source

if err != nil {
return
}

defer rows.Close()

for rows.Next() {
var id int
var name string
err = rows.Scan(&id, &name)

if err != nil {
return
}

sink(id, name) // $ hasTaintFlow="id" hasTaintFlow="name"

valmap := make(map[string]interface{})
rows.MapScan(valmap)

id = valmap["id"].(int)
sink(id) // $ hasTaintFlow="id"

var user User
rows.StructScan(&user)
sink(user) // $ hasTaintFlow="user"
}

row := stmt.QueryRowx("SELECT * FROM users WHERE id = 1") // $ source

userMap := make(map[string]interface{})
row.MapScan(userMap)

id := userMap["id"].(int)
sink(id) // $ hasTaintFlow="id"

var user User
row.StructScan(&user)
sink(user) // $ hasTaintFlow="user"

var user2 User
stmt.Get(&user2, "SELECT * FROM users WHERE id = 1") // $ source

var user3 User
stmt.GetContext(nil, &user3, "SELECT * FROM users WHERE id = 1") // $ source

var user4 User
stmt.Select(&user4, "SELECT * FROM users WHERE id = 1") // $ source
}

func test_sqlx_Tx(tx *sqlx.Tx) {
example, err := tx.Query("SELECT * FROM users") // $ source
ignore(example, err)

rows, err := tx.Queryx("SELECT * FROM users") // $ source

if err != nil {
return
}

defer rows.Close()

for rows.Next() {
var id int
var name string
err = rows.Scan(&id, &name)

if err != nil {
return
}

sink(id, name) // $ hasTaintFlow="id" hasTaintFlow="name"

valmap := make(map[string]interface{})
rows.MapScan(valmap)

id = valmap["id"].(int)
sink(id) // $ hasTaintFlow="id"

var user User
rows.StructScan(&user)
sink(user) // $ hasTaintFlow="user"
}

row := tx.QueryRowx("SELECT * FROM users WHERE id = 1") // $ source

userMap := make(map[string]interface{})
row.MapScan(userMap)

id := userMap["id"].(int)
sink(id) // $ hasTaintFlow="id"

var user User
row.StructScan(&user)
sink(user) // $ hasTaintFlow="user"

var user2 User
tx.Get(&user2, "SELECT * FROM users WHERE id = 1") // $ source

var user3 User
tx.GetContext(nil, &user3, "SELECT * FROM users WHERE id = 1") // $ source

var user4 User
rows, err = tx.NamedQuery("SELECT * FROM users WHERE id = :id", map[string]any{"id": 1}) // $ source
ignore(err)
rows.StructScan(&user4)
sink(user4) // $ hasTaintFlow="user4"

var user5 User
tx.Select(&user5, "SELECT * FROM users WHERE id = 1") // $ source
}
Loading

0 comments on commit af15eba

Please sign in to comment.