Merge pull request #149 from max-schaefer/cleanup-130

Clean up NoSQL library
This commit is contained in:
Max Schaefer
2020-05-20 13:55:54 +01:00
committed by GitHub
7 changed files with 57 additions and 41 deletions

View File

@@ -0,0 +1,3 @@
lgtm,codescanning
* Modeling of the `go.mongodb.org/mongo-driver/mongo` package has been added, which may lead to more
results from the security queries.

View File

@@ -7,83 +7,98 @@ import go
/** Provides classes for working with NoSQL-related APIs. */
module NoSQL {
/**
* A data-flow node whose string value is interpreted as (part of) a NoSQL query.
* A data-flow node whose value is interpreted as (part of) a NoSQL query.
*
* Extend this class to refine existing API models. If you want to model new APIs,
* extend `NoSQL::QueryString::Range` instead.
* extend `NoSQL::Query::Range` instead.
*/
class NoSQLQueryString extends DataFlow::Node {
NoSQLQueryString::Range self;
class Query extends DataFlow::Node {
Query::Range self;
NoSQLQueryString() { this = self }
Query() { this = self }
}
/** Provides classes for working with SQL query strings. */
module NoSQLQueryString {
/** Provides classes for working with NoSQL queries. */
module Query {
/**
* A data-flow node whose string value is interpreted as (part of) a NoSQL query.
* A data-flow node whose value is interpreted as (part of) a NoSQL query.
*
* Extend this class to model new APIs. If you want to refine existing API models,
* extend `NoSQL::QueryString` instead.
* extend `NoSQL::Query` instead.
*/
abstract class Range extends DataFlow::Node { }
/**
* Holds if method `name` of `Collection` struct of `go.mongodb.org/mongo-driver/mongo`
* package interprets parameter `n` as a query.
* Holds if method `name` of struct `Collection` from package
* [go.mongodb.org/mongo-driver/mongo](https://pkg.go.dev/go.mongodb.org/mongo-driver/mongo)
* interprets parameter `n` as a query.
*/
private predicate collectionMethods(string name, int n) {
// func (coll *Collection) CountDocuments(ctx context.Context, filter interface{}, opts ...*options.CountOptions) (int64, error)
private predicate mongoDbCollectionMethod(string name, int n) {
// func (coll *Collection) CountDocuments(ctx context.Context, filter interface{},
// opts ...*options.CountOptions) (int64, error)
name = "CountDocuments" and n = 1
or
// func (coll *Collection) DeleteMany(ctx context.Context, filter interface{}, opts ...*options.DeleteOptions) (*DeleteResult, error)
// func (coll *Collection) DeleteMany(ctx context.Context, filter interface{},
// opts ...*options.DeleteOptions) (*DeleteResult, error)
name = "DeleteMany" and n = 1
or
// func (coll *Collection) DeleteOne(ctx context.Context, filter interface{}, opts ...*options.DeleteOptions) (*DeleteResult, error)
// func (coll *Collection) DeleteOne(ctx context.Context, filter interface{},
// opts ...*options.DeleteOptions) (*DeleteResult, error)
name = "DeleteOne" and n = 1
or
// func (coll *Collection) Distinct(ctx context.Context, fieldName string, filter interface{}, ...) ([]interface{}, error)
// func (coll *Collection) Distinct(ctx context.Context, fieldName string, filter interface{},
// ...) ([]interface{}, error)
name = "Distinct" and n = 2
or
// func (coll *Collection) Find(ctx context.Context, filter interface{}, opts ...*options.FindOptions) (*Cursor, error)
// func (coll *Collection) Find(ctx context.Context, filter interface{},
// opts ...*options.FindOptions) (*Cursor, error)
name = "Find" and n = 1
or
// func (coll *Collection) FindOne(ctx context.Context, filter interface{}, opts ...*options.FindOneOptions) *SingleResult
// func (coll *Collection) FindOne(ctx context.Context, filter interface{},
// opts ...*options.FindOneOptions) *SingleResult
name = "FindOne" and n = 1
or
// func (coll *Collection) FindOneAndDelete(ctx context.Context, filter interface{}, ...) *SingleResult
// func (coll *Collection) FindOneAndDelete(ctx context.Context, filter interface{}, ...)
// *SingleResult
name = "FindOneAndDelete" and n = 1
or
// func (coll *Collection) FindOneAndReplace(ctx context.Context, filter interface{}, replacement interface{}, ...) *SingleResult
// func (coll *Collection) FindOneAndReplace(ctx context.Context, filter interface{},
// replacement interface{}, ...) *SingleResult
name = "FindOneAndReplace" and n = 1
or
// func (coll *Collection) FindOneAndUpdate(ctx context.Context, filter interface{}, update interface{}, ...) *SingleResult
// func (coll *Collection) FindOneAndUpdate(ctx context.Context, filter interface{},
// update interface{}, ...) *SingleResult
name = "FindOneAndUpdate" and n = 1
or
// func (coll *Collection) ReplaceOne(ctx context.Context, filter interface{}, replacement interface{}, ...) (*UpdateResult, error)
// func (coll *Collection) ReplaceOne(ctx context.Context, filter interface{},
// replacement interface{}, ...) (*UpdateResult, error)
name = "ReplaceOne" and n = 1
or
// func (coll *Collection) UpdateMany(ctx context.Context, filter interface{}, update interface{}, ...) (*UpdateResult, error)
// func (coll *Collection) UpdateMany(ctx context.Context, filter interface{},
// update interface{}, ...) (*UpdateResult, error)
name = "UpdateMany" and n = 1
or
// func (coll *Collection) UpdateOne(ctx context.Context, filter interface{}, update interface{}, ...) (*UpdateResult, error)
// func (coll *Collection) UpdateOne(ctx context.Context, filter interface{},
// update interface{}, ...) (*UpdateResult, error)
name = "UpdateOne" and n = 1
or
// func (coll *Collection) Watch(ctx context.Context, pipeline interface{}, ...) (*ChangeStream, error)
// func (coll *Collection) Watch(ctx context.Context, pipeline interface{}, ...)
// (*ChangeStream, error)
name = "Watch" and n = 1
or
// func (coll *Collection) Aggregate(ctx context.Context, pipeline interface{}, opts ...*options.AggregateOptions) (*Cursor, error)
// func (coll *Collection) Aggregate(ctx context.Context, pipeline interface{},
// opts ...*options.AggregateOptions) (*Cursor, error)
name = "Aggregate" and n = 1
}
/**
* A query string used in an API function acting on a `Collection` struct of
* `go.mongodb.org/mongo-driver/mongo` package
* A query used in an API function acting on a `Collection` struct of package
* [go.mongodb.org/mongo-driver/mongo](https://pkg.go.dev/go.mongodb.org/mongo-driver/mongo).
*/
private class MongoDbCollectionQueryString extends Range {
MongoDbCollectionQueryString() {
private class MongoDbCollectionQuery extends Range {
MongoDbCollectionQuery() {
exists(Method meth, string methodName, int n |
collectionMethods(methodName, n) and
mongoDbCollectionMethod(methodName, n) and
meth.hasQualifiedName("go.mongodb.org/mongo-driver/mongo", "Collection", methodName) and
this = meth.getACall().getArgument(n)
)
@@ -97,7 +112,7 @@ module NoSQL {
predicate isAdditionalMongoTaintStep(DataFlow::Node pred, DataFlow::Node succ) {
// Taint an entry if the `Value` is tainted
exists(Write w, DataFlow::Node base, Field f | w.writesField(base, f, pred) |
base = succ.getASuccessor*() and
base = succ.(DataFlow::PostUpdateNode).getPreUpdateNode() and
base.getType().hasQualifiedName("go.mongodb.org/mongo-driver/bson/primitive", "E") and
f.getName() = "Value"
)

View File

@@ -23,8 +23,8 @@ module SqlInjection {
override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
override predicate isAdditionalTaintStep(DataFlow::Node prev, DataFlow::Node succ) {
NoSQL::isAdditionalMongoTaintStep(prev, succ)
override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) {
NoSQL::isAdditionalMongoTaintStep(pred, succ)
}
override predicate isSanitizer(DataFlow::Node node) {

View File

@@ -40,8 +40,8 @@ module SqlInjection {
SqlQueryAsSink() { this instanceof SQL::QueryString }
}
/** An NoSQL string, considered as a taint sink for SQL injection. */
/** A NoSQL query, considered as a taint sink for SQL injection. */
class NoSqlQueryAsSink extends Sink {
NoSqlQueryAsSink() { this instanceof NoSQL::NoSQLQueryString }
NoSqlQueryAsSink() { this instanceof NoSQL::Query }
}
}

View File

@@ -0,0 +1,3 @@
import go
select any(NoSQL::Query q)

View File

@@ -1,5 +0,0 @@
import go
import semmle.go.frameworks.NoSQL
from NoSQL::NoSQLQueryString qs
select qs