Merge pull request #13413 from egregius313/egregius313/trust-boundary

Java: Trust Boundary Violation Query
This commit is contained in:
Edward Minnix III
2023-08-18 10:33:32 -04:00
committed by GitHub
25 changed files with 518 additions and 3 deletions

View File

@@ -397,3 +397,8 @@ class GetServletResourceAsStreamMethod extends Method {
this.hasName("getResourceAsStream")
}
}
/** The interface `javax.servlet.http.HttpSession` */
class HttpServletSession extends RefType {
HttpServletSession() { this.hasQualifiedName("javax.servlet.http", "HttpSession") }
}

View File

@@ -0,0 +1,40 @@
/** Classes and predicates for reasoning about the `owasp.easpi` package. */
import java
/**
* The `org.owasp.esapi.Validator` interface.
*/
class EsapiValidator extends RefType {
EsapiValidator() { this.hasQualifiedName("org.owasp.esapi", "Validator") }
}
/**
* The methods of `org.owasp.esapi.Validator` which validate data.
*/
class EsapiIsValidMethod extends Method {
EsapiIsValidMethod() {
this.getDeclaringType() instanceof EsapiValidator and
this.hasName([
"isValidCreditCard", "isValidDate", "isValidDirectoryPath", "isValidDouble",
"isValidFileContent", "isValidFileName", "isValidInput", "isValidInteger",
"isValidListItem", "isValidNumber", "isValidPrintable", "isValidRedirectLocation",
"isValidSafeHTML", "isValidURI"
])
}
}
/**
* The methods of `org.owasp.esapi.Validator` which return validated data.
*/
class EsapiGetValidMethod extends Method {
EsapiGetValidMethod() {
this.getDeclaringType() instanceof EsapiValidator and
this.hasName([
"getValidCreditCard", "getValidDate", "getValidDirectoryPath", "getValidDouble",
"getValidFileContent", "getValidFileName", "getValidInput", "getValidInteger",
"getValidListItem", "getValidNumber", "getValidPrintable", "getValidRedirectLocation",
"getValidSafeHTML", "getValidURI"
])
}
}

View File

@@ -0,0 +1,70 @@
/** Provides classes and predicates to reason about trust boundary violations */
import java
private import semmle.code.java.dataflow.DataFlow
private import semmle.code.java.controlflow.Guards
private import semmle.code.java.dataflow.ExternalFlow
private import semmle.code.java.dataflow.FlowSources
private import semmle.code.java.frameworks.owasp.Esapi
/**
* A source of data that crosses a trust boundary.
*/
abstract class TrustBoundaryViolationSource extends DataFlow::Node { }
private class RemoteSource extends TrustBoundaryViolationSource instanceof RemoteFlowSource { }
/**
* A sink for data that crosses a trust boundary.
*/
class TrustBoundaryViolationSink extends DataFlow::Node {
TrustBoundaryViolationSink() { sinkNode(this, "trust-boundary-violation") }
}
/**
* A sanitizer for data that crosses a trust boundary.
*/
abstract class TrustBoundaryValidationSanitizer extends DataFlow::Node { }
/**
* A node validated by an OWASP ESAPI validation method.
*/
private class EsapiValidatedInputSanitizer extends TrustBoundaryValidationSanitizer {
EsapiValidatedInputSanitizer() {
this = DataFlow::BarrierGuard<esapiIsValidData/3>::getABarrierNode() or
this.asExpr().(MethodAccess).getMethod() instanceof EsapiGetValidMethod
}
}
/**
* Holds if `g` is a guard that checks that `e` is valid data according to an OWASP ESAPI validation method.
*/
private predicate esapiIsValidData(Guard g, Expr e, boolean branch) {
branch = true and
exists(MethodAccess ma | ma.getMethod() instanceof EsapiIsValidMethod |
g = ma and
e = ma.getArgument(1)
)
}
/**
* Taint tracking for data that crosses a trust boundary.
*/
module TrustBoundaryConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof TrustBoundaryViolationSource }
predicate isBarrier(DataFlow::Node node) {
node instanceof TrustBoundaryValidationSanitizer or
node.getType() instanceof HttpServletSession or
node.getType() instanceof NumberType or
node.getType() instanceof PrimitiveType or
node.getType() instanceof BoxedType
}
predicate isSink(DataFlow::Node sink) { sink instanceof TrustBoundaryViolationSink }
}
/**
* Taint-tracking flow for values which cross a trust boundary.
*/
module TrustBoundaryFlow = TaintTracking::Global<TrustBoundaryConfig>;