Skip to content

Commit 29ad3bf

Browse files
committed
C++: Test dataflow and other slightly more complex cases.
1 parent cd5a534 commit 29ad3bf

File tree

2 files changed

+90
-8
lines changed

2 files changed

+90
-8
lines changed
Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1-
| test3.cpp:39:3:39:6 | call to recv | test3.cpp:39:15:39:22 | password |
2-
| test3.cpp:47:3:47:6 | call to recv | test3.cpp:47:15:47:22 | password |
1+
| test3.cpp:41:3:41:6 | call to recv | test3.cpp:41:15:41:22 | password |
2+
| test3.cpp:49:3:49:6 | call to recv | test3.cpp:49:15:49:22 | password |
3+
| 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: 87 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11

22
typedef unsigned long size_t;
3+
#define STDIN_FILENO (0)
34

45
size_t strlen(const char *s);
56

6-
void send(int a, const void *buf, size_t bufLen, int d);
7-
void recv(int a, void *buf, size_t bufLen, int d);
7+
void send(int fd, const void *buf, size_t bufLen, int d);
8+
void recv(int fd, void *buf, size_t bufLen, int d);
9+
void read(int fd, void *buf, size_t bufLen);
810

911
void LogonUserA(int a, int b, const char *password, int d, int e, int f);
1012

@@ -13,17 +15,17 @@ int val();
1315
void test_send(const char *password1, const char *password2, const char *password_hash, const char *message)
1416
{
1517
{
16-
LogonUserA(val(), val(), password1, val(), val(), val()); // proof `password` is plaintext
18+
LogonUserA(val(), val(), password1, val(), val(), val()); // proof `password1` is plaintext
1719

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

2123
{
22-
send(val(), password2, strlen(password2), val()); // BAD: `password` is sent plaintext (probably) [NOT DETECTED]
24+
send(val(), password2, strlen(password2), val()); // BAD: `password2` is sent plaintext (probably) [NOT DETECTED]
2325
}
2426

2527
{
26-
send(val(), password_hash, strlen(password_hash), val()); // GOOD: `password` is sent encrypted
28+
send(val(), password_hash, strlen(password_hash), val()); // GOOD: `password_hash` is sent encrypted
2729
}
2830

2931
{
@@ -59,3 +61,82 @@ void test_receive()
5961
recv(val(), message, 256, val()); // GOOD: `message` is not a password
6062
}
6163
}
64+
65+
void test_dataflow(const char *password1)
66+
{
67+
{
68+
const char *ptr = password1;
69+
70+
send(val(), ptr, strlen(ptr), val()); // BAD: `password` is sent plaintext [NOT DETECTED]
71+
}
72+
73+
{
74+
char password[256];
75+
char *ptr = password;
76+
77+
recv(val(), ptr, 256, val()); // BAD: `password` is received plaintext
78+
}
79+
80+
{
81+
char buffer[256];
82+
83+
recv(val(), buffer, 256, val()); // BAD: `password` is received plaintext [NOT DETECTED]
84+
85+
char *password = buffer;
86+
}
87+
}
88+
89+
void test_read()
90+
{
91+
{
92+
char password[256];
93+
int fd = val();
94+
95+
read(fd, password, 256); // BAD: `password` is received plaintext [NOT DETECTED]
96+
}
97+
98+
{
99+
char password[256];
100+
int fd = STDIN_FILENO;
101+
102+
read(fd, password, 256); // GOOD: `password` is received from stdin, not a network socket
103+
}
104+
}
105+
106+
void my_recv(char *buffer, size_t bufferSize)
107+
{
108+
recv(val(), buffer, bufferSize, val());
109+
}
110+
111+
const char *id(const char *buffer)
112+
{
113+
return buffer;
114+
}
115+
116+
char *global_password;
117+
118+
char *get_global_str()
119+
{
120+
return global_password;
121+
}
122+
123+
void test_interprocedural(const char *password1)
124+
{
125+
{
126+
char password[256];
127+
128+
my_recv(password, 256); // BAD: `password` is received plaintext [NOT DETECTED]
129+
}
130+
131+
{
132+
const char *ptr = id(password1);
133+
134+
send(val(), ptr, strlen(ptr), val()); // BAD: `password1` is sent plaintext [NOT DETECTED]
135+
}
136+
137+
{
138+
char *data = get_global_str();
139+
140+
send(val(), data, strlen(data), val()); // BAD: `global_password` is sent plaintext [NOT DETECTED]
141+
}
142+
}

0 commit comments

Comments
 (0)