Merge pull request #6713 from geoffw0/cwe139

C++: New query for 'Cleartext transmission of sensitive information'
This commit is contained in:
Mathias Vorreiter Pedersen
2021-10-01 11:10:36 +02:00
committed by GitHub
10 changed files with 353 additions and 1 deletions

View File

@@ -0,0 +1,49 @@
edges
| test3.cpp:68:21:68:29 | password1 | test3.cpp:70:15:70:17 | ptr |
| test3.cpp:75:15:75:22 | password | test3.cpp:77:15:77:17 | ptr |
| test3.cpp:106:20:106:25 | buffer | test3.cpp:108:14:108:19 | buffer |
| test3.cpp:111:28:111:33 | buffer | test3.cpp:113:9:113:14 | buffer |
| test3.cpp:120:9:120:23 | global_password | test3.cpp:138:16:138:29 | call to get_global_str |
| test3.cpp:128:11:128:18 | password | test3.cpp:106:20:106:25 | buffer |
| test3.cpp:132:21:132:22 | call to id | test3.cpp:134:15:134:17 | ptr |
| test3.cpp:132:24:132:32 | password1 | test3.cpp:111:28:111:33 | buffer |
| test3.cpp:132:24:132:32 | password1 | test3.cpp:132:21:132:22 | call to id |
| test3.cpp:138:16:138:29 | call to get_global_str | test3.cpp:140:15:140:18 | data |
| test3.cpp:151:19:151:26 | password | test3.cpp:153:15:153:20 | buffer |
nodes
| test3.cpp:20:15:20:23 | password1 | semmle.label | password1 |
| test3.cpp:24:15:24:23 | password2 | semmle.label | password2 |
| test3.cpp:41:15:41:22 | password | semmle.label | password |
| test3.cpp:49:15:49:22 | password | semmle.label | password |
| test3.cpp:68:21:68:29 | password1 | semmle.label | password1 |
| test3.cpp:70:15:70:17 | ptr | semmle.label | ptr |
| test3.cpp:75:15:75:22 | password | semmle.label | password |
| test3.cpp:77:15:77:17 | ptr | semmle.label | ptr |
| test3.cpp:95:12:95:19 | password | semmle.label | password |
| test3.cpp:106:20:106:25 | buffer | semmle.label | buffer |
| test3.cpp:108:14:108:19 | buffer | semmle.label | buffer |
| test3.cpp:111:28:111:33 | buffer | semmle.label | buffer |
| test3.cpp:113:9:113:14 | buffer | semmle.label | buffer |
| test3.cpp:120:9:120:23 | global_password | semmle.label | global_password |
| test3.cpp:128:11:128:18 | password | semmle.label | password |
| test3.cpp:132:21:132:22 | call to id | semmle.label | call to id |
| test3.cpp:132:24:132:32 | password1 | semmle.label | password1 |
| test3.cpp:134:15:134:17 | ptr | semmle.label | ptr |
| test3.cpp:138:16:138:29 | call to get_global_str | semmle.label | call to get_global_str |
| test3.cpp:140:15:140:18 | data | semmle.label | data |
| test3.cpp:151:19:151:26 | password | semmle.label | password |
| test3.cpp:153:15:153:20 | buffer | semmle.label | buffer |
subpaths
| test3.cpp:132:24:132:32 | password1 | test3.cpp:111:28:111:33 | buffer | test3.cpp:113:9:113:14 | buffer | test3.cpp:132:21:132:22 | call to id |
#select
| test3.cpp:20:3:20:6 | call to send | test3.cpp:20:15:20:23 | password1 | test3.cpp:20:15:20:23 | password1 | This operation transmits 'password1', which may contain unencrypted sensitive data from $@ | test3.cpp:20:15:20:23 | password1 | password1 |
| test3.cpp:24:3:24:6 | call to send | test3.cpp:24:15:24:23 | password2 | test3.cpp:24:15:24:23 | password2 | This operation transmits 'password2', which may contain unencrypted sensitive data from $@ | test3.cpp:24:15:24:23 | password2 | password2 |
| test3.cpp:41:3:41:6 | call to recv | test3.cpp:41:15:41:22 | password | test3.cpp:41:15:41:22 | password | This operation receives into 'password', which may put unencrypted sensitive data into $@ | test3.cpp:41:15:41:22 | password | password |
| test3.cpp:49:3:49:6 | call to recv | test3.cpp:49:15:49:22 | password | test3.cpp:49:15:49:22 | password | This operation receives into 'password', which may put unencrypted sensitive data into $@ | test3.cpp:49:15:49:22 | password | password |
| test3.cpp:70:3:70:6 | call to send | test3.cpp:68:21:68:29 | password1 | test3.cpp:70:15:70:17 | ptr | This operation transmits 'ptr', which may contain unencrypted sensitive data from $@ | test3.cpp:68:21:68:29 | password1 | password1 |
| test3.cpp:77:3:77:6 | call to recv | test3.cpp:75:15:75:22 | password | test3.cpp:77:15:77:17 | ptr | This operation receives into 'ptr', which may put unencrypted sensitive data into $@ | test3.cpp:75:15:75:22 | password | password |
| test3.cpp:95:3:95:6 | call to read | test3.cpp:95:12:95:19 | password | test3.cpp:95:12:95:19 | password | This operation receives into 'password', which may put unencrypted sensitive data into $@ | test3.cpp:95:12:95:19 | password | password |
| test3.cpp:108:2:108:5 | call to recv | test3.cpp:128:11:128:18 | password | test3.cpp:108:14:108:19 | buffer | This operation receives into 'buffer', which may put unencrypted sensitive data into $@ | test3.cpp:128:11:128:18 | password | password |
| test3.cpp:134:3:134:6 | call to send | test3.cpp:132:24:132:32 | password1 | test3.cpp:134:15:134:17 | ptr | This operation transmits 'ptr', which may contain unencrypted sensitive data from $@ | test3.cpp:132:24:132:32 | password1 | password1 |
| test3.cpp:140:3:140:6 | call to send | test3.cpp:120:9:120:23 | global_password | test3.cpp:140:15:140:18 | data | This operation transmits 'data', which may contain unencrypted sensitive data from $@ | test3.cpp:120:9:120:23 | global_password | global_password |
| test3.cpp:153:3:153:6 | call to send | test3.cpp:151:19:151:26 | password | test3.cpp:153:15:153:20 | buffer | This operation transmits 'buffer', which may contain unencrypted sensitive data from $@ | test3.cpp:151:19:151:26 | password | password |

