Finish taint steps

This commit is contained in:
jorgectf
2022-03-13 13:59:03 +01:00
parent 447636bf1c
commit ded9663f2b
3 changed files with 76 additions and 19 deletions

View File

@@ -4,6 +4,8 @@
import java
import semmle.code.java.dataflow.ExternalFlow
private import semmle.code.java.dataflow.DataFlow
private import semmle.code.java.dataflow.TaintTracking
/** The class `org.apache.ibatis.jdbc.SqlRunner`. */
class MyBatisSqlRunner extends RefType {
@@ -104,38 +106,93 @@ class TypeParam extends Interface {
}
module ProviderInjection {
private import semmle.code.java.dataflow.DataFlow
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()
.hasQualifiedName("org.apache.ibatis.annotations",
["Select", "Delete", "Insert", "Update"] + "Provider") and
a.getType() instanceof MyBatisProvider and
type = a.getValue(["type", "value"]) and
c.hasMethod(m, type.getTypeName().getType()) and
m.hasName(a.getTarget().getName()) and
m.hasName(a.getValue("method").(StringLiteral).getValue()) and
this.asExpr() = m.getBody().getAStmt().(ReturnStmt).getResult()
)
}
}
class MyBatisAbstractSQLStep extends Unit {
predicate step(DataFlow::Node node1, DataFlow::Node node2) {
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()
.hasQualifiedName("org.apache.ibatis.jdbc", ["AbstractSQL", "AbstractSQL<SQL>"]) and
ma.getMethod()
.hasName([
"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"
]) and
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
)
}
}
}

View File

@@ -129,6 +129,6 @@ private class MyBatisOgnlInjectionSink extends OgnlInjectionSink instanceof MyBa
private class MyBatisAbstractSQLOgnlInjectionStep extends OgnlInjectionAdditionalTaintStep {
override predicate step(DataFlow::Node node1, DataFlow::Node node2) {
any(MyBatisAbstractSQLStep step).step(node1, node2)
any(MyBatisAdditionalTaintStep step).step(node1, node2)
}
}

View File

@@ -73,6 +73,6 @@ private class MyBatisSqlInjectionSink extends QueryInjectionSink instanceof MyBa
private class MyBatisAbstractSQLInjectionStep extends AdditionalQueryInjectionTaintStep {
override predicate step(DataFlow::Node node1, DataFlow::Node node2) {
any(MyBatisAbstractSQLStep step).step(node1, node2)
any(MyBatisAdditionalTaintStep step).step(node1, node2)
}
}