44 * @kind path-problem
55 * @problem.severity error
66 * @security-severity 7.8
7- * @precision medium
7+ * @precision high
88 * @id py/user-controlled-file-decompression
99 * @tags security
1010 * experimental
@@ -18,85 +18,13 @@ import semmle.python.ApiGraphs
1818import semmle.python.dataflow.new.RemoteFlowSources
1919import semmle.python.dataflow.new.internal.DataFlowPublic
2020
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 { }
10028module Lzma {
10129 private API:: Node lzmaClass ( ) {
10230 result = API:: moduleImport ( "lzma" ) .getMember ( [ "LZMAFile" , "open" ] )
@@ -204,13 +132,18 @@ module Gzip {
204132}
205133
206134module ZipFile {
207- // more sinks file:///home/am/CodeQL-home/codeql-repo/python/ql/src/experimental/semmle/python/security/ZipSlip.qll
208135 /**
209136 * ```python
210137 * zipfile.ZipFile()
211138 * ```
212139 */
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+ }
214147
215148 /**
216149 * ```python
0 commit comments