-
Notifications
You must be signed in to change notification settings - Fork 247
/
05_DataFlow.ql
78 lines (68 loc) · 2.42 KB
/
05_DataFlow.ql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
/**
* @name Etherpad Reflected File Download CVE-2018-6835
* @description Returning an unsanitized string in a HTTP response
* could cause a Reflected File Download (RFD) vulnerability.
* @kind path-problem
* @problem.severity warning
* @id etherpad/javascript/rfd-cve-2018-6835
*/
import javascript
import semmle.javascript.security.dataflow.ReflectedXss::ReflectedXss
import DataFlow::PathGraph
/**
* A function with `req` and `res` parameters, and hence most likely an
* HTTP route handler.
*/
class LikelyRouteHandler extends DataFlow::FunctionNode {
DataFlow::ParameterNode req;
DataFlow::ParameterNode res;
LikelyRouteHandler() {
req = getParameter(0) and req.getName() = "req" and
res = getParameter(1) and res.getName() = "res"
}
DataFlow::ParameterNode getRequestParameter() {
result = req
}
/** Gets a method of `res` that sends an HTTP response. */
string getASendMethodName() {
// res.send
result = "send"
or
// or a method `m` such that there is an assignment `res.m = res.n` where `n`
// is already known to be a send method
exists (DataFlow::PropWrite pwn |
pwn = res.getAPropertyWrite(result) and
pwn.getRhs() = getASendMethodReference()
)
}
/** Gets a reference to `res.send` or some other known send method. */
DataFlow::PropRead getASendMethodReference() {
result = res.getAPropertyRead(getASendMethodName())
}
/** Gets a call to the send method. */
DataFlow::CallNode getASendMethodCall() {
result = getASendMethodReference().getACall()
}
}
/** An argument passed to `res.send`, marked as an XSS sink. */
class LikelySendArgument extends Sink {
LikelySendArgument() {
this = any(LikelyRouteHandler rh).getASendMethodCall().getAnArgument()
}
}
/** An access to a request parameter, marked as an XSS source. */
class LikelyRequestParameter extends Source, DataFlow::SourceNode {
LikelyRequestParameter() {
exists (DataFlow::SourceNode base | this = base.getAPropertyRead() |
// either a property access on `req` itself
base = any(LikelyRouteHandler rh).getRequestParameter()
or
// or a more deeply nested property access
base instanceof LikelyRequestParameter
)
}
}
// We are now ready to run the data flow analysis.
from Configuration xss, DataFlow::PathNode source, DataFlow::PathNode sink
where xss.hasFlowPath(source, sink)
select sink, source, sink, "Reflected File Download (RFD) vulnerability"