@@ -357,27 +357,6 @@ private predicate maybeNull(Expr expr) {
357
357
)
358
358
}
359
359
360
- /** A taint-tracking configuration for reasoning about tainted arguments. */
361
- private module TaintedArgConfig implements DataFlow:: ConfigSig {
362
- predicate isSource ( DataFlow:: Node src ) {
363
- src instanceof ActiveThreatModelSource or
364
- src instanceof ApiSourceNode or
365
- // for InlineFlowTest
366
- src .asExpr ( ) .( MethodCall ) .getMethod ( ) .getName ( ) = "source"
367
- }
368
-
369
- predicate isSink ( DataFlow:: Node sink ) {
370
- sink .asExpr ( ) =
371
- any ( ConstructorCall constrCall |
372
- constrCall .getConstructedType ( ) instanceof TypeFile and
373
- constrCall .getNumArgument ( ) = 2
374
- ) .getArgument ( 0 )
375
- }
376
- }
377
-
378
- /** Tracks taint flow to the parent argument of a `File` constructor. */
379
- private module TaintedArgFlow = TaintTracking:: Global< TaintedArgConfig > ;
380
-
381
360
/** Holds if `g` is a guard that checks for `..` components. */
382
361
private predicate pathTraversalGuard ( Guard g , Expr e , boolean branch ) {
383
362
// Local taint-flow is used here to handle cases where the validated expression comes from the
@@ -391,31 +370,27 @@ private predicate pathTraversalGuard(Guard g, Expr e, boolean branch) {
391
370
}
392
371
393
372
/**
394
- * A sanitizer that considers a `File` constructor safe if its second argument
395
- * is checked for `..` components (`PathTraversalGuard`) or if any internal
396
- * `..` components are removed from it (`PathNormalizeSanitizer`).
373
+ * A taint step from a child argument of a `java.io.File` constructor to the
374
+ * constructor call.
397
375
*
398
- * This also requires a check to ensure that the first argument of the
399
- * `File` constructor is not tainted.
376
+ * This step only applies if the argument is not guarded by a check for `..`
377
+ * components (`PathTraversalGuard`), or it does not have any internal `..`
378
+ * components removed from it (`PathNormalizeSanitizer`), or if the parent
379
+ * argument of the constructor may be null.
400
380
*/
401
- private class FileConstructorSanitizer extends PathInjectionSanitizer {
402
- FileConstructorSanitizer ( ) {
403
- exists ( ConstructorCall constrCall , Argument arg |
381
+ private class FileConstructorChildArgumentStep extends AdditionalTaintStep {
382
+ override predicate step ( DataFlow :: Node n1 , DataFlow :: Node n2 ) {
383
+ exists ( ConstructorCall constrCall |
404
384
constrCall .getConstructedType ( ) instanceof TypeFile and
405
- // Exclude cases where the parent argument is null since the
406
- // `java.io.File` documentation states that such cases are
407
- // treated as if invoking the single-argument `File` constructor.
408
- not maybeNull ( constrCall .getArgument ( 0 ) ) and
409
- // Since we are sanitizing the constructor call, we need to check
410
- // that the parent argument is not tainted.
411
- not TaintedArgFlow:: flowToExpr ( constrCall .getArgument ( 0 ) ) and
412
- arg = constrCall .getArgument ( 1 ) and
385
+ n1 .asExpr ( ) = constrCall .getArgument ( 1 ) and
386
+ n2 .asExpr ( ) = constrCall and
413
387
(
414
- arg = DataFlow:: BarrierGuard< pathTraversalGuard / 3 > :: getABarrierNode ( ) .asExpr ( ) or
415
- arg = ValidationMethod< pathTraversalGuard / 3 > :: getAValidatedNode ( ) .asExpr ( ) or
416
- TaintTracking:: localExprTaint ( any ( PathNormalizeSanitizer p ) , arg )
417
- ) and
418
- this .asExpr ( ) = constrCall
388
+ not n1 = DataFlow:: BarrierGuard< pathTraversalGuard / 3 > :: getABarrierNode ( ) and
389
+ not n1 = ValidationMethod< pathTraversalGuard / 3 > :: getAValidatedNode ( ) and
390
+ not TaintTracking:: localExprTaint ( any ( PathNormalizeSanitizer p ) , n1 .asExpr ( ) )
391
+ or
392
+ maybeNull ( constrCall .getArgument ( 0 ) )
393
+ )
419
394
)
420
395
}
421
396
}
0 commit comments