4
4
* @kind path-problem
5
5
* @problem.severity error
6
6
* @security-severity 7.8
7
- * @precision medium
7
+ * @precision high
8
8
* @id py/user-controlled-file-decompression
9
9
* @tags security
10
10
* experimental
@@ -18,85 +18,13 @@ import semmle.python.ApiGraphs
18
18
import semmle.python.dataflow.new.RemoteFlowSources
19
19
import semmle.python.dataflow.new.internal.DataFlowPublic
20
20
21
- module PyZipFile {
22
- /**
23
- * ```python
24
- * zipfile.PyZipFile()
25
- */
26
- private API:: Node pyZipFileClass ( ) {
27
- result = API:: moduleImport ( "zipfile" ) .getMember ( "PyZipFile" )
28
- }
29
-
30
- /**
31
- * same as zipfileSinks
32
- */
33
- DataFlow:: Node isSink ( ) { result = sink ( pyZipFileClass ( ) ) .getACall ( ) }
34
-
35
- private API:: Node sink ( API:: Node pyZipFileClass ) {
36
- result = pyZipFileClass .getReturn ( ) .getMember ( [ "extractall" , "read" , "extract" , "testzip" ] )
37
- or
38
- result = pyZipFileClass .getReturn ( ) .getMember ( "open" ) and
39
- // only read mode is sink
40
- // mode can be set in open() argument or in PyZipFile instantiation argument
41
- (
42
- not exists (
43
- result
44
- .getACall ( )
45
- .getParameter ( 1 , "mode" )
46
- .getAValueReachingSink ( )
47
- .asExpr ( )
48
- .( StrConst )
49
- .getText ( )
50
- ) or
51
- result
52
- .getACall ( )
53
- .getParameter ( 1 , "mode" )
54
- .getAValueReachingSink ( )
55
- .asExpr ( )
56
- .( StrConst )
57
- .getText ( ) = "r"
58
- ) and
59
- (
60
- not exists (
61
- pyZipFileClass
62
- .getACall ( )
63
- .getParameter ( 1 , "mode" )
64
- .getAValueReachingSink ( )
65
- .asExpr ( )
66
- .( StrConst )
67
- .getText ( )
68
- ) or
69
- pyZipFileClass
70
- .getACall ( )
71
- .getParameter ( 1 , "mode" )
72
- .getAValueReachingSink ( )
73
- .asExpr ( )
74
- .( StrConst )
75
- .getText ( ) = "r"
76
- )
77
- }
78
-
79
- /**
80
- * Same as ZipFile
81
- * I made PyZipFile separated from ZipFile as in future this will be compatible
82
- * if anyone want to add new methods an sink to each object.
83
- */
84
- predicate isAdditionalTaintStep ( DataFlow:: Node nodeFrom , DataFlow:: Node nodeTo ) {
85
- exists ( API:: Node pyZipFileClass | pyZipFileClass = pyZipFileClass ( ) |
86
- nodeFrom = pyZipFileClass .getACall ( ) .getParameter ( 0 , "file" ) .asSink ( ) and
87
- nodeTo =
88
- [
89
- sink ( pyZipFileClass ) .getACall ( ) ,
90
- pyZipFileClass
91
- .getACall ( )
92
- .getReturn ( )
93
- .getMember ( [ "extractall" , "read" , "extract" , "testzip" ] )
94
- .getACall ( )
95
- ]
96
- )
97
- }
98
- }
99
-
21
+ // /**
22
+ // * Same as ZipFile
23
+ // * I can made PyZipFile separated from ZipFile
24
+ // * as in future this will be more compatible if it has more differences from ZipFile
25
+ // * and we can add new changes easier.
26
+ // */
27
+ // module PyZipFile { }
100
28
module Lzma {
101
29
private API:: Node lzmaClass ( ) {
102
30
result = API:: moduleImport ( "lzma" ) .getMember ( [ "LZMAFile" , "open" ] )
@@ -204,13 +132,18 @@ module Gzip {
204
132
}
205
133
206
134
module ZipFile {
207
- // more sinks file:///home/am/CodeQL-home/codeql-repo/python/ql/src/experimental/semmle/python/security/ZipSlip.qll
208
135
/**
209
136
* ```python
210
137
* zipfile.ZipFile()
211
138
* ```
212
139
*/
213
- private API:: Node zipFileClass ( ) { result = API:: moduleImport ( "zipfile" ) .getMember ( "ZipFile" ) }
140
+ private API:: Node zipFileClass ( ) {
141
+ result =
142
+ [
143
+ API:: moduleImport ( "zipfile" ) .getMember ( "ZipFile" ) ,
144
+ API:: moduleImport ( "zipfile" ) .getMember ( "PyZipFile" )
145
+ ]
146
+ }
214
147
215
148
/**
216
149
* ```python
0 commit comments