-
Notifications
You must be signed in to change notification settings - Fork 2k
Expand file tree
/
Copy pathBindToAllInterfaces.ql
More file actions
61 lines (53 loc) · 1.99 KB
/
BindToAllInterfaces.ql
File metadata and controls
61 lines (53 loc) · 1.99 KB
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
/**
* @name Binding a socket to all network interfaces
* @description Binding a socket to all interfaces opens it up to traffic from any IPv4 address
* and is therefore associated with security risks.
* @kind path-problem
* @tags security
* external/cwe/cwe-200
* @problem.severity error
* @security-severity 6.5
* @sub-severity low
* @precision high
* @id py/bind-socket-all-network-interfaces
*/
import python
import semmle.python.dataflow.new.DataFlow
import semmle.python.dataflow.new.TaintTracking
private import semmle.python.frameworks.data.ModelsAsData
import BindToAllInterfacesFlow::PathGraph
/** Gets a hostname that can be used to bind to all interfaces. */
private string vulnerableHostname() {
result in [
// IPv4
"0.0.0.0", "",
// IPv6
"::", "::0"
]
}
private module BindToAllInterfacesConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
source.asExpr().(StringLiteral).getText() = vulnerableHostname()
}
predicate isSink(DataFlow::Node sink) {
ModelOutput::sinkNode(sink, "bind-socket-all-interfaces")
}
}
private module BindToAllInterfacesFlow = TaintTracking::Global<BindToAllInterfacesConfig>;
private import BindToAllInterfacesFlow
/**
* Holds if `sink` is the address argument of a `bind()` call on a
* network socket (AF_INET or AF_INET6), as opposed to a Unix domain
* socket (AF_UNIX) which takes a plain string path.
*
* Network socket addresses are tuples like `(host, port)`, so we check
* that the sink argument is a tuple, by looking for flow from a tuple expression.
*/
private predicate isNetworkBind(DataFlow::Node sink) {
any(DataFlow::LocalSourceNode n | n.asExpr() instanceof Tuple).flowsTo(sink)
}
from PathNode source, PathNode sink
where flowPath(source, sink) and isNetworkBind(sink.getNode())
select sink.getNode(), source, sink,
"Binding a socket to all interfaces (using $@) is a security risk.", source.getNode(),
"'" + source.getNode().asExpr().(StringLiteral).getText() + "'"