mirror of
https://github.com/github/codeql.git
synced 2026-04-18 05:24:01 +02:00
Upgrade and convert gorqlite sql-injection sinks to MaD
This commit is contained in:
35
go/ql/lib/ext/github.com.rqlite.gorqlite.model.yml
Normal file
35
go/ql/lib/ext/github.com.rqlite.gorqlite.model.yml
Normal file
@@ -0,0 +1,35 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: packageGrouping
|
||||
data:
|
||||
- ["gorqlite", "github.com/rqlite/gorqlite"]
|
||||
- ["gorqlite", "github.com/raindog308/gorqlite"]
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: sinkModel
|
||||
data:
|
||||
- ["group:gorqlite", "Connection", True, "Query", "", "", "Argument[0]", "sql-injection", "manual"]
|
||||
- ["group:gorqlite", "Connection", True, "QueryContext", "", "", "Argument[1]", "sql-injection", "manual"]
|
||||
- ["group:gorqlite", "Connection", True, "QueryOne", "", "", "Argument[0]", "sql-injection", "manual"]
|
||||
- ["group:gorqlite", "Connection", True, "QueryOneContext", "", "", "Argument[1]", "sql-injection", "manual"]
|
||||
- ["group:gorqlite", "Connection", True, "QueryOneParameterized", "", "", "Argument[0]", "sql-injection", "manual"]
|
||||
- ["group:gorqlite", "Connection", True, "QueryOneParameterizedContext", "", "", "Argument[1]", "sql-injection", "manual"]
|
||||
- ["group:gorqlite", "Connection", True, "QueryParameterized", "", "", "Argument[0]", "sql-injection", "manual"]
|
||||
- ["group:gorqlite", "Connection", True, "QueryParameterizedContext", "", "", "Argument[1]", "sql-injection", "manual"]
|
||||
- ["group:gorqlite", "Connection", True, "Queue", "", "", "Argument[0]", "sql-injection", "manual"]
|
||||
- ["group:gorqlite", "Connection", True, "QueueContext", "", "", "Argument[1]", "sql-injection", "manual"]
|
||||
- ["group:gorqlite", "Connection", True, "QueueOne", "", "", "Argument[0]", "sql-injection", "manual"]
|
||||
- ["group:gorqlite", "Connection", True, "QueueOneContext", "", "", "Argument[1]", "sql-injection", "manual"]
|
||||
- ["group:gorqlite", "Connection", True, "QueueOneParameterized", "", "", "Argument[0]", "sql-injection", "manual"]
|
||||
- ["group:gorqlite", "Connection", True, "QueueOneParameterizedContext", "", "", "Argument[1]", "sql-injection", "manual"]
|
||||
- ["group:gorqlite", "Connection", True, "QueueParameterized", "", "", "Argument[0]", "sql-injection", "manual"]
|
||||
- ["group:gorqlite", "Connection", True, "QueueParameterizedContext", "", "", "Argument[1]", "sql-injection", "manual"]
|
||||
- ["group:gorqlite", "Connection", True, "Write", "", "", "Argument[0]", "sql-injection", "manual"]
|
||||
- ["group:gorqlite", "Connection", True, "WriteContext", "", "", "Argument[1]", "sql-injection", "manual"]
|
||||
- ["group:gorqlite", "Connection", True, "WriteOne", "", "", "Argument[0]", "sql-injection", "manual"]
|
||||
- ["group:gorqlite", "Connection", True, "WriteOneContext", "", "", "Argument[1]", "sql-injection", "manual"]
|
||||
- ["group:gorqlite", "Connection", True, "WriteOneParameterized", "", "", "Argument[0]", "sql-injection", "manual"]
|
||||
- ["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"]
|
||||
@@ -85,11 +85,6 @@ module SQL {
|
||||
/** A string that might identify package `go-pg/pg/orm` or a specific version of it. */
|
||||
private string gopgorm() { result = package("github.com/go-pg/pg", "orm") }
|
||||
|
||||
/** A string that might identify package `github.com/rqlite/gorqlite` or `github.com/raindog308/gorqlite` or a specific version of it. */
|
||||
private string gorqlite() {
|
||||
result = package(["github.com/rqlite/gorqlite", "github.com/raindog308/gorqlite"], "")
|
||||
}
|
||||
|
||||
/** A string that might identify package `github.com/gogf/gf/database/gdb` or a specific version of it. */
|
||||
private string gogf() { result = package("github.com/gogf/gf", "database/gdb") }
|
||||
|
||||
@@ -158,25 +153,6 @@ module SQL {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A string argument to an API of `github.com/rqlite/gorqlite`, or a specific version of it, that is directly interpreted as SQL without
|
||||
* taking syntactic structure into account.
|
||||
*/
|
||||
private class GorqliteQueryString extends Range {
|
||||
GorqliteQueryString() {
|
||||
// func (conn *Connection) Query(sqlStatements []string) (results []QueryResult, err error)
|
||||
// func (conn *Connection) QueryOne(sqlStatement string) (qr QueryResult, err error)
|
||||
// func (conn *Connection) Queue(sqlStatements []string) (seq int64, err error)
|
||||
// func (conn *Connection) QueueOne(sqlStatement string) (seq int64, err error)
|
||||
// func (conn *Connection) Write(sqlStatements []string) (results []WriteResult, err error)
|
||||
// func (conn *Connection) WriteOne(sqlStatement string) (wr WriteResult, err error)
|
||||
exists(Method m, string name | m.hasQualifiedName(gorqlite(), "Connection", name) |
|
||||
name = ["Query", "QueryOne", "Queue", "QueueOne", "Write", "WriteOne"] and
|
||||
this = m.getACall().getArgument(0)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A string argument to an API of `github.com/gogf/gf/database/gdb`, or a specific version of it, that is directly interpreted as SQL without
|
||||
* taking syntactic structure into account.
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
testFailures
|
||||
invalidModelRow
|
||||
failures
|
||||
@@ -0,0 +1,60 @@
|
||||
import go
|
||||
import semmle.go.dataflow.ExternalFlow
|
||||
import ModelValidation
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
|
||||
module SqlTest implements TestSig {
|
||||
string getARelevantTag() { result = "query" }
|
||||
|
||||
predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
tag = "query" and
|
||||
exists(SQL::Query q, SQL::QueryString qs | qs = q.getAQueryString() |
|
||||
q.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(),
|
||||
location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and
|
||||
element = q.toString() and
|
||||
value = qs.toString()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
module QueryString implements TestSig {
|
||||
string getARelevantTag() { result = "querystring" }
|
||||
|
||||
predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
tag = "querystring" and
|
||||
element = "" and
|
||||
exists(SQL::QueryString qs | not exists(SQL::Query q | qs = q.getAQueryString()) |
|
||||
qs.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(),
|
||||
location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and
|
||||
value = qs.toString()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
module Config implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node n) { n.asExpr() instanceof StringLit }
|
||||
|
||||
predicate isSink(DataFlow::Node n) {
|
||||
n = any(DataFlow::CallNode cn | cn.getTarget().getName() = "sink").getAnArgument()
|
||||
}
|
||||
}
|
||||
|
||||
module Flow = TaintTracking::Global<Config>;
|
||||
|
||||
module TaintFlow implements TestSig {
|
||||
string getARelevantTag() { result = "flowfrom" }
|
||||
|
||||
predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
tag = "flowfrom" and
|
||||
element = "" and
|
||||
exists(DataFlow::Node fromNode, DataFlow::Node toNode |
|
||||
toNode
|
||||
.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(),
|
||||
location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and
|
||||
Flow::flow(fromNode, toNode) and
|
||||
value = fromNode.asExpr().(StringLit).getValue()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
import MakeTest<MergeTests3<SqlTest, QueryString, TaintFlow>>
|
||||
@@ -2,4 +2,4 @@ module main
|
||||
|
||||
go 1.18
|
||||
|
||||
require github.com/rqlite/gorqlite v0.0.0-20220528150909-c4e99ae96be6
|
||||
require github.com/rqlite/gorqlite v0.0.0-20240808172217-12ae7d03ef19
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
| gorqlite.go:11:13:11:16 | sqls |
|
||||
| gorqlite.go:12:13:12:16 | sqls |
|
||||
| gorqlite.go:13:13:13:16 | sqls |
|
||||
| gorqlite.go:14:16:14:18 | sql |
|
||||
| gorqlite.go:15:16:15:18 | sql |
|
||||
| gorqlite.go:16:16:16:18 | sql |
|
||||
@@ -1,20 +1,49 @@
|
||||
package main
|
||||
|
||||
//go:generate depstubber -vendor github.com/rqlite/gorqlite Connection Open
|
||||
//go:generate depstubber -vendor github.com/rqlite/gorqlite Connection,ParameterizedStatement Open
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/rqlite/gorqlite"
|
||||
)
|
||||
|
||||
func gorqlitetest(sql string, sqls []string) {
|
||||
func gorqlitetest(sql string, sqls []string, param_sql gorqlite.ParameterizedStatement, param_sqls []gorqlite.ParameterizedStatement, ctx context.Context) {
|
||||
conn, _ := gorqlite.Open("dbUrl")
|
||||
conn.Query(sqls) // $ querystring=sqls
|
||||
conn.Queue(sqls) // $ querystring=sqls
|
||||
conn.Write(sqls) // $ querystring=sqls
|
||||
|
||||
conn.Query(sqls) // $ querystring=sqls
|
||||
conn.Queue(sqls) // $ querystring=sqls
|
||||
conn.Write(sqls) // $ querystring=sqls
|
||||
|
||||
conn.QueryOne(sql) // $ querystring=sql
|
||||
conn.QueueOne(sql) // $ querystring=sql
|
||||
conn.WriteOne(sql) // $ querystring=sql
|
||||
|
||||
conn.QueryParameterized(param_sqls) // $ querystring=param_sqls
|
||||
conn.QueueParameterized(param_sqls) // $ querystring=param_sqls
|
||||
conn.WriteParameterized(param_sqls) // $ querystring=param_sqls
|
||||
|
||||
conn.QueryOneParameterized(param_sql) // $ querystring=param_sql
|
||||
conn.QueueOneParameterized(param_sql) // $ querystring=param_sql
|
||||
conn.WriteOneParameterized(param_sql) // $ querystring=param_sql
|
||||
|
||||
conn.QueryContext(ctx, sqls) // $ querystring=sqls
|
||||
conn.QueueContext(ctx, sqls) // $ querystring=sqls
|
||||
conn.WriteContext(ctx, sqls) // $ querystring=sqls
|
||||
|
||||
conn.QueryOneContext(ctx, sql) // $ querystring=sql
|
||||
conn.QueueOneContext(ctx, sql) // $ querystring=sql
|
||||
conn.WriteOneContext(ctx, sql) // $ querystring=sql
|
||||
|
||||
conn.QueryParameterizedContext(ctx, param_sqls) // $ querystring=param_sqls
|
||||
conn.QueueParameterizedContext(ctx, param_sqls) // $ querystring=param_sqls
|
||||
conn.WriteParameterizedContext(ctx, param_sqls) // $ querystring=param_sqls
|
||||
|
||||
conn.QueryOneParameterizedContext(ctx, param_sql) // $ querystring=param_sql
|
||||
conn.QueueOneParameterizedContext(ctx, param_sql) // $ querystring=param_sql
|
||||
conn.WriteOneParameterizedContext(ctx, param_sql) // $ querystring=param_sql
|
||||
}
|
||||
|
||||
func main() {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
import go
|
||||
|
||||
from SQL::QueryString qs
|
||||
select qs
|
||||
@@ -2,11 +2,15 @@
|
||||
// This is a simple stub for github.com/rqlite/gorqlite, strictly for use in testing.
|
||||
|
||||
// See the LICENSE file for information about the licensing of the original library.
|
||||
// Source: github.com/rqlite/gorqlite (exports: Connection; functions: Open)
|
||||
// Source: github.com/rqlite/gorqlite (exports: Connection,ParameterizedStatement; functions: Open)
|
||||
|
||||
// Package gorqlite is a stub of github.com/rqlite/gorqlite, generated by depstubber.
|
||||
package gorqlite
|
||||
|
||||
import (
|
||||
context "context"
|
||||
)
|
||||
|
||||
type Connection struct {
|
||||
ID string
|
||||
}
|
||||
@@ -29,19 +33,83 @@ func (_ *Connection) Query(_ []string) ([]QueryResult, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (_ *Connection) QueryContext(_ context.Context, _ []string) ([]QueryResult, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (_ *Connection) QueryOne(_ string) (QueryResult, error) {
|
||||
return QueryResult{}, nil
|
||||
}
|
||||
|
||||
func (_ *Connection) QueryOneContext(_ context.Context, _ string) (QueryResult, error) {
|
||||
return QueryResult{}, nil
|
||||
}
|
||||
|
||||
func (_ *Connection) QueryOneParameterized(_ ParameterizedStatement) (QueryResult, error) {
|
||||
return QueryResult{}, nil
|
||||
}
|
||||
|
||||
func (_ *Connection) QueryOneParameterizedContext(_ context.Context, _ ParameterizedStatement) (QueryResult, error) {
|
||||
return QueryResult{}, nil
|
||||
}
|
||||
|
||||
func (_ *Connection) QueryParameterized(_ []ParameterizedStatement) ([]QueryResult, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (_ *Connection) QueryParameterizedContext(_ context.Context, _ []ParameterizedStatement) ([]QueryResult, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (_ *Connection) Queue(_ []string) (int64, error) {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func (_ *Connection) QueueContext(_ context.Context, _ []string) (int64, error) {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func (_ *Connection) QueueOne(_ string) (int64, error) {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func (_ *Connection) SetConsistencyLevel(_ string) error {
|
||||
func (_ *Connection) QueueOneContext(_ context.Context, _ string) (int64, error) {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func (_ *Connection) QueueOneParameterized(_ ParameterizedStatement) (int64, error) {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func (_ *Connection) QueueOneParameterizedContext(_ context.Context, _ ParameterizedStatement) (int64, error) {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func (_ *Connection) QueueParameterized(_ []ParameterizedStatement) (int64, error) {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func (_ *Connection) QueueParameterizedContext(_ context.Context, _ []ParameterizedStatement) (int64, error) {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func (_ *Connection) Request(_ []string) ([]RequestResult, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (_ *Connection) RequestContext(_ context.Context, _ []string) ([]RequestResult, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (_ *Connection) RequestParameterized(_ []ParameterizedStatement) ([]RequestResult, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (_ *Connection) RequestParameterizedContext(_ context.Context, _ []ParameterizedStatement) ([]RequestResult, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (_ *Connection) SetConsistencyLevel(_ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -53,12 +121,41 @@ func (_ *Connection) Write(_ []string) ([]WriteResult, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (_ *Connection) WriteContext(_ context.Context, _ []string) ([]WriteResult, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (_ *Connection) WriteOne(_ string) (WriteResult, error) {
|
||||
return WriteResult{}, nil
|
||||
}
|
||||
|
||||
func Open(_ string) (Connection, error) {
|
||||
return Connection{}, nil
|
||||
func (_ *Connection) WriteOneContext(_ context.Context, _ string) (WriteResult, error) {
|
||||
return WriteResult{}, nil
|
||||
}
|
||||
|
||||
func (_ *Connection) WriteOneParameterized(_ ParameterizedStatement) (WriteResult, error) {
|
||||
return WriteResult{}, nil
|
||||
}
|
||||
|
||||
func (_ *Connection) WriteOneParameterizedContext(_ context.Context, _ ParameterizedStatement) (WriteResult, error) {
|
||||
return WriteResult{}, nil
|
||||
}
|
||||
|
||||
func (_ *Connection) WriteParameterized(_ []ParameterizedStatement) ([]WriteResult, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (_ *Connection) WriteParameterizedContext(_ context.Context, _ []ParameterizedStatement) ([]WriteResult, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func Open(_ string) (*Connection, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
type ParameterizedStatement struct {
|
||||
Query string
|
||||
Arguments []interface{}
|
||||
}
|
||||
|
||||
type QueryResult struct {
|
||||
@@ -90,10 +187,20 @@ func (_ *QueryResult) Scan(_ ...interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *QueryResult) Slice() ([]interface{}, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (_ *QueryResult) Types() []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
type RequestResult struct {
|
||||
Err error
|
||||
Query *QueryResult
|
||||
Write *WriteResult
|
||||
}
|
||||
|
||||
type WriteResult struct {
|
||||
Err error
|
||||
Timing float64
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
# github.com/rqlite/gorqlite v0.0.0-20220528150909-c4e99ae96be6
|
||||
# github.com/rqlite/gorqlite v0.0.0-20240808172217-12ae7d03ef19
|
||||
## explicit
|
||||
github.com/rqlite/gorqlite
|
||||
|
||||
Reference in New Issue
Block a user