mirror of
https://github.com/github/codeql.git
synced 2026-04-30 19:26:02 +02:00
C#: Add Dapper support to SQL injection queries
This commit is contained in:
42
csharp/ql/src/semmle/code/csharp/frameworks/Dapper.qll
Normal file
42
csharp/ql/src/semmle/code/csharp/frameworks/Dapper.qll
Normal file
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* Classes for modelling Dapper.
|
||||
*/
|
||||
|
||||
import csharp
|
||||
private import semmle.code.csharp.frameworks.system.Data
|
||||
|
||||
/** Definitions relating to the `Dapper` package. */
|
||||
module Dapper {
|
||||
/** The namespace `Dapper`. */
|
||||
class DapperNamespace extends Namespace {
|
||||
DapperNamespace() { this.hasQualifiedName("Dapper") }
|
||||
}
|
||||
|
||||
/** A class in `Dapper`. */
|
||||
class DapperClass extends Class {
|
||||
DapperClass() { this.getParent() instanceof DapperNamespace }
|
||||
}
|
||||
|
||||
/** A struct in `Dapper`. */
|
||||
class DapperStruct extends Struct {
|
||||
DapperStruct() { this.getParent() instanceof DapperNamespace }
|
||||
}
|
||||
|
||||
/** The `Dapper.SqlMapper` class. */
|
||||
class SqlMapperClass extends DapperClass {
|
||||
SqlMapperClass() { this.hasName("SqlMapper") }
|
||||
|
||||
/** Gets a DB query method. */
|
||||
ExtensionMethod getAQueryMethod() {
|
||||
result = this.getAMethod() and
|
||||
result.getName().regexpMatch("Query.*|Execute.*") and
|
||||
result.getExtendedType() instanceof SystemDataIDbConnectionInterface and
|
||||
result.isPublic()
|
||||
}
|
||||
}
|
||||
|
||||
/** The `Dapper.CommandDefinition` struct. */
|
||||
class CommandDefinitionStruct extends DapperStruct {
|
||||
CommandDefinitionStruct() { this.hasName("CommandDefinition") }
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,8 @@ private import semmle.code.csharp.frameworks.system.Data
|
||||
private import semmle.code.csharp.frameworks.system.data.SqlClient
|
||||
private import semmle.code.csharp.frameworks.EntityFramework
|
||||
private import semmle.code.csharp.frameworks.NHibernate
|
||||
private import semmle.code.csharp.frameworks.Dapper
|
||||
private import semmle.code.csharp.dataflow.DataFlow3
|
||||
|
||||
/** An expression containing a SQL command. */
|
||||
abstract class SqlExpr extends Expr {
|
||||
@@ -83,3 +85,37 @@ class MicrosoftSqlHelperMethodCallSqlExpr extends SqlExpr, MethodCall {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/** A `Dapper.SqlMapper` method that is taking a SQL string argument. */
|
||||
class DapperSqlMethodCallSqlExpr extends SqlExpr, MethodCall {
|
||||
DapperSqlMethodCallSqlExpr() {
|
||||
this.getTarget() = any(Dapper::SqlMapperClass c).getAQueryMethod()
|
||||
}
|
||||
|
||||
override Expr getSql() { result = this.getArgumentForName("sql") }
|
||||
}
|
||||
|
||||
/** A `Dapper.CommandDefinition` creation that is taking a SQL string argument and is passed to a `Dapper.SqlMapper` method. */
|
||||
class DapperCommandDefinitionMethodCallSqlExpr extends SqlExpr, ObjectCreation {
|
||||
DapperCommandDefinitionMethodCallSqlExpr() {
|
||||
this.getObjectType() instanceof Dapper::CommandDefinitionStruct and
|
||||
exists(Conf c | c.hasFlow(DataFlow::exprNode(this), _))
|
||||
}
|
||||
|
||||
override Expr getSql() { result = this.getArgumentForName("commandText") }
|
||||
}
|
||||
|
||||
private class Conf extends DataFlow3::Configuration {
|
||||
Conf() { this = "DapperCommandDefinitionFlowConfig" }
|
||||
|
||||
override predicate isSource(DataFlow::Node node) {
|
||||
node.asExpr().(ObjectCreation).getObjectType() instanceof Dapper::CommandDefinitionStruct
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node node) {
|
||||
exists(MethodCall mc |
|
||||
mc.getTarget() = any(Dapper::SqlMapperClass c).getAQueryMethod() and
|
||||
node.asExpr() = mc.getArgumentForName("command")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user