Skip to content

Commit b506b7d

Browse files
committed
better documents, remove separate PyZipFile
1 parent a38405e commit b506b7d

File tree

1 file changed

+15
-82
lines changed

1 file changed

+15
-82
lines changed

python/ql/src/experimental/Security/CWE-409/DecompressionBombs.ql

Lines changed: 15 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
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
1818
import semmle.python.dataflow.new.RemoteFlowSources
1919
import 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 { }
10028
module Lzma {
10129
private API::Node lzmaClass() {
10230
result = API::moduleImport("lzma").getMember(["LZMAFile", "open"])
@@ -204,13 +132,18 @@ module Gzip {
204132
}
205133

206134
module 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

Comments
 (0)