Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit cca78f3

Browse files
committed
Python: Move PamAuthorization to new dataflow API
1 parent dcd9608 commit cca78f3

3 files changed

Lines changed: 38 additions & 5 deletions

File tree

python/ql/lib/semmle/python/security/dataflow/PamAuthorizationQuery.qll

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,11 @@ import semmle.python.dataflow.new.TaintTracking
1212
import PamAuthorizationCustomizations::PamAuthorizationCustomizations
1313

1414
/**
15+
* DEPRECATED: Use `PamAuthorizationFlow` module instead.
16+
*
1517
* A taint-tracking configuration for detecting "PAM Authorization" vulnerabilities.
1618
*/
17-
class Configuration extends TaintTracking::Configuration {
19+
deprecated class Configuration extends TaintTracking::Configuration {
1820
Configuration() { this = "PamAuthorization" }
1921

2022
override predicate isSource(DataFlow::Node node) { node instanceof Source }
@@ -37,3 +39,28 @@ class Configuration extends TaintTracking::Configuration {
3739
exists(VulnPamAuthCall c | c.getArg(0) = node1 | node2 = c)
3840
}
3941
}
42+
43+
private module PamAuthorizationConfig implements DataFlow::ConfigSig {
44+
predicate isSource(DataFlow::Node source) { source instanceof Source }
45+
46+
predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
47+
48+
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
49+
// Models flow from a remotely supplied username field to a PAM `handle`.
50+
// `retval = pam_start(service, username, byref(conv), byref(handle))`
51+
exists(API::CallNode pamStart, DataFlow::Node handle, API::CallNode pointer |
52+
pointer = API::moduleImport("ctypes").getMember(["pointer", "byref"]).getACall() and
53+
pamStart = libPam().getMember("pam_start").getACall() and
54+
pointer = pamStart.getArg(3) and
55+
handle = pointer.getArg(0) and
56+
pamStart.getArg(1) = node1 and
57+
handle = node2
58+
)
59+
or
60+
// Flow from handle to the authenticate call in the final step
61+
exists(VulnPamAuthCall c | c.getArg(0) = node1 | node2 = c)
62+
}
63+
}
64+
65+
/** Global taint-tracking for detecting "PAM Authorization" vulnerabilities. */
66+
module PamAuthorizationFlow = TaintTracking::Global<PamAuthorizationConfig>;

python/ql/src/Security/CWE-285/PamAuthorization.ql

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@
1111
*/
1212

1313
import python
14-
import DataFlow::PathGraph
14+
import PamAuthorizationFlow::PathGraph
1515
import semmle.python.ApiGraphs
1616
import semmle.python.security.dataflow.PamAuthorizationQuery
1717

18-
from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink
19-
where config.hasFlowPath(source, sink)
18+
from PamAuthorizationFlow::PathNode source, PamAuthorizationFlow::PathNode sink
19+
where PamAuthorizationFlow::flowPath(source, sink)
2020
select sink.getNode(), source, sink,
2121
"This PAM authentication depends on a $@, and 'pam_acct_mgmt' is not called afterwards.",
2222
source.getNode(), "user-provided value"
Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,24 @@
11
edges
22
| pam_test.py:4:26:4:32 | ControlFlowNode for ImportMember | pam_test.py:4:26:4:32 | GSSA Variable request |
33
| pam_test.py:4:26:4:32 | GSSA Variable request | pam_test.py:71:16:71:22 | ControlFlowNode for request |
4-
| pam_test.py:71:5:71:12 | SSA variable username | pam_test.py:76:14:76:40 | ControlFlowNode for pam_authenticate() |
4+
| pam_test.py:71:5:71:12 | SSA variable username | pam_test.py:74:33:74:40 | ControlFlowNode for username |
55
| pam_test.py:71:16:71:22 | ControlFlowNode for request | pam_test.py:71:16:71:27 | ControlFlowNode for Attribute |
66
| pam_test.py:71:16:71:27 | ControlFlowNode for Attribute | pam_test.py:71:16:71:47 | ControlFlowNode for Attribute() |
77
| pam_test.py:71:16:71:47 | ControlFlowNode for Attribute() | pam_test.py:71:5:71:12 | SSA variable username |
8+
| pam_test.py:74:33:74:40 | ControlFlowNode for username | pam_test.py:74:62:74:67 | ControlFlowNode for handle |
9+
| pam_test.py:74:62:74:67 | ControlFlowNode for handle | pam_test.py:76:31:76:36 | ControlFlowNode for handle |
10+
| pam_test.py:76:31:76:36 | ControlFlowNode for handle | pam_test.py:76:14:76:40 | ControlFlowNode for pam_authenticate() |
811
nodes
912
| pam_test.py:4:26:4:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember |
1013
| pam_test.py:4:26:4:32 | GSSA Variable request | semmle.label | GSSA Variable request |
1114
| pam_test.py:71:5:71:12 | SSA variable username | semmle.label | SSA variable username |
1215
| pam_test.py:71:16:71:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
1316
| pam_test.py:71:16:71:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
1417
| pam_test.py:71:16:71:47 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
18+
| pam_test.py:74:33:74:40 | ControlFlowNode for username | semmle.label | ControlFlowNode for username |
19+
| pam_test.py:74:62:74:67 | ControlFlowNode for handle | semmle.label | ControlFlowNode for handle |
1520
| pam_test.py:76:14:76:40 | ControlFlowNode for pam_authenticate() | semmle.label | ControlFlowNode for pam_authenticate() |
21+
| pam_test.py:76:31:76:36 | ControlFlowNode for handle | semmle.label | ControlFlowNode for handle |
1622
subpaths
1723
#select
1824
| pam_test.py:76:14:76:40 | ControlFlowNode for pam_authenticate() | pam_test.py:4:26:4:32 | ControlFlowNode for ImportMember | pam_test.py:76:14:76:40 | ControlFlowNode for pam_authenticate() | This PAM authentication depends on a $@, and 'pam_acct_mgmt' is not called afterwards. | pam_test.py:4:26:4:32 | ControlFlowNode for ImportMember | user-provided value |

0 commit comments

Comments
 (0)