Skip to content

Commit 4376870

Browse files
committed
An uploded file is considered a source
1 parent 54109b8 commit 4376870

File tree

1 file changed

+75
-47
lines changed

1 file changed

+75
-47
lines changed

python/ql/src/experimental/Security/CWE-022bis/UnsafeUnpack.ql

Lines changed: 75 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,21 @@ class UnsafeUnpackingConfig extends TaintTracking::Configuration {
4343
exists(MethodCallNode mcn |
4444
mcn = API::moduleImport("wget").getMember("download").getACall() and source = mcn.getArg(1)
4545
)
46+
or
47+
// catch the uploaded files as a source
48+
exists(Subscript s, Attribute at |
49+
at = s.getObject() and at.getAttr() = "FILES" and source.asExpr() = s
50+
)
51+
or
52+
exists(Node obj, AttrRead ar |
53+
ar.getAMethodCall("get").flowsTo(source) and
54+
ar.accesses(obj, "FILES")
55+
)
56+
or
57+
exists(Node obj, AttrRead ar |
58+
ar.getAMethodCall("getlist").flowsTo(source) and
59+
ar.accesses(obj, "FILES")
60+
)
4661
}
4762

4863
override predicate isSink(DataFlow::Node sink) {
@@ -51,53 +66,66 @@ class UnsafeUnpackingConfig extends TaintTracking::Configuration {
5166
}
5267

5368
override predicate isAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
54-
(
55-
// Writing the response data to the archive
56-
exists(Stdlib::FileLikeObject::InstanceSource is, Node f, MethodCallNode mc |
57-
is.flowsTo(f) and
58-
mc.getMethodName() = "write" and
59-
f = mc.getObject() and
60-
nodeFrom = mc.getArg(0) and
61-
nodeTo = is.(CallCfgNode).getArg(0)
62-
)
63-
or
64-
// Copying the response data to the archive
65-
exists(Stdlib::FileLikeObject::InstanceSource is, Node f, MethodCallNode mc |
66-
is.flowsTo(f) and
67-
mc = API::moduleImport("shutil").getMember("copyfileobj").getACall() and
68-
f = mc.getArg(1) and
69-
nodeFrom = mc.getArg(0) and
70-
nodeTo = is.(CallCfgNode).getArg(0)
71-
)
72-
or
73-
// Reading the response
74-
exists(MethodCallNode mc |
75-
nodeFrom = mc.getObject() and
76-
mc.getMethodName() = "read" and
77-
mc.flowsTo(nodeTo)
78-
)
79-
or
80-
// Accessing the name or raw content
81-
exists(AttrRead ar | ar.accesses(nodeFrom, ["name", "raw"]) and ar.flowsTo(nodeTo))
82-
or
83-
//Use of join of filename
84-
exists(API::CallNode mcn |
85-
mcn = API::moduleImport("os").getMember("path").getMember("join").getACall() and
86-
nodeFrom = mcn.getArg(1) and
87-
mcn.flowsTo(nodeTo)
88-
)
89-
or
90-
// Read by chunks
91-
exists(MethodCallNode mc |
92-
nodeFrom = mc.getObject() and mc.getMethodName() = "chunks" and mc.flowsTo(nodeTo)
93-
)
94-
or
95-
// Considering the use of closing()
96-
exists(API::CallNode closing |
97-
closing = API::moduleImport("contextlib").getMember("closing").getACall() and
98-
closing.flowsTo(nodeTo) and
99-
nodeFrom = closing.getArg(0)
100-
)
69+
// Writing the response data to the archive
70+
exists(Stdlib::FileLikeObject::InstanceSource is, Node f, MethodCallNode mc |
71+
is.flowsTo(f) and
72+
mc.getMethodName() = "write" and
73+
f = mc.getObject() and
74+
nodeFrom = mc.getArg(0) and
75+
nodeTo = is.(CallCfgNode).getArg(0)
76+
)
77+
or
78+
// Copying the response data to the archive
79+
exists(Stdlib::FileLikeObject::InstanceSource is, Node f, MethodCallNode mc |
80+
is.flowsTo(f) and
81+
mc = API::moduleImport("shutil").getMember("copyfileobj").getACall() and
82+
f = mc.getArg(1) and
83+
nodeFrom = mc.getArg(0) and
84+
nodeTo = is.(CallCfgNode).getArg(0)
85+
)
86+
or
87+
// Reading the response
88+
exists(MethodCallNode mc |
89+
nodeFrom = mc.getObject() and
90+
mc.getMethodName() = "read" and
91+
mc.flowsTo(nodeTo)
92+
)
93+
or
94+
// Accessing the name or raw content
95+
exists(AttrRead ar | ar.accesses(nodeFrom, ["name", "raw"]) and ar.flowsTo(nodeTo))
96+
or
97+
//Use of join of filename
98+
exists(API::CallNode mcn |
99+
mcn = API::moduleImport("os").getMember("path").getMember("join").getACall() and
100+
nodeFrom = mcn.getArg(1) and
101+
mcn.flowsTo(nodeTo)
102+
)
103+
or
104+
// Read by chunks
105+
exists(MethodCallNode mc |
106+
nodeFrom = mc.getObject() and mc.getMethodName() = "chunks" and mc.flowsTo(nodeTo)
107+
)
108+
or
109+
// Considering the use of closing()
110+
exists(API::CallNode closing |
111+
closing = API::moduleImport("contextlib").getMember("closing").getACall() and
112+
closing.flowsTo(nodeTo) and
113+
nodeFrom = closing.getArg(0)
114+
)
115+
or
116+
// Considering the use of "fs"
117+
exists(API::CallNode fs, MethodCallNode mcn |
118+
fs =
119+
API::moduleImport("django")
120+
.getMember("core")
121+
.getMember("files")
122+
.getMember("storage")
123+
.getMember("FileSystemStorage")
124+
.getACall() and
125+
fs.flowsTo(mcn.getObject()) and
126+
mcn.getMethodName() = ["save", "path"] and
127+
nodeFrom = mcn.getArg(0) and
128+
nodeTo = mcn
101129
)
102130
}
103131
}

0 commit comments

Comments
 (0)