@@ -45,7 +45,11 @@ module ZipSlip {
45
45
*/
46
46
private class GzipReaderOpen extends Source {
47
47
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
49
53
// If argument refers to a string object, then it's a hardcoded path and
50
54
// this file is safe.
51
55
not this .( DataFlow:: CallNode )
@@ -61,19 +65,17 @@ module ZipSlip {
61
65
*/
62
66
private class TarReaderInstance extends Source {
63
67
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
+ )
77
79
}
78
80
}
79
81
@@ -82,14 +84,23 @@ module ZipSlip {
82
84
*/
83
85
private class ZipFileOpen extends Source {
84
86
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
+ )
93
104
}
94
105
}
95
106
0 commit comments