Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* Added `database` source models for the `github.com/rqlite/gorqlite` package.
19 changes: 19 additions & 0 deletions go/ql/lib/ext/github.com.rqlite.gorqlite.model.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,21 @@ extensions:
pack: codeql/go-all
extensible: packageGrouping
data:
- ["gorqlite", "github.com/kanikanema/gorqlite"]
- ["gorqlite", "github.com/rqlite/gorqlite"]
- ["gorqlite", "github.com/raindog308/gorqlite"]
- addsTo:
pack: codeql/go-all
extensible: sourceModel
data:
- ["group:gorqlite", "Connection", True, "Query", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:gorqlite", "Connection", True, "QueryContext", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:gorqlite", "Connection", True, "QueryOne", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:gorqlite", "Connection", True, "QueryOneContext", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:gorqlite", "Connection", True, "QueryOneParameterized", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:gorqlite", "Connection", True, "QueryOneParameterizedContext", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:gorqlite", "Connection", True, "QueryParameterized", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:gorqlite", "Connection", True, "QueryParameterizedContext", "", "", "ReturnValue[0]", "database", "manual"]
- addsTo:
pack: codeql/go-all
extensible: sinkModel
Expand Down Expand Up @@ -33,3 +46,9 @@ extensions:
- ["group:gorqlite", "Connection", True, "WriteOneParameterizedContext", "", "", "Argument[1]", "sql-injection", "manual"]
- ["group:gorqlite", "Connection", True, "WriteParameterized", "", "", "Argument[0]", "sql-injection", "manual"]
- ["group:gorqlite", "Connection", True, "WriteParameterizedContext", "", "", "Argument[1]", "sql-injection", "manual"]
- addsTo:
pack: codeql/go-all
extensible: summaryModel
data:
- ["group:gorqlite", "QueryResult", True, "Map", "", "", "Argument[receiver]", "ReturnValue[0]", "taint", "manual"]
- ["group:gorqlite", "QueryResult", True, "Slice", "", "", "Argument[receiver]", "ReturnValue[0]", "taint", "manual"]
35 changes: 35 additions & 0 deletions go/ql/lib/semmle/go/frameworks/Gorqlite.qll
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/**
* Provides classes modeling security-relevant aspects of the `gorqlite` package.
*/

import go

/**
* Provides classes modeling security-relevant aspects of the `gorqlite` package.
*/
module Gorqlite {
private string packagePath() {
result =
package([
"github.com/rqlite/gorqlite", "github.com/raindog308/gorqlite",
"github.com/kanikanema/gorqlite"
], "")
}

// These are expressed using TaintTracking::FunctionModel because varargs functions don't work with Models-as-Data summaries yet.
private class QueryResultScan extends TaintTracking::FunctionModel, Method {
FunctionInput inp;
FunctionOutput outp;

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

override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input = inp and output = outp
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package test

//go:generate depstubber -vendor github.com/rqlite/gorqlite Connection,QueryResult

import (
"context"

"github.com/rqlite/gorqlite"
)

func parameterize(query string) gorqlite.ParameterizedStatement {
return gorqlite.ParameterizedStatement{
Query: query,
Arguments: []interface{}{},
}
}

func test_rqlite_gorqlite(conn *gorqlite.Connection, ctx context.Context, query []string) {
v1, err := conn.Query(query) // $ source
if err != nil {
return
}

sink(v1) // $ hasTaintFlow="v1"

v2, err := conn.QueryContext(ctx, query) // $ source
if err != nil {
return
}

sink(v2) // $ hasTaintFlow="v2"

v3, err := conn.QueryOne(query[0]) // $ source
if err != nil {
return
}

r3, err := v3.Slice()
if err != nil {
return
}

sink(r3) // $ hasTaintFlow="r3"

v4, err := conn.QueryOneContext(ctx, query[0]) // $ source
if err != nil {
return
}

var r41, r42, r43 string
v4.Scan(&r41, &r42, &r43)

v5, err := conn.QueryOneParameterized(parameterize(query[0])) // $ source
if err != nil {
return
}

r5, err := v5.Map()

r5Name := r5["name"]

sink(r5Name) // $ hasTaintFlow="r5Name"

v6, err := conn.QueryOneParameterizedContext(ctx, parameterize(query[0])) // $ source
if err != nil {
return
}

sink(v6) // $ hasTaintFlow="v6"

v7, err := conn.QueryParameterized([]gorqlite.ParameterizedStatement{parameterize(query[0])}) // $ source
if err != nil {
return
}

sink(v7) // $ hasTaintFlow="v7"

v8, err := conn.QueryParameterizedContext(ctx, []gorqlite.ParameterizedStatement{parameterize(query[0])}) // $ source
if err != nil {
return
}

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

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.