Pyhton: Extract vulnerable hostnames into own predicate

Which makes the code a bit cleaner (and made testing out back-tracking easier).
This commit is contained in:
Rasmus Wriedt Larsen
2021-02-25 13:18:48 +01:00
parent 4804a0a9f8
commit 99c1b2039c

View File

@@ -14,47 +14,50 @@ import python
import semmle.python.dataflow.new.DataFlow
import semmle.python.ApiGraphs
/** Gets a hostname that can be used to bind to all interfaces. */
private string vulnerableHostname() {
result in [
// IPv4
"0.0.0.0", "",
// IPv6
"::", "::0"
]
}
/** Gets a reference to a hostname that can be used to bind to all interfaces. */
private DataFlow::LocalSourceNode vulnerableHostname(DataFlow::TypeTracker t, string hostname) {
private DataFlow::LocalSourceNode vulnerableHostnameRef(DataFlow::TypeTracker t, string hostname) {
t.start() and
exists(StrConst allInterfacesStrConst |
hostname in [
// IPv4
"0.0.0.0", "",
// IPv6
"::", "::0"
]
|
exists(StrConst allInterfacesStrConst | hostname = vulnerableHostname() |
allInterfacesStrConst.getText() = hostname and
result.asExpr() = allInterfacesStrConst
)
or
// Due to bad performance when using normal setup with `vulnerableHostname(t2, hostname).track(t2, t)`
// Due to bad performance when using normal setup with `vulnerableHostnameRef(t2, hostname).track(t2, t)`
// we have inlined that code and forced a join
exists(DataFlow::TypeTracker t2 |
exists(DataFlow::StepSummary summary |
vulnerableHostname_first_join(t2, hostname, result, summary) and
vulnerableHostnameRef_first_join(t2, hostname, result, summary) and
t = t2.append(summary)
)
)
}
pragma[nomagic]
private predicate vulnerableHostname_first_join(
private predicate vulnerableHostnameRef_first_join(
DataFlow::TypeTracker t2, string hostname, DataFlow::Node res, DataFlow::StepSummary summary
) {
DataFlow::StepSummary::step(vulnerableHostname(t2, hostname), res, summary)
DataFlow::StepSummary::step(vulnerableHostnameRef(t2, hostname), res, summary)
}
/** Gets a reference to a hostname that can be used to bind to all interfaces. */
DataFlow::Node vulnerableHostname(string hostname) {
vulnerableHostname(DataFlow::TypeTracker::end(), hostname).flowsTo(result)
DataFlow::Node vulnerableHostnameRef(string hostname) {
vulnerableHostnameRef(DataFlow::TypeTracker::end(), hostname).flowsTo(result)
}
/** Gets a reference to tuple containing a hostname as the first element, that can be used to bind to all interfaces. */
private DataFlow::LocalSourceNode vulnerableAddressTuple(DataFlow::TypeTracker t, string hostname) {
t.start() and
result.asExpr() = any(Tuple tup | tup.getElt(0) = vulnerableHostname(hostname).asExpr())
result.asExpr() = any(Tuple tup | tup.getElt(0) = vulnerableHostnameRef(hostname).asExpr())
or
// Due to bad performance when using normal setup with `vulnerableAddressTuple(t2, hostname).track(t2, t)`
// we have inlined that code and forced a join