@@ -3,12 +3,12 @@ import semmle.code.java.dataflow.TaintTracking
33
44module DecompressionBomb {
55 newtype DecompressionState =
6- ZipFile ( ) or
76 Zip4j ( ) or
87 Inflator ( ) or
98 ApacheCommons ( ) or
109 XerialSnappy ( ) or
11- UtilZip ( )
10+ UtilZip ( ) or
11+ ZipFile ( )
1212
1313 /**
1414 * The Decompression bomb Sink
@@ -86,9 +86,6 @@ module XerialSnappy {
8686 * A method Access as a sink which responsible for reading bytes
8787 */
8888 MethodCall getAByteRead ( ) { result = this }
89-
90- // look at Zip4j comments for this method
91- predicate isControlledRead ( ) { none ( ) }
9289 }
9390
9491 class Sink extends DecompressionBomb:: Sink {
@@ -211,9 +208,6 @@ module ApacheCommons {
211208 * A method Access as a sink which responsible for reading bytes
212209 */
213210 MethodCall getAByteRead ( ) { result = this }
214-
215- // look at Zip4j comments for this method
216- predicate isControlledRead ( ) { none ( ) }
217211 }
218212
219213 class Sink extends DecompressionBomb:: Sink {
@@ -289,9 +283,6 @@ module ApacheCommons {
289283 * A method Access as a sink which responsible for reading bytes
290284 */
291285 MethodCall getAByteRead ( ) { result = this }
292-
293- // look at Zip4j comments for this method
294- predicate isControlledRead ( ) { none ( ) }
295286 }
296287
297288 class Sink extends DecompressionBomb:: Sink {
@@ -381,9 +372,6 @@ module ApacheCommons {
381372 * A method Access as a sink which responsible for reading bytes
382373 */
383374 MethodCall getAByteRead ( ) { result = this }
384-
385- // look at Zip4j comments for this method
386- predicate isControlledRead ( ) { none ( ) }
387375 }
388376
389377 class Sink extends DecompressionBomb:: Sink {
@@ -421,22 +409,6 @@ module Zip4j {
421409 * A method Access as a sink which responsible for reading bytes
422410 */
423411 MethodCall getAByteRead ( ) { result = this }
424-
425- // while ((readLen = zipInputStream.read(readBuffer)) != -1) {
426- // totallRead += readLen;
427- // if (totallRead > 1024 * 1024 * 4) {
428- // System.out.println("potential Bomb");
429- // break;
430- // }
431- // outputStream.write(readBuffer, 0, readLen);
432- // }
433- // TODO: I don't know why we can't reach totallRead with Local Tainting
434- // the same behaviour exists in golang
435- predicate isControlledRead ( ) {
436- exists ( ComparisonExpr i |
437- TaintTracking:: localExprTaint ( [ this , this .getArgument ( 2 ) ] , i .getAChildExpr * ( ) )
438- )
439- }
440412 }
441413
442414 class Sink extends DecompressionBomb:: Sink {
@@ -496,17 +468,13 @@ module CommonsIO {
496468 override predicate sink ( DataFlow:: Node sink , DecompressionBomb:: DecompressionState state ) {
497469 sink .asExpr ( ) = any ( IOUtils r ) .getArgument ( 0 ) and
498470 (
499- state instanceof DecompressionBomb:: ZipFile
500- or
501471 state instanceof DecompressionBomb:: Zip4j
502472 or
503473 state instanceof DecompressionBomb:: Inflator
504474 or
505475 state instanceof DecompressionBomb:: ApacheCommons
506476 or
507477 state instanceof DecompressionBomb:: XerialSnappy
508- or
509- state instanceof DecompressionBomb:: UtilZip
510478 )
511479 }
512480 }
@@ -540,9 +508,6 @@ module Zip {
540508 * A method Access as a sink which responsible for reading bytes
541509 */
542510 MethodCall getAByteRead ( ) { result = this }
543-
544- // look at Zip4j comments for this method
545- predicate isControlledRead ( ) { none ( ) }
546511 }
547512
548513 class ReadInputStreamSink extends DecompressionBomb:: Sink {
@@ -642,9 +607,6 @@ module Zip {
642607 * A method Access as a sink which responsible for reading bytes
643608 */
644609 MethodCall getAByteRead ( ) { result = this }
645-
646- // look at Zip4j comments for this method
647- predicate isControlledRead ( ) { none ( ) }
648610 }
649611
650612 class InflateSink extends DecompressionBomb:: Sink {
@@ -654,96 +616,48 @@ module Zip {
654616 }
655617 }
656618
657- /**
658- * A type that is responsible for `ZipFile` Class
659- */
660- class TypeZipFile extends RefType {
661- TypeZipFile ( ) { this .hasQualifiedName ( "java.util.zip" , "ZipFile" ) }
619+ class ZipFileSink extends DecompressionBomb:: Sink {
620+ override predicate sink ( DataFlow:: Node sink , DecompressionBomb:: DecompressionState state ) {
621+ exists ( MethodCall call |
622+ call .getCallee ( ) .getDeclaringType ( ) instanceof TypeZipFile and
623+ call .getCallee ( ) .hasName ( "getInputStream" ) and
624+ sink .asExpr ( ) = call
625+ ) and
626+ state instanceof DecompressionBomb:: ZipFile
627+ }
662628 }
663629
664630 /**
665- * Gets `n1` and `n2` which `ZipFile n2 = new ZipFile(n1);` or
666- * `InputStream n2 = zipFile.getInputStream(n1);` or `zipFile_As_n1.getInputStream(n2);`
631+ * Gets `n1` and `n2` which `InputStream n2 = zipFile.getInputStream(n1)`
667632 */
668633 private class ZipFileAdditionalTaintStep extends DecompressionBomb:: AdditionalStep {
669634 override predicate step (
670635 DataFlow:: Node n1 , DecompressionBomb:: DecompressionState stateFrom , DataFlow:: Node n2 ,
671636 DecompressionBomb:: DecompressionState stateTo
672637 ) {
673638 (
674- exists ( MethodCall ma |
675- ma .getReceiverType ( ) instanceof TypeZipFile and
676- ma = n2 .asExpr ( ) and
677- ma .getQualifier ( ) = n1 .asExpr ( ) and
678- ma .getCallee ( ) .hasName ( "getInputStream" )
639+ exists ( ConstructorCall call |
640+ call .getConstructedType ( ) instanceof TypeZipFile and
641+ n1 .asExpr ( ) = call .getAnArgument ( ) and
642+ n2 .asExpr ( ) = call
679643 )
680644 or
681- exists ( Call c |
682- c .getCallee ( ) .getDeclaringType ( ) instanceof TypeZipFile and
683- c .getArgument ( 0 ) = n1 .asExpr ( ) and
684- c = n2 .asExpr ( )
645+ exists ( MethodCall call |
646+ call .getCallee ( ) .getDeclaringType ( ) .hasQualifiedName ( "java.util.zip" , "ZipFile" ) and
647+ call .getCallee ( ) .hasName ( "getInputStream" ) and
648+ n1 .asExpr ( ) = call .getQualifier ( ) and
649+ n2 .asExpr ( ) = call
685650 )
686651 ) and
687652 stateFrom instanceof DecompressionBomb:: ZipFile and
688653 stateTo instanceof DecompressionBomb:: ZipFile
689654 }
690655 }
691- }
692-
693- /**
694- * Providing InputStream and it subClasses that mostly related to Sinks of ZipFile Type,
695- * we can do
696- */
697- module InputStream {
698- /**
699- * The Types that are responsible for `InputStream` Class and all classes that are child of InputStream Class
700- */
701- class TypeInputStream extends RefType {
702- TypeInputStream ( ) { this .getASupertype * ( ) .hasQualifiedName ( "java.io" , "InputStream" ) }
703- }
704-
705- /**
706- * The methods that read bytes and belong to `InputStream` Type and all Types that are child of InputStream Type
707- */
708- class Read extends MethodCall {
709- Read ( ) {
710- this .getReceiverType ( ) instanceof TypeInputStream and
711- this .getCallee ( ) .hasName ( [ "read" , "readNBytes" , "readAllBytes" ] )
712- }
713- }
714-
715- class ReadSink extends DecompressionBomb:: Sink {
716- override predicate sink ( DataFlow:: Node sink , DecompressionBomb:: DecompressionState state ) {
717- sink .asExpr ( ) = any ( Read r ) and state instanceof DecompressionBomb:: ZipFile
718- }
719- }
720656
721657 /**
722- * general additional taint steps for all inputStream and all Types that are child of inputStream
658+ * A type that is responsible for `ZipFile` Class
723659 */
724- private class InputStreamAdditionalTaintStep extends DecompressionBomb:: AdditionalStep {
725- override predicate step (
726- DataFlow:: Node n1 , DecompressionBomb:: DecompressionState stateFrom , DataFlow:: Node n2 ,
727- DecompressionBomb:: DecompressionState stateTo
728- ) {
729- exists ( Call call |
730- // Method calls
731- call .( MethodCall ) .getReceiverType ( ) = any ( TypeInputStream t ) and
732- call .getCallee ( ) .hasName ( [ "read" , "readNBytes" , "readAllBytes" ] ) and
733- call .getQualifier ( ) = n1 .asExpr ( ) and
734- call = n2 .asExpr ( )
735- ) and
736- stateFrom instanceof DecompressionBomb:: ZipFile and
737- stateTo instanceof DecompressionBomb:: ZipFile
738- or
739- exists ( Call call |
740- // Method calls
741- call .( ConstructorCall ) .getConstructedType ( ) .hasQualifiedName ( "java.util.zip" , "ZipFile" ) and
742- n1 .asExpr ( ) = call .getAnArgument ( ) and
743- n2 .asExpr ( ) = call
744- ) and
745- stateFrom instanceof DecompressionBomb:: ZipFile and
746- stateTo instanceof DecompressionBomb:: ZipFile
747- }
660+ class TypeZipFile extends RefType {
661+ TypeZipFile ( ) { this .hasQualifiedName ( "java.util.zip" , "ZipFile" ) }
748662 }
749663}
0 commit comments