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.
This commit is contained in:
Porcupiney Hairs
2022-10-03 02:31:43 +05:30
committed by porcupineyhairs
parent a964325724
commit db231a111c
7 changed files with 158 additions and 27 deletions

View File

@@ -1,7 +1,7 @@
/**
* @name PAM authorization bypass due to incorrect usage
* @description Not using `pam_acct_mgmt` after `pam_authenticate` to check the validity of a login can lead to authorization bypass.
* @kind problem
* @kind path-problem
* @problem.severity warning
* @security-severity 8.1
* @precision high
@@ -11,28 +11,11 @@
*/
import python
import DataFlow::PathGraph
import semmle.python.ApiGraphs
import experimental.semmle.python.Concepts
import semmle.python.dataflow.new.TaintTracking
import semmle.python.security.dataflow.PamAuthorization::PamAuthorization
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()
)
}
from API::CallNode authenticateCall, DataFlow::Node handle
where
authenticateCall = libPam().getMember("pam_authenticate").getACall() and
handle = authenticateCall.getArg(0) and
not exists(API::CallNode acctMgmtCall |
acctMgmtCall = libPam().getMember("pam_acct_mgmt").getACall() and
DataFlow::localFlow(handle, acctMgmtCall.getArg(0))
)
select authenticateCall,
"This PAM authentication call may lead to an authorization bypass, since 'pam_acct_mgmt' is not called afterwards."
from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink
where config.hasFlowPath(source, sink)
select sink.getNode(), source, sink,
"This PAM authentication call may lead to an authorization bypass, since `pam_acct_mgmt` is not called afterwards."