Generally extend TaintTracking::AdditionalTaintStep

This commit is contained in:
jorgectf
2022-03-14 13:39:20 +01:00
parent ded9663f2b
commit a0bf68f7cd
3 changed files with 84 additions and 104 deletions

View File

@@ -105,94 +105,88 @@ class TypeParam extends Interface {
TypeParam() { this.hasQualifiedName("org.apache.ibatis.annotations", "Param") }
}
module ProviderInjection {
private class MyBatisAbstractSQL extends RefType {
MyBatisAbstractSQL() { this.hasQualifiedName("org.apache.ibatis.jdbc", "AbstractSQL") }
}
private class MyBatisAbstractSQL extends RefType {
MyBatisAbstractSQL() { this.hasQualifiedName("org.apache.ibatis.jdbc", "AbstractSQL") }
}
private class MyBatisProvider extends RefType {
MyBatisProvider() {
this.hasQualifiedName("org.apache.ibatis.annotations",
["Select", "Delete", "Insert", "Update"] + "Provider")
}
}
private class MyBatisAbstractSQLMethodNames extends string {
MyBatisAbstractSQLMethodNames() {
this in [
"SELECT", "OFFSET_ROWS", "FETCH_FIRST_ROWS_ONLY", "OFFSET", "LIMIT", "ORDER_BY", "HAVING",
"GROUP_BY", "WHERE", "OUTER_JOIN", "RIGHT_OUTER_JOIN", "LEFT_OUTER_JOIN", "INNER_JOIN",
"JOIN", "FROM", "DELETE_FROM", "SELECT_DISTINCT", "SELECT", "INTO_VALUES", "INTO_COLUMNS",
"VALUES", "INSERT_INTO", "SET", "UPDATE"
]
}
}
class MyBatisInjectionSink extends DataFlow::Node {
MyBatisInjectionSink() {
exists(Annotation a, Method m, TypeLiteral type, Class c |
a.getType() instanceof MyBatisProvider and
type = a.getValue(["type", "value"]) and
c.hasMethod(m, type.getTypeName().getType()) and
m.hasName(a.getValue("method").(StringLiteral).getValue()) and
this.asExpr() = m.getBody().getAStmt().(ReturnStmt).getResult()
)
}
}
class MyBatisAdditionalTaintStep extends TaintTracking::AdditionalTaintStep {
abstract override predicate step(DataFlow::Node node1, DataFlow::Node node2);
}
private class MyBatisProviderStep extends MyBatisAdditionalTaintStep {
override predicate step(DataFlow::Node n1, DataFlow::Node n2) {
exists(
MethodAccess ma, Annotation a, Method annotatedMethod, Method providerMethod,
TypeLiteral type, Class c
|
a.getType() instanceof MyBatisProvider and
annotatedMethod.getAnAnnotation() = a and
ma.getMethod() = annotatedMethod and
ma.getAnArgument() = n1.asExpr() and
type = a.getValue(["type", "value"]) and
providerMethod.hasName(a.getValue("method").(StringLiteral).getValue()) and
c.hasMethod(providerMethod, type.getTypeName().getType()) and
providerMethod.getAParameter() = n2.asParameter()
)
}
}
private class MyBatisAbstractSQLToStringStep extends MyBatisAdditionalTaintStep {
override predicate step(DataFlow::Node node1, DataFlow::Node node2) {
exists(MethodAccess ma |
ma.getMethod().getDeclaringType().getSourceDeclaration() instanceof MyBatisAbstractSQL and
ma.getMethod().getName() = "toString" and
ma.getQualifier() = node1.asExpr() and
ma = node2.asExpr()
)
}
}
private class MyBatisAbstractSQLMethodsStep extends MyBatisAdditionalTaintStep {
override predicate step(DataFlow::Node node1, DataFlow::Node node2) {
exists(MethodAccess ma |
ma.getMethod().getDeclaringType().getSourceDeclaration() instanceof MyBatisAbstractSQL and
ma.getMethod().getName() instanceof MyBatisAbstractSQLMethodNames and
ma.getArgument([0, 1]) = node1.asExpr() and
ma = node2.asExpr()
)
}
}
private class MyBatisAbstractSQLAnonymousClassStep extends MyBatisAdditionalTaintStep {
override predicate step(DataFlow::Node node1, DataFlow::Node node2) {
exists(MethodAccess ma, ClassInstanceExpr c |
ma.getMethod().getDeclaringType().getSourceDeclaration() instanceof MyBatisAbstractSQL and
ma.getMethod().getName() instanceof MyBatisAbstractSQLMethodNames and
c.getAnonymousClass().getACallable() = ma.getCaller() and
node1.asExpr() = ma and
node2.asExpr() = c
)
}
private class MyBatisProvider extends RefType {
MyBatisProvider() {
this.hasQualifiedName("org.apache.ibatis.annotations",
["Select", "Delete", "Insert", "Update"] + "Provider")
}
}
private class MyBatisAbstractSQLMethodNames extends string {
MyBatisAbstractSQLMethodNames() {
this in [
"SELECT", "OFFSET_ROWS", "FETCH_FIRST_ROWS_ONLY", "OFFSET", "LIMIT", "ORDER_BY", "HAVING",
"GROUP_BY", "WHERE", "OUTER_JOIN", "RIGHT_OUTER_JOIN", "LEFT_OUTER_JOIN", "INNER_JOIN",
"JOIN", "FROM", "DELETE_FROM", "SELECT_DISTINCT", "SELECT", "INTO_VALUES", "INTO_COLUMNS",
"VALUES", "INSERT_INTO", "SET", "UPDATE"
]
}
}
class MyBatisInjectionSink extends DataFlow::Node {
MyBatisInjectionSink() {
exists(Annotation a, Method m, TypeLiteral type, Class c |
a.getType() instanceof MyBatisProvider and
type = a.getValue(["type", "value"]) and
c.hasMethod(m, type.getTypeName().getType()) and
m.hasName(a.getValue("method").(StringLiteral).getValue()) and
this.asExpr() = m.getBody().getAStmt().(ReturnStmt).getResult()
)
}
}
private class MyBatisProviderStep extends TaintTracking::AdditionalTaintStep {
override predicate step(DataFlow::Node n1, DataFlow::Node n2) {
exists(
MethodAccess ma, Annotation a, Method annotatedMethod, Method providerMethod,
TypeLiteral type, Class c
|
a.getType() instanceof MyBatisProvider and
annotatedMethod.getAnAnnotation() = a and
ma.getMethod() = annotatedMethod and
ma.getAnArgument() = n1.asExpr() and
type = a.getValue(["type", "value"]) and
providerMethod.hasName(a.getValue("method").(StringLiteral).getValue()) and
c.hasMethod(providerMethod, type.getTypeName().getType()) and
providerMethod.getAParameter() = n2.asParameter()
)
}
}
private class MyBatisAbstractSQLToStringStep extends TaintTracking::AdditionalTaintStep {
override predicate step(DataFlow::Node node1, DataFlow::Node node2) {
exists(MethodAccess ma |
ma.getMethod().getDeclaringType().getSourceDeclaration() instanceof MyBatisAbstractSQL and
ma.getMethod().getName() = "toString" and
ma.getQualifier() = node1.asExpr() and
ma = node2.asExpr()
)
}
}
private class MyBatisAbstractSQLMethodsStep extends TaintTracking::AdditionalTaintStep {
override predicate step(DataFlow::Node node1, DataFlow::Node node2) {
exists(MethodAccess ma |
ma.getMethod().getDeclaringType().getSourceDeclaration() instanceof MyBatisAbstractSQL and
ma.getMethod().getName() instanceof MyBatisAbstractSQLMethodNames and
ma.getArgument([0, 1]) = node1.asExpr() and
ma = node2.asExpr()
)
}
}
private class MyBatisAbstractSQLAnonymousClassStep extends TaintTracking::AdditionalTaintStep {
override predicate step(DataFlow::Node node1, DataFlow::Node node2) {
exists(MethodAccess ma, ClassInstanceExpr c |
ma.getMethod().getDeclaringType().getSourceDeclaration() instanceof MyBatisAbstractSQL and
ma.getMethod().getName() instanceof MyBatisAbstractSQLMethodNames and
c.getAnonymousClass().getACallable() = ma.getCaller() and
node1.asExpr() = ma and
node2.asExpr() = c
)
}
}

View File

@@ -3,6 +3,7 @@
import java
private import semmle.code.java.dataflow.DataFlow
private import semmle.code.java.dataflow.ExternalFlow
private import semmle.code.java.frameworks.MyBatis
/**
* A data flow sink for unvalidated user input that is used in OGNL EL evaluation.
@@ -123,12 +124,4 @@ private class DefaultOgnlInjectionAdditionalTaintStep extends OgnlInjectionAddit
}
}
private import semmle.code.java.frameworks.MyBatis::ProviderInjection
private class MyBatisOgnlInjectionSink extends OgnlInjectionSink instanceof MyBatisInjectionSink { }
private class MyBatisAbstractSQLOgnlInjectionStep extends OgnlInjectionAdditionalTaintStep {
override predicate step(DataFlow::Node node1, DataFlow::Node node2) {
any(MyBatisAdditionalTaintStep step).step(node1, node2)
}
}

View File

@@ -3,6 +3,7 @@
import java
import semmle.code.java.dataflow.DataFlow
import semmle.code.java.frameworks.javaee.Persistence
private import semmle.code.java.frameworks.MyBatis
import semmle.code.java.dataflow.ExternalFlow
/** A sink for database query language injection vulnerabilities. */
@@ -67,12 +68,4 @@ private class MongoJsonStep extends AdditionalQueryInjectionTaintStep {
}
}
private import semmle.code.java.frameworks.MyBatis::ProviderInjection
private class MyBatisSqlInjectionSink extends QueryInjectionSink instanceof MyBatisInjectionSink { }
private class MyBatisAbstractSQLInjectionStep extends AdditionalQueryInjectionTaintStep {
override predicate step(DataFlow::Node node1, DataFlow::Node node2) {
any(MyBatisAdditionalTaintStep step).step(node1, node2)
}
}