Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions go/ql/lib/change-notes/2025-03-02-squirrel-source-models.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
category: minorAnalysis
---
* Added `database` source models for the `github.com/Masterminds/squirrel` ORM package.

Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,37 @@ extensions:
- ["squirrel", "github.com/Masterminds/squirrel"]
- ["squirrel", "gopkg.in/Masterminds/squirrel"]
- ["squirrel", "github.com/lann/squirrel"]
- addsTo:
pack: codeql/go-all
extensible: sourceModel
data:
- ["group:squirrel", "", True, "QueryContextWith", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "", True, "QueryRowContextWith", "", "", "ReturnValue", "database", "manual"]
- ["group:squirrel", "", True, "QueryRowWith", "", "", "ReturnValue", "database", "manual"]
- ["group:squirrel", "", True, "QueryWith", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "DeleteBuilder", True, "Query", "", "", "ReturnValue[0]", "database", "manual"]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding a comment to the yml models pointing out there are also QL models and vice versa

- ["group:squirrel", "DeleteBuilder", True, "QueryContext", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "DeleteBuilder", True, "QueryRowContext", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "InsertBuilder", True, "Query", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "InsertBuilder", True, "QueryContext", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "InsertBuilder", True, "QueryRow", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "InsertBuilder", True, "QueryRowContext", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "QueryRower", True, "QueryRow", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "QueryRowerContext", True, "QueryRowContext", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "Queryer", True, "Query", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "QueryerContext", True, "QueryContext", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "SelectBuilder", True, "Query", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "SelectBuilder", True, "QueryContext", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "SelectBuilder", True, "QueryRow", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "SelectBuilder", True, "QueryRowContext", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "StdSql", True, "Query", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "StdSql", True, "QueryRow", "", "", "ReturnValue", "database", "manual"]
- ["group:squirrel", "StdSqlCtx", True, "QueryContext", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "StdSqlCtx", True, "QueryRowContext", "", "", "ReturnValue", "database", "manual"]
- ["group:squirrel", "UpdateBuilder", True, "Query", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "UpdateBuilder", True, "QueryContext", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "UpdateBuilder", True, "QueryRow", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:squirrel", "UpdateBuilder", True, "QueryRowContext", "", "", "ReturnValue[0]", "database", "manual"]
- addsTo:
pack: codeql/go-all
extensible: sinkModel
Expand Down
1 change: 1 addition & 0 deletions go/ql/lib/go.qll
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ import semmle.go.frameworks.Protobuf
import semmle.go.frameworks.Revel
import semmle.go.frameworks.Spew
import semmle.go.frameworks.SQL
import semmle.go.frameworks.Squirrel
import semmle.go.frameworks.Stdlib
import semmle.go.frameworks.SystemCommandExecutors
import semmle.go.frameworks.Testing
Expand Down
85 changes: 85 additions & 0 deletions go/ql/lib/semmle/go/frameworks/Squirrel.qll
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/**
* Provides classes modeling security-relevant aspects of the `squirrel` ORM package.
*/

import go

/**
* Provides classes modeling security-relevant aspects of the `squirrel` ORM package.
*/
module Squirrel {
private string packagePath() {
result =
package([
"github.com/Masterminds/squirrel",
"github.com/lann/squirrel",
"gopkg.in/Masterminds/squirrel",
], "")
}

private class RowScan extends TaintTracking::FunctionModel, Method {
FunctionInput inp;
FunctionOutput outp;

RowScan() {
// signature: func (r *Row) Scan(dest ...interface{}) error
this.hasQualifiedName(packagePath(), "Row", "Scan") and
inp.isReceiver() and
outp.isParameter(_)
}

override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input = inp and output = outp
}
}

private class RowScannerScan extends TaintTracking::FunctionModel, Method {
FunctionInput inp;
FunctionOutput outp;

RowScannerScan() {
// signature: func (rs *RowScanner) Scan(dest ...interface{}) error
this.hasQualifiedName(packagePath(), "RowScanner", "Scan") and
inp.isReceiver() and
outp.isParameter(_)
}

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 InsertBuilder) Scan(dest ...interface{}) error
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// signature: func (b InsertBuilder) Scan(dest ...interface{}) error
// 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 InsertBuilder) ScanContext(ctx context.Context, dest ...interface{}) error
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// signature: func (b InsertBuilder) ScanContext(ctx context.Context, dest ...interface{}) error
// 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
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ require (
github.com/couchbase/gocb v1.6.7
github.com/couchbase/gocb/v2 v2.9.4
github.com/jmoiron/sqlx v1.4.0
github.com/Masterminds/squirrel v1.5.4
github.com/rqlite/gorqlite v0.0.0-20250128004930-114c7828b55a
go.mongodb.org/mongo-driver v1.17.3
gorm.io/gorm v1.25.12
github.com/nonexistent/sources v0.0.0-20250300000000-000000000000
)

require (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,9 @@ extensions:
pack: codeql/threat-models
extensible: threatModelConfiguration
data:
- ["database", true, 0]
- ["database", true, 0]
- addsTo:
pack: codeql/go-all
extensible: sourceModel
data:
- ["github.com/nonexistent/sources", "", False, "Source", "", "", "ReturnValue", "database", "manual"]
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,9 @@ extensions:
extensible: threatModelConfiguration
data:
- ["database", true, 0]

- addsTo:
pack: codeql/go-all
extensible: sourceModel
data:
- ["github.com/nonexistent/sources", "", False, "Source", "", "", "ReturnValue", "database", "manual"]
Loading