@@ -45,7 +45,11 @@ module ZipSlip {
4545 */
4646 private class GzipReaderOpen extends Source {
4747 GzipReaderOpen ( ) {
48- this = API:: getTopLevelMember ( "Zlib" ) .getMember ( "GzipReader" ) .getReturn ( "open" ) .asSource ( ) and
48+ (
49+ this = API:: getTopLevelMember ( "Zlib" ) .getMember ( "GzipReader" ) .getReturn ( "open" ) .asSource ( )
50+ or
51+ this = API:: getTopLevelMember ( "Zlib" ) .getMember ( "GzipReader" ) .getInstance ( ) .asSource ( )
52+ ) and
4953 // If argument refers to a string object, then it's a hardcoded path and
5054 // this file is safe.
5155 not this .( DataFlow:: CallNode )
@@ -61,19 +65,17 @@ module ZipSlip {
6165 */
6266 private class TarReaderInstance extends Source {
6367 TarReaderInstance ( ) {
64- this =
65- API:: getTopLevelMember ( "Gem" )
66- .getMember ( "Package" )
67- .getMember ( "TarReader" )
68- .getInstance ( )
69- .asSource ( ) and
70- // If argument refers to a string object, then it's a hardcoded path and
71- // this file is safe.
72- not this .( DataFlow:: CallNode )
73- .getArgument ( 0 )
74- .getALocalSource ( )
75- .getConstantValue ( )
76- .isStringlikeValue ( _)
68+ exists ( API:: MethodAccessNode newTarReader |
69+ newTarReader =
70+ API:: getTopLevelMember ( "Gem" ) .getMember ( "Package" ) .getMember ( "TarReader" ) .getMethod ( "new" )
71+ |
72+ // Unlike in two other modules, there's no check for the constant path because TarReader class is called with an `io` object and not filepath.
73+ // This, of course, can be modeled but probably in the internal IO.qll file
74+ // For now, I'm leaving this prone to false-positives
75+ not exists ( newTarReader .getBlock ( ) ) and this = newTarReader .getReturn ( ) .asSource ( )
76+ or
77+ this = newTarReader .getBlock ( ) .getParameter ( 0 ) .asSource ( )
78+ )
7779 }
7880 }
7981
@@ -82,14 +84,23 @@ module ZipSlip {
8284 */
8385 private class ZipFileOpen extends Source {
8486 ZipFileOpen ( ) {
85- this = API:: getTopLevelMember ( "Zip" ) .getMember ( "File" ) .getReturn ( "open" ) .asSource ( ) and
86- // If argument refers to a string object, then it's a hardcoded path and
87- // this file is safe.
88- not this .( DataFlow:: CallNode )
89- .getArgument ( 0 )
90- .getALocalSource ( )
91- .getConstantValue ( )
92- .isStringlikeValue ( _)
87+ exists ( API:: MethodAccessNode zipOpen |
88+ zipOpen = API:: getTopLevelMember ( "Zip" ) .getMember ( "File" ) .getMethod ( "open" ) and
89+ // If argument refers to a string object, then it's a hardcoded path and
90+ // this file is safe.
91+ not zipOpen
92+ .getCallNode ( )
93+ .getArgument ( 0 )
94+ .getALocalSource ( )
95+ .getConstantValue ( )
96+ .isStringlikeValue ( _)
97+ |
98+ // the case with variable assignment `zip_file = Zip::File.open(path)`
99+ not exists ( zipOpen .getBlock ( ) ) and this = zipOpen .getReturn ( ) .asSource ( )
100+ or
101+ // the case with direct block`Zip::File.open(path) do |zip_file|` case
102+ this = zipOpen .getBlock ( ) .getParameter ( 0 ) .asSource ( )
103+ )
93104 }
94105 }
95106
0 commit comments