Skip to content

Commit 1707d67

Browse files
committed
C++: Support 'send' as well.
1 parent 29ad3bf commit 1707d67

File tree

3 files changed

+32
-10
lines changed

3 files changed

+32
-10
lines changed

cpp/ql/src/Security/CWE/CWE-311/CleartextTransmission.ql

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,36 @@ import semmle.code.cpp.security.FileWrite
1717
import semmle.code.cpp.dataflow.DataFlow
1818
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
1919

20-
// TODO: network send?
20+
/**
21+
* A function call that sends or receives data over a network.
22+
*/
23+
abstract class NetworkSendRecv extends FunctionCall {
24+
/**
25+
* Gets the expression for the buffer to be sent from / received into.
26+
*/
27+
abstract Expr getDataExpr();
28+
}
29+
30+
/**
31+
* A function call that sends data over a network.
32+
*
33+
* note: functions such as `read` may be reading from a network source or a file. We could attempt to determine which, and sort results into `cpp/cleartext-transmission` and perhaps `cpp/cleartext-storage-file`. In practice it probably isn't very important which query reports a result as long as its reported exactly once.
34+
*/
35+
class NetworkSend extends NetworkSendRecv {
36+
NetworkSend() { this.getTarget().hasGlobalName("send") }
37+
38+
override Expr getDataExpr() { result = this.getArgument(1) }
39+
}
2140

2241
/**
23-
* TODO
42+
* A function call that receives data over a network.
2443
*/
25-
class NetworkRecv extends FunctionCall {
44+
class NetworkRecv extends NetworkSendRecv {
2645
NetworkRecv() { this.getTarget().hasGlobalName("recv") }
2746

28-
Expr getData() { result = this.getArgument(1) }
47+
override Expr getDataExpr() { result = this.getArgument(1) }
2948
}
3049

31-
from NetworkRecv recv, SensitiveExpr e
32-
where DataFlow::localFlow(DataFlow::exprNode(e), DataFlow::exprNode(recv.(NetworkRecv).getData()))
33-
select recv, e
50+
from NetworkSendRecv transmission, SensitiveExpr e
51+
where DataFlow::localFlow(DataFlow::exprNode(e), DataFlow::exprNode(transmission.getDataExpr()))
52+
select transmission, e
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
| test3.cpp:20:3:20:6 | call to send | test3.cpp:20:15:20:23 | password1 |
2+
| test3.cpp:24:3:24:6 | call to send | test3.cpp:24:15:24:23 | password2 |
13
| test3.cpp:41:3:41:6 | call to recv | test3.cpp:41:15:41:22 | password |
24
| test3.cpp:49:3:49:6 | call to recv | test3.cpp:49:15:49:22 | password |
5+
| test3.cpp:70:3:70:6 | call to send | test3.cpp:68:21:68:29 | password1 |
36
| test3.cpp:77:3:77:6 | call to recv | test3.cpp:75:15:75:22 | password |

cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/test3.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@ void test_send(const char *password1, const char *password2, const char *passwor
1717
{
1818
LogonUserA(val(), val(), password1, val(), val(), val()); // proof `password1` is plaintext
1919

20-
send(val(), password1, strlen(password1), val()); // BAD: `password1` is sent plaintext (certainly) [NOT DETECTED]
20+
send(val(), password1, strlen(password1), val()); // BAD: `password1` is sent plaintext (certainly)
2121
}
2222

2323
{
24-
send(val(), password2, strlen(password2), val()); // BAD: `password2` is sent plaintext (probably) [NOT DETECTED]
24+
send(val(), password2, strlen(password2), val()); // BAD: `password2` is sent plaintext (probably)
2525
}
2626

2727
{
@@ -67,7 +67,7 @@ void test_dataflow(const char *password1)
6767
{
6868
const char *ptr = password1;
6969

70-
send(val(), ptr, strlen(ptr), val()); // BAD: `password` is sent plaintext [NOT DETECTED]
70+
send(val(), ptr, strlen(ptr), val()); // BAD: `password` is sent plaintext
7171
}
7272

7373
{

0 commit comments

Comments
 (0)