View File

@@ -0,0 +1 @@
Security/CWE/CWE-311/CleartextTransmission.ql

View File

@@ -0,0 +1,155 @@
typedef unsigned long size_t;
#define STDIN_FILENO (0)
size_t strlen(const char *s);
void send(int fd, const void *buf, size_t bufLen, int d);
void recv(int fd, void *buf, size_t bufLen, int d);
void read(int fd, void *buf, size_t bufLen);
void LogonUserA(int a, int b, const char *password, int d, int e, int f);
int val();
void test_send(const char *password1, const char *password2, const char *password_hash, const char *message)
{
{
LogonUserA(val(), val(), password1, val(), val(), val()); // proof `password1` is plaintext
send(val(), password1, strlen(password1), val()); // BAD: `password1` is sent plaintext (certainly)
}
{
send(val(), password2, strlen(password2), val()); // BAD: `password2` is sent plaintext (probably)
}
{
send(val(), password_hash, strlen(password_hash), val()); // GOOD: `password_hash` is sent encrypted
}
{
send(val(), message, strlen(message), val()); // GOOD: `message` is not a password
}
}
void test_receive()
{
{
char password[256];
recv(val(), password, 256, val()); // BAD: `password` is received plaintext (certainly)
LogonUserA(val(), val(), password, val(), val(), val()); // (proof `password` is plaintext)
}
{
char password[256];
recv(val(), password, 256, val()); // BAD: `password` is received plaintext (probably)
}
{
char password_hash[256];
recv(val(), password_hash, 256, val()); // GOOD: `password` is received encrypted
}
{
char message[256];
recv(val(), message, 256, val()); // GOOD: `message` is not a password
}
}
void test_dataflow(const char *password1)
{
{
const char *ptr = password1;
send(val(), ptr, strlen(ptr), val()); // BAD: `password` is sent plaintext
}
{
char password[256];
char *ptr = password;
recv(val(), ptr, 256, val()); // BAD: `password` is received plaintext
}
{
char buffer[256];
recv(val(), buffer, 256, val()); // BAD: `password` is received plaintext [NOT DETECTED]
char *password = buffer;
}
}
void test_read()
{
{
char password[256];
int fd = val();
read(fd, password, 256); // BAD: `password` is received plaintext
}
{
char password[256];
int fd = STDIN_FILENO;
read(fd, password, 256); // GOOD: `password` is received from stdin, not a network socket
}
}
void my_recv(char *buffer, size_t bufferSize)
{
recv(val(), buffer, bufferSize, val());
}
const char *id(const char *buffer)
{
return buffer;
}
char *global_password;
char *get_global_str()
{
return global_password;
}
void test_interprocedural(const char *password1)
{
{
char password[256];
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
}
{
char *data = get_global_str();
send(val(), data, strlen(data), val()); // BAD: `global_password` is sent plaintext
}
}
char *strncpy(char *s1, const char *s2, size_t n);
void test_taint(const char *password)
{
{
char buffer[16];
strncpy(buffer, password, 16);
buffer[15] = 0;
send(val(), buffer, 16, val()); // BAD: `password` is (partially) sent plaintext
}
}