Files
codeql/python/ql/lib/semmle/python/security/dataflow/PamAuthorizationCustomizations.qll
Porcupiney Hairs db231a111c Python : Improve the PAM authentication bypass query
The current PAM auth bypass query which was contributed by me a few months back, alert on a vulenrable function but does not check if the function is actually function. This leads to a lot of fasle positives.

With this PR, I add a taint-tracking configuration to check if the username parameter can actually be supplied by an attacker.

This should bring the FP's significantly down.
2022-11-19 01:29:25 +05:30

62 lines
1.8 KiB
Plaintext

/**
* Provides default sources, sinks and sanitizers for detecting
* "PAM Authorization" vulnerabilities.
*/
import python
import semmle.python.ApiGraphs
import semmle.python.dataflow.new.TaintTracking
import semmle.python.dataflow.new.RemoteFlowSources
/**
* Provides default sources, sinks and sanitizers for detecting
* "PAM Authorization" vulnerabilities.
*/
module PamAuthorizationCustomizations {
/**
* Models a node corresponding to the `pam` library
*/
API::Node libPam() {
exists(API::CallNode findLibCall, API::CallNode cdllCall |
findLibCall =
API::moduleImport("ctypes").getMember("util").getMember("find_library").getACall() and
findLibCall.getParameter(0).getAValueReachingSink().asExpr().(StrConst).getText() = "pam" and
cdllCall = API::moduleImport("ctypes").getMember("CDLL").getACall() and
cdllCall.getParameter(0).getAValueReachingSink() = findLibCall
|
result = cdllCall.getReturn()
)
}
/**
* A data flow source for "PAM Authorization" vulnerabilities.
*/
abstract class Source extends DataFlow::Node { }
/**
* A data flow sink for "PAM Authorization" vulnerabilities.
*/
abstract class Sink extends DataFlow::Node { }
/**
* A source of remote user input, considered as a flow source.
*/
class RemoteFlowSourceAsSource extends Source, RemoteFlowSource { }
/**
* A vulnerable `pam_authenticate` call considered as a flow sink.
*/
class VulnPamAuthCall extends API::CallNode, Sink {
VulnPamAuthCall() {
exists(DataFlow::Node h |
this = libPam().getMember("pam_authenticate").getACall() and
h = this.getArg(0) and
not exists(API::CallNode acctMgmtCall |
acctMgmtCall = libPam().getMember("pam_acct_mgmt").getACall() and
DataFlow::localFlow(h, acctMgmtCall.getArg(0))
)
)
}
}
}