@@ -72,7 +72,10 @@ module DecompressionBombs {
7272 * `ZipEntry.extract`
7373 */
7474 class ZipSink extends DecompressionBombSink {
75- ZipSink ( ) { this = zipInputStream ( ) .getMethod ( [ "open" , "new" ] ) .getReturn ( ) .asSource ( ) }
75+ ZipSink ( ) {
76+ this = zipInputStream ( ) .getMethod ( [ "open" , "new" ] ) .getReturn ( ) .asSource ( ) and
77+ not this .getLocation ( ) .getFile ( ) .getBaseName ( ) .matches ( "%spec%" )
78+ }
7679 }
7780
7881 predicate isAdditionalTaintStep ( DataFlow:: Node nodeFrom , DataFlow:: Node nodeTo ) {
@@ -84,25 +87,18 @@ module DecompressionBombs {
8487 }
8588
8689 module ZipFile {
87- // // Because of additional step and ZipSink predicates, I couldn't use unary predicate
88- // // I put the explanation because I think there should be a soloution to not use other rubyZipNode predicate
89- // API::Node rubyZipNode() {
90- // result = zipFile() or
91- // result = rubyZipNode().getMethod(_).getReturn() or
92- // result = rubyZipNode().getMethod(_).getBlock().getParameter(_) or
93- // result = rubyZipNode().getMethod(_).getParameter(0) or
94- // result = rubyZipNode().getAnElement()
95- // }
96- API:: Node rubyZipNode ( API:: Node n ) {
97- result = n
90+ API:: Node rubyZipNode ( ) {
91+ result = zipFile ( )
92+ or
93+ result = rubyZipNode ( ) .getMethod ( _)
9894 or
99- result = rubyZipNode ( n ) . getMethod ( _ ) .getReturn ( )
95+ result = rubyZipNode ( ) .getReturn ( )
10096 or
101- result = rubyZipNode ( n ) . getMethod ( _ ) . getBlock ( ) .getParameter ( _)
97+ result = rubyZipNode ( ) .getParameter ( _)
10298 or
103- result = rubyZipNode ( n ) . getMethod ( _ ) . getParameter ( 0 )
99+ result = rubyZipNode ( ) . getAnElement ( )
104100 or
105- result = rubyZipNode ( n ) . getAnElement ( )
101+ result = rubyZipNode ( ) . getBlock ( )
106102 }
107103
108104 /**
@@ -113,26 +109,24 @@ module DecompressionBombs {
113109 */
114110 class ZipSink extends DecompressionBombSink {
115111 ZipSink ( ) {
116- exists ( API:: Node zipnodes | zipnodes = zipFile ( ) |
117- this = rubyZipNode ( zipnodes ) .getMethod ( [ "extract" , "read" ] ) .getReturn ( ) .asSource ( ) and
118- not exists (
119- rubyZipNode ( zipnodes ) .getMethod ( "size" ) .getReturn ( ) .getMethod ( ">" ) .getParameter ( 0 )
120- )
112+ exists ( API:: Node zipnodes | zipnodes = rubyZipNode ( ) |
113+ this = zipnodes .getMethod ( [ "extract" , "read" ] ) .getReturn ( ) .asSource ( ) and
114+ not exists ( zipnodes .getMethod ( "size" ) .getReturn ( ) .getMethod ( ">" ) .getParameter ( 0 ) )
121115 )
122116 }
123117 }
124118
125119 predicate isAdditionalTaintStep ( DataFlow:: Node nodeFrom , DataFlow:: Node nodeTo ) {
126- exists ( API:: Node zipnodes | zipnodes = zipFile ( ) |
127- nodeTo = rubyZipNode ( zipnodes ) .getMethod ( [ "extract" , "read" ] ) .getReturn ( ) .asSource ( ) and
120+ exists ( API:: Node zipnodes | zipnodes = rubyZipNode ( ) |
121+ nodeTo = zipnodes .getMethod ( [ "extract" , "read" ] ) .getReturn ( ) .asSource ( ) and
128122 nodeFrom = zipnodes .getMethod ( [ "new" , "open" ] ) .getParameter ( 0 ) .asSink ( )
129123 )
130124 }
131125
132126 /**
133127 * `Zip::File`
134128 */
135- private API:: Node zipFile ( ) { result = API:: getTopLevelMember ( "Zip" ) .getMember ( "File" ) }
129+ API:: Node zipFile ( ) { result = API:: getTopLevelCall ( "Zip" ) .getMember ( "File" ) }
136130 }
137131}
138132
@@ -148,9 +142,15 @@ class IoCopyStream extends DataFlow::CallNode {
148142class Bombs extends TaintTracking:: Configuration {
149143 Bombs ( ) { this = "Decompression Bombs" }
150144
145+ override predicate isSanitizer ( DataFlow:: Node node ) {
146+ not node .getLocation ( ) .hasLocationInfo ( "%spec%" , _, _, _, _)
147+ }
148+
151149 override predicate isSource ( DataFlow:: Node source ) {
152- source instanceof RemoteFlowSource or
153- source instanceof DataFlow:: LocalSourceNode
150+ source instanceof RemoteFlowSource
151+ // or
152+ // source instanceof DataFlow::LocalSourceNode
153+ // source = API::getTopLevelCall("Zip").getMember("InputStream").getASuccessor*()
154154 }
155155
156156 override predicate isSink ( DataFlow:: Node sink ) {
0 commit comments