Add TaintedPermissionsCheckQuery

This commit is contained in:
Ed Minnix
2023-03-30 22:22:37 -04:00
parent 4035b16ac1
commit 1af6d5f7b3
3 changed files with 70 additions and 49 deletions

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* Added the `TaintedPermissionQuery.qll` library to provide the `TaintedPermissionFlow` taint-tracking module to reason about tainted permission vulnerabilities.

View File

@@ -0,0 +1,65 @@
/** Provides classes to reason about tainted permissions check vulnerabilities. */
import java
import semmle.code.java.dataflow.FlowSources
import semmle.code.java.dataflow.TaintTracking
/**
* The `org.apache.shiro.subject.Subject` class.
*/
private class TypeShiroSubject extends RefType {
TypeShiroSubject() { this.getQualifiedName() = "org.apache.shiro.subject.Subject" }
}
/**
* The `org.apache.shiro.authz.permission.WildcardPermission` class.
*/
private class TypeShiroWildCardPermission extends RefType {
TypeShiroWildCardPermission() {
this.getQualifiedName() = "org.apache.shiro.authz.permission.WildcardPermission"
}
}
/**
* An expression that constructs a permission.
*/
abstract class PermissionsConstruction extends Top {
/** Gets the input to this permission construction. */
abstract Expr getInput();
}
private class PermissionsCheckMethodAccess extends MethodAccess, PermissionsConstruction {
PermissionsCheckMethodAccess() {
exists(Method m | m = this.getMethod() |
m.getDeclaringType() instanceof TypeShiroSubject and
m.getName() = "isPermitted"
or
m.getName().toLowerCase().matches("%permitted%") and
m.getNumberOfParameters() = 1
)
}
override Expr getInput() { result = this.getArgument(0) }
}
private class WildCardPermissionConstruction extends ClassInstanceExpr, PermissionsConstruction {
WildCardPermissionConstruction() {
this.getConstructor().getDeclaringType() instanceof TypeShiroWildCardPermission
}
override Expr getInput() { result = this.getArgument(0) }
}
/**
* A configuration for tracking flow from user input to a permissions check.
*/
module TaintedPermissionsCheckFlowConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof UserInput }
predicate isSink(DataFlow::Node sink) {
sink.asExpr() = any(PermissionsConstruction p).getInput()
}
}
/** Tracks flow from user input to a permissions check. */
module TaintedPermissionsCheckFlow = TaintTracking::Global<TaintedPermissionsCheckFlowConfig>;