mirror of
https://github.com/github/codeql.git
synced 2026-05-04 21:25:44 +02:00
C++: Full dataflow version.
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
* @kind problem
|
||||
* @problem.severity warning
|
||||
* @security-severity 7.5 TODO
|
||||
* @precision high
|
||||
* @precision high TODO
|
||||
* @id cpp/cleartext-transmission
|
||||
* @tags security
|
||||
* external/cwe/cwe-319
|
||||
@@ -13,9 +13,7 @@
|
||||
|
||||
import cpp
|
||||
import semmle.code.cpp.security.SensitiveExprs
|
||||
import semmle.code.cpp.security.FileWrite
|
||||
import semmle.code.cpp.dataflow.DataFlow
|
||||
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
|
||||
|
||||
/**
|
||||
* A function call that sends or receives data over a network.
|
||||
@@ -65,10 +63,31 @@ class NetworkRecv extends NetworkSendRecv {
|
||||
override Expr getDataExpr() { result = this.getArgument(1) }
|
||||
}
|
||||
|
||||
from NetworkSendRecv transmission, SensitiveExpr e
|
||||
/**
|
||||
* Taint flow from a sensitive expression to a network operation with data
|
||||
* tainted by that expression.
|
||||
*/
|
||||
class SensitiveSendRecvConfiguration extends DataFlow::Configuration {
|
||||
SensitiveSendRecvConfiguration() { this = "SensitiveSendRecvConfiguration" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source.asExpr() instanceof SensitiveExpr }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) {
|
||||
exists(NetworkSendRecv transmission |
|
||||
sink.asExpr() = transmission.getDataExpr() and
|
||||
not exists(Zero zero |
|
||||
DataFlow::localFlow(DataFlow::exprNode(zero),
|
||||
DataFlow::exprNode(transmission.getSocketExpr()))
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
from SensitiveSendRecvConfiguration config1, Expr source, Expr sink
|
||||
where
|
||||
DataFlow::localFlow(DataFlow::exprNode(e), DataFlow::exprNode(transmission.getDataExpr())) and
|
||||
not exists(Zero zero |
|
||||
DataFlow::localFlow(DataFlow::exprNode(zero), DataFlow::exprNode(transmission.getSocketExpr()))
|
||||
exists(DataFlow::PathNode sourceNode, DataFlow::PathNode sinkNode |
|
||||
config1.hasFlowPath(sourceNode, sinkNode) and
|
||||
source = sourceNode.getNode().asExpr() and
|
||||
sink = sinkNode.getNode().asExpr()
|
||||
)
|
||||
select transmission, e
|
||||
select sink, source
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
| test3.cpp:20:3:20:6 | call to send | test3.cpp:20:15:20:23 | password1 |
|
||||
| test3.cpp:24:3:24:6 | call to send | test3.cpp:24:15:24:23 | password2 |
|
||||
| test3.cpp:41:3:41:6 | call to recv | test3.cpp:41:15:41:22 | password |
|
||||
| test3.cpp:49:3:49:6 | call to recv | test3.cpp:49:15:49:22 | password |
|
||||
| test3.cpp:70:3:70:6 | call to send | test3.cpp:68:21:68:29 | password1 |
|
||||
| test3.cpp:77:3:77:6 | call to recv | test3.cpp:75:15:75:22 | password |
|
||||
| test3.cpp:95:3:95:6 | call to read | test3.cpp:95:12:95:19 | password |
|
||||
| test3.cpp:20:15:20:23 | password1 | test3.cpp:20:15:20:23 | password1 |
|
||||
| test3.cpp:24:15:24:23 | password2 | test3.cpp:24:15:24:23 | password2 |
|
||||
| test3.cpp:41:15:41:22 | password | test3.cpp:41:15:41:22 | password |
|
||||
| test3.cpp:49:15:49:22 | password | test3.cpp:49:15:49:22 | password |
|
||||
| test3.cpp:70:15:70:17 | ptr | test3.cpp:68:21:68:29 | password1 |
|
||||
| test3.cpp:77:15:77:17 | ptr | test3.cpp:75:15:75:22 | password |
|
||||
| test3.cpp:95:12:95:19 | password | test3.cpp:95:12:95:19 | password |
|
||||
| test3.cpp:108:14:108:19 | buffer | test3.cpp:128:11:128:18 | password |
|
||||
| test3.cpp:134:15:134:17 | ptr | test3.cpp:132:24:132:32 | password1 |
|
||||
| test3.cpp:140:15:140:18 | data | test3.cpp:120:9:120:23 | global_password |
|
||||
|
||||
@@ -125,18 +125,18 @@ void test_interprocedural(const char *password1)
|
||||
{
|
||||
char password[256];
|
||||
|
||||
my_recv(password, 256); // BAD: `password` is received plaintext [NOT DETECTED]
|
||||
my_recv(password, 256); // BAD: `password` is received plaintext [detected on line 108]
|
||||
}
|
||||
|
||||
{
|
||||
const char *ptr = id(password1);
|
||||
|
||||
send(val(), ptr, strlen(ptr), val()); // BAD: `password1` is sent plaintext [NOT DETECTED]
|
||||
send(val(), ptr, strlen(ptr), val()); // BAD: `password1` is sent plaintext
|
||||
}
|
||||
|
||||
{
|
||||
char *data = get_global_str();
|
||||
|
||||
send(val(), data, strlen(data), val()); // BAD: `global_password` is sent plaintext [NOT DETECTED]
|
||||
send(val(), data, strlen(data), val()); // BAD: `global_password` is sent plaintext
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user