Skip to content

Commit a04ff18

Browse files
committed
Java: Enable validation wrappers in BarrierGuards.
1 parent 3674966 commit a04ff18

File tree

2 files changed

+11
-45
lines changed

2 files changed

+11
-45
lines changed

java/ql/lib/semmle/code/java/dataflow/internal/SsaImpl.qll

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -562,14 +562,18 @@ private module Cached {
562562

563563
cached // nothing is actually cached
564564
module BarrierGuard<guardChecksSig/3 guardChecks> {
565-
private predicate guardChecksAdjTypes(
565+
private predicate guardChecksAdjTypes(Guards::Guards_v3::Guard g, Expr e, boolean branch) {
566+
guardChecks(g, e, branch)
567+
}
568+
569+
private predicate guardChecksWithWrappers(
566570
DataFlowIntegrationInput::Guard g, DataFlowIntegrationInput::Expr e, Guards::GuardValue val
567571
) {
568-
guardChecks(g, e, val.asBooleanValue())
572+
Guards::Guards_v3::ValidationWrapper<guardChecksAdjTypes/3>::guardChecks(g, e, val)
569573
}
570574

571575
private Node getABarrierNodeImpl() {
572-
result = DataFlowIntegrationImpl::BarrierGuard<guardChecksAdjTypes/3>::getABarrierNode()
576+
result = DataFlowIntegrationImpl::BarrierGuard<guardChecksWithWrappers/3>::getABarrierNode()
573577
}
574578

575579
predicate getABarrierNode = getABarrierNodeImpl/0;

java/ql/lib/semmle/code/java/security/PathSanitizer.qll

Lines changed: 4 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -13,33 +13,6 @@ private import semmle.code.java.dataflow.Nullness
1313
/** A sanitizer that protects against path injection vulnerabilities. */
1414
abstract class PathInjectionSanitizer extends DataFlow::Node { }
1515

16-
/**
17-
* Provides a set of nodes validated by a method that uses a validation guard.
18-
*/
19-
private module ValidationMethod<DataFlow::guardChecksSig/3 validationGuard> {
20-
/** Gets a node that is safely guarded by a method that uses the given guard check. */
21-
DataFlow::Node getAValidatedNode() {
22-
exists(MethodCall ma, int pos, VarRead rv |
23-
validationMethod(ma.getMethod(), pos) and
24-
ma.getArgument(pos) = rv and
25-
adjacentUseUseSameVar(rv, result.asExpr()) and
26-
ma.getBasicBlock().dominates(result.asExpr().getBasicBlock())
27-
)
28-
}
29-
30-
/**
31-
* Holds if `m` validates its `arg`th parameter by using `validationGuard`.
32-
*/
33-
private predicate validationMethod(Method m, int arg) {
34-
exists(Guard g, SsaImplicitInit var, ControlFlow::NormalExitNode normexit, boolean branch |
35-
validationGuard(g, var.getAUse(), branch) and
36-
var.isParameterDefinition(m.getParameter(arg)) and
37-
normexit.getEnclosingCallable() = m and
38-
g.controls(normexit.getBasicBlock(), branch)
39-
)
40-
}
41-
}
42-
4316
/**
4417
* Holds if `g` is guard that compares a path to a trusted value.
4518
*/
@@ -68,8 +41,6 @@ private predicate exactPathMatchGuard(Guard g, Expr e, boolean branch) {
6841
class ExactPathMatchSanitizer extends PathInjectionSanitizer {
6942
ExactPathMatchSanitizer() {
7043
this = DataFlow::BarrierGuard<exactPathMatchGuard/3>::getABarrierNode()
71-
or
72-
this = ValidationMethod<exactPathMatchGuard/3>::getAValidatedNode()
7344
}
7445
}
7546

@@ -120,8 +91,7 @@ private predicate allowedPrefixGuard(Guard g, Expr e, boolean branch) {
12091

12192
private class AllowedPrefixSanitizer extends PathInjectionSanitizer {
12293
AllowedPrefixSanitizer() {
123-
this = DataFlow::BarrierGuard<allowedPrefixGuard/3>::getABarrierNode() or
124-
this = ValidationMethod<allowedPrefixGuard/3>::getAValidatedNode()
94+
this = DataFlow::BarrierGuard<allowedPrefixGuard/3>::getABarrierNode()
12595
}
12696
}
12797

@@ -139,10 +109,7 @@ private predicate dotDotCheckGuard(Guard g, Expr e, boolean branch) {
139109
}
140110

141111
private class DotDotCheckSanitizer extends PathInjectionSanitizer {
142-
DotDotCheckSanitizer() {
143-
this = DataFlow::BarrierGuard<dotDotCheckGuard/3>::getABarrierNode() or
144-
this = ValidationMethod<dotDotCheckGuard/3>::getAValidatedNode()
145-
}
112+
DotDotCheckSanitizer() { this = DataFlow::BarrierGuard<dotDotCheckGuard/3>::getABarrierNode() }
146113
}
147114

148115
private class BlockListGuard extends PathGuard instanceof MethodCall {
@@ -179,10 +146,7 @@ private predicate blockListGuard(Guard g, Expr e, boolean branch) {
179146
}
180147

181148
private class BlockListSanitizer extends PathInjectionSanitizer {
182-
BlockListSanitizer() {
183-
this = DataFlow::BarrierGuard<blockListGuard/3>::getABarrierNode() or
184-
this = ValidationMethod<blockListGuard/3>::getAValidatedNode()
185-
}
149+
BlockListSanitizer() { this = DataFlow::BarrierGuard<blockListGuard/3>::getABarrierNode() }
186150
}
187151

188152
private class ConstantOrRegex extends Expr {
@@ -368,7 +332,6 @@ private class FileConstructorChildArgumentStep extends AdditionalTaintStep {
368332
n2.asExpr() = constrCall
369333
|
370334
not n1 = DataFlow::BarrierGuard<pathTraversalGuard/3>::getABarrierNode() and
371-
not n1 = ValidationMethod<pathTraversalGuard/3>::getAValidatedNode() and
372335
not TaintTracking::localExprTaint(any(PathNormalizeSanitizer p), n1.asExpr())
373336
or
374337
DataFlow::localExprFlow(nullExpr(), constrCall.getArgument(0))
@@ -546,7 +509,6 @@ private predicate directoryCharactersGuard(Guard g, Expr e, boolean branch) {
546509
private class DirectoryCharactersSanitizer extends PathInjectionSanitizer {
547510
DirectoryCharactersSanitizer() {
548511
this.asExpr() instanceof ReplaceDirectoryCharactersSanitizer or
549-
this = DataFlow::BarrierGuard<directoryCharactersGuard/3>::getABarrierNode() or
550-
this = ValidationMethod<directoryCharactersGuard/3>::getAValidatedNode()
512+
this = DataFlow::BarrierGuard<directoryCharactersGuard/3>::getABarrierNode()
551513
}
552514
}

0 commit comments

Comments
 (0)