mirror of
https://github.com/github/codeql.git
synced 2026-04-21 06:55:31 +02:00
Python: Add support for more URL redirect sanitisers.
Since some sanitisers don't handle backslashes correctly, I updated the data-flow configuration to incorporate a flow state tracking whether or not backslashes have been eliminated or converted to forward slashes.
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
private import python
|
||||
private import semmle.python.Concepts
|
||||
private import semmle.python.ApiGraphs
|
||||
private import semmle.python.security.dataflow.UrlRedirectCustomizations
|
||||
|
||||
/**
|
||||
* Provides models for the `urllib` module, part of
|
||||
@@ -70,4 +71,55 @@ private module Urllib {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides models for the `urllib.parse` extension library.
|
||||
*/
|
||||
module Parse {
|
||||
/**
|
||||
* A call to `urllib.parse.urlparse`.
|
||||
*/
|
||||
private DataFlow::CallCfgNode getUrlParseCall() {
|
||||
result = API::moduleImport("urllib").getMember("parse").getMember("urlparse").getACall()
|
||||
}
|
||||
|
||||
/**
|
||||
* A read of the `netloc` attribute of a parsed URL as returned by `urllib.parse.urlparse`,
|
||||
* which is being checked in a way that is relevant for URL redirection vulnerabilities.
|
||||
*/
|
||||
private predicate netlocCheck(DataFlow::GuardNode g, ControlFlowNode node, boolean branch) {
|
||||
exists(DataFlow::CallCfgNode urlParseCall, DataFlow::AttrRead netlocRead |
|
||||
urlParseCall = getUrlParseCall() and
|
||||
netlocRead = urlParseCall.getAnAttributeRead("netloc") and
|
||||
node = urlParseCall.getArg(0).asCfgNode()
|
||||
|
|
||||
// either a simple check of the netloc attribute
|
||||
g = netlocRead.asCfgNode() and
|
||||
branch = false
|
||||
or
|
||||
// or a comparison (we don't care against what)
|
||||
exists(Compare cmp, string op |
|
||||
cmp = g.getNode() and
|
||||
op = unique(Cmpop opp | opp = cmp.getAnOp()).getSymbol() and
|
||||
cmp.getASubExpression() = netlocRead.asExpr()
|
||||
|
|
||||
op in ["==", "is", "in"] and branch = true
|
||||
or
|
||||
op in ["!=", "is not", "not in"] and branch = false
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* A check of `urllib.parse.urlparse().netloc`, considered as a sanitizer-guard for URL redirection.
|
||||
*/
|
||||
private class NetlocCheck extends UrlRedirect::Sanitizer {
|
||||
NetlocCheck() { this = DataFlow::BarrierGuard<netlocCheck/3>::getABarrierNode() }
|
||||
|
||||
override predicate sanitizes(UrlRedirect::FlowState state) {
|
||||
// `urlparse` does not handle backslashes
|
||||
state instanceof UrlRedirect::NoBackslashes
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user