Convert squirrel sql-injection sinks to MaD (non-existent methods removed)

Various non-existent methods were modeled, and I couldn't find any
evidence that they used to exist. They aren't in the stubs or tests. I
have removed them.
This commit is contained in:
Owen Mansel-Chan
2024-08-08 12:21:32 +01:00
parent 45458ed72b
commit 924467bebe
3 changed files with 68 additions and 45 deletions

View File

@@ -0,0 +1,51 @@
extensions:
- addsTo:
pack: codeql/go-all
extensible: packageGrouping
data:
- ["squirrel", "github.com/Masterminds/squirrel"]
- ["squirrel", "gopkg.in/Masterminds/squirrel"]
- ["squirrel", "github.com/lann/squirrel"]
- addsTo:
pack: codeql/go-all
extensible: sinkModel
data:
- ["group:squirrel", "", True, "Delete", "", "", "Argument[0]", "sql-injection", "manual"]
- ["group:squirrel", "", True, "Expr", "", "", "Argument[0]", "sql-injection", "manual"]
- ["group:squirrel", "", True, "Insert", "", "", "Argument[0]", "sql-injection", "manual"]
- ["group:squirrel", "", True, "Select", "", "", "Argument[0]", "sql-injection", "manual"] # TODO: when sources can have access paths, use .ArrayElement
- ["group:squirrel", "", True, "Update", "", "", "Argument[0]", "sql-injection", "manual"] # TODO: when sources can have access paths, use .ArrayElement
- ["group:squirrel", "DeleteBuilder", True, "From", "", "", "Argument[0]", "sql-injection", "manual"]
- ["group:squirrel", "DeleteBuilder", True, "OrderBy", "", "", "Argument[0]", "sql-injection", "manual"] # TODO: when sources can have access paths, use .ArrayElement
- ["group:squirrel", "DeleteBuilder", True, "Prefix", "", "", "Argument[0]", "sql-injection", "manual"]
- ["group:squirrel", "DeleteBuilder", True, "Suffix", "", "", "Argument[0]", "sql-injection", "manual"]
- ["group:squirrel", "DeleteBuilder", True, "Where", "", "", "Argument[0]", "sql-injection", "manual"]
- ["group:squirrel", "InsertBuilder", True, "Columns", "", "", "Argument[0]", "sql-injection", "manual"] # TODO: when sources can have access paths, use .ArrayElement
- ["group:squirrel", "InsertBuilder", True, "Into", "", "", "Argument[0]", "sql-injection", "manual"]
- ["group:squirrel", "InsertBuilder", True, "Options", "", "", "Argument[0]", "sql-injection", "manual"] # TODO: when sources can have access paths, use .ArrayElement
- ["group:squirrel", "InsertBuilder", True, "Prefix", "", "", "Argument[0]", "sql-injection", "manual"]
- ["group:squirrel", "InsertBuilder", True, "Suffix", "", "", "Argument[0]", "sql-injection", "manual"]
- ["group:squirrel", "SelectBuilder", True, "CrossJoin", "", "", "Argument[0]", "sql-injection", "manual"]
- ["group:squirrel", "SelectBuilder", True, "Column", "", "", "Argument[0]", "sql-injection", "manual"]
- ["group:squirrel", "SelectBuilder", True, "Columns", "", "", "Argument[0]", "sql-injection", "manual"] # TODO: when sources can have access paths, use .ArrayElement
- ["group:squirrel", "SelectBuilder", True, "From", "", "", "Argument[0]", "sql-injection", "manual"]
- ["group:squirrel", "SelectBuilder", True, "GroupBy", "", "", "Argument[0]", "sql-injection", "manual"]
- ["group:squirrel", "SelectBuilder", True, "InnerJoin", "", "", "Argument[0]", "sql-injection", "manual"]
- ["group:squirrel", "SelectBuilder", True, "LeftJoin", "", "", "Argument[0]", "sql-injection", "manual"]
- ["group:squirrel", "SelectBuilder", True, "Options", "", "", "Argument[0]", "sql-injection", "manual"] # TODO: when sources can have access paths, use .ArrayElement
- ["group:squirrel", "SelectBuilder", True, "OrderBy", "", "", "Argument[0]", "sql-injection", "manual"] # TODO: when sources can have access paths, use .ArrayElement
- ["group:squirrel", "SelectBuilder", True, "Prefix", "", "", "Argument[0]", "sql-injection", "manual"]
- ["group:squirrel", "SelectBuilder", True, "RightJoin", "", "", "Argument[0]", "sql-injection", "manual"]
- ["group:squirrel", "SelectBuilder", True, "Suffix", "", "", "Argument[0]", "sql-injection", "manual"]
- ["group:squirrel", "SelectBuilder", True, "Where", "", "", "Argument[0]", "sql-injection", "manual"]
- ["group:squirrel", "UpdateBuilder", True, "From", "", "", "Argument[0]", "sql-injection", "manual"]
- ["group:squirrel", "UpdateBuilder", True, "OrderBy", "", "", "Argument[0]", "sql-injection", "manual"] # TODO: when sources can have access paths, use .ArrayElement
- ["group:squirrel", "UpdateBuilder", True, "Prefix", "", "", "Argument[0]", "sql-injection", "manual"]
- ["group:squirrel", "UpdateBuilder", True, "Set", "", "", "Argument[0]", "sql-injection", "manual"]
- ["group:squirrel", "UpdateBuilder", True, "Suffix", "", "", "Argument[0]", "sql-injection", "manual"]
- ["group:squirrel", "UpdateBuilder", True, "Table", "", "", "Argument[0]", "sql-injection", "manual"]
- ["group:squirrel", "UpdateBuilder", True, "Where", "", "", "Argument[0]", "sql-injection", "manual"]

View File

@@ -67,42 +67,14 @@ module SQL {
*/
abstract class Range extends DataFlow::Node { }
/**
* An argument to an API of the squirrel library that is directly interpreted as SQL without
* taking syntactic structure into account.
*/
private class SquirrelQueryString extends Range {
SquirrelQueryString() {
exists(Function fn |
exists(string sq |
sq =
package([
"github.com/Masterminds/squirrel", "gopkg.in/Masterminds/squirrel",
"github.com/lann/squirrel"
], "")
|
fn.hasQualifiedName(sq, ["Delete", "Expr", "Insert", "Select", "Update"])
or
exists(Method m, string builder | m = fn |
builder = ["DeleteBuilder", "InsertBuilder", "SelectBuilder", "UpdateBuilder"] and
m.hasQualifiedName(sq, builder,
["Columns", "From", "Options", "OrderBy", "Prefix", "Suffix", "Where"])
or
builder = "InsertBuilder" and
m.hasQualifiedName(sq, builder, ["Replace", "Into"])
or
builder = "SelectBuilder" and
m.hasQualifiedName(sq, builder,
["CrossJoin", "GroupBy", "InnerJoin", "LeftJoin", "RightJoin"])
or
builder = "UpdateBuilder" and
m.hasQualifiedName(sq, builder, ["Set", "Table"])
)
) and
this = fn.getACall().getArgument(0)
|
this.getType().getUnderlyingType() instanceof StringType or
this.getType().getUnderlyingType().(SliceType).getElementType() instanceof StringType
private class DefaultQueryString extends Range {
DefaultQueryString() {
exists(DataFlow::ArgumentNode arg | sinkNode(arg, "sql-injection") |
not arg instanceof DataFlow::ImplicitVarargsSlice and
this = arg
or
arg instanceof DataFlow::ImplicitVarargsSlice and
this = arg.getCall().getAnImplicitVarargsArgument()
)
}
}

View File

@@ -10,35 +10,35 @@ func squirrelTest(querypart string) {
squirrel.Expr(querypart) // $ querystring=querypart
deleteBuilder := squirrel.Delete(querypart) // $ querystring=querypart
deleteBuilder.From(querypart) // $ querystring=querypart
deleteBuilder.OrderBy(querypart) // $ querystring=[]type{args}
deleteBuilder.OrderBy(querypart) // $ querystring=querypart
deleteBuilder.Prefix(querypart) // $ querystring=querypart
deleteBuilder.Suffix(querypart) // $ querystring=querypart
deleteBuilder.Where(querypart) // $ querystring=querypart
insertBuilder := squirrel.Insert(querypart) // $ querystring=querypart
insertBuilder.Columns(querypart) // $ querystring=[]type{args}
insertBuilder.Options(querypart) // $ querystring=[]type{args}
insertBuilder.Columns(querypart) // $ querystring=querypart
insertBuilder.Options(querypart) // $ querystring=querypart
insertBuilder.Prefix(querypart) // $ querystring=querypart
insertBuilder.Suffix(querypart) // $ querystring=querypart
insertBuilder.Into(querypart) // $ querystring=querypart
selectBuilder := squirrel.Select(querypart) // $ querystring=[]type{args}
selectBuilder.Columns(querypart) // $ querystring=[]type{args}
selectBuilder := squirrel.Select(querypart) // $ querystring=querypart
selectBuilder.Columns(querypart) // $ querystring=querypart
selectBuilder.From(querypart) // $ querystring=querypart
selectBuilder.Options(querypart) // $ querystring=[]type{args}
selectBuilder.OrderBy(querypart) // $ querystring=[]type{args}
selectBuilder.Options(querypart) // $ querystring=querypart
selectBuilder.OrderBy(querypart) // $ querystring=querypart
selectBuilder.Prefix(querypart) // $ querystring=querypart
selectBuilder.Suffix(querypart) // $ querystring=querypart
selectBuilder.Where(querypart) // $ querystring=querypart
selectBuilder.CrossJoin(querypart) // $ querystring=querypart
selectBuilder.GroupBy(querypart) // $ querystring=[]type{args}
selectBuilder.GroupBy(querypart) // $ querystring=querypart
selectBuilder.InnerJoin(querypart) // $ querystring=querypart
selectBuilder.LeftJoin(querypart) // $ querystring=querypart
selectBuilder.RightJoin(querypart) // $ querystring=querypart
updateBuilder := squirrel.Update(querypart) // $ querystring=querypart
updateBuilder.From(querypart) // $ querystring=querypart
updateBuilder.OrderBy(querypart) // $ querystring=[]type{args}
updateBuilder.OrderBy(querypart) // $ querystring=querypart
updateBuilder.Prefix(querypart) // $ querystring=querypart
updateBuilder.Suffix(querypart) // $ querystring=querypart
updateBuilder.Where(querypart) // $ querystring=querypart