Skip to content

Commit 620bdf1

Browse files
committed
C++: Add some tests. The missing result is from the fact that we block flow on all integral types (which includes char-like types). Also add some MaD pretty-printing.
1 parent eb60024 commit 620bdf1

3 files changed

Lines changed: 94 additions & 17 deletions

File tree

‎cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/CleartextFileWrite.expected‎

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,30 @@
1+
#select
2+
| test2.cpp:43:2:43:8 | call to fprintf | test2.cpp:43:36:43:43 | password | test2.cpp:43:36:43:43 | password | This write into file 'log' may contain unencrypted data from $@. | test2.cpp:43:36:43:43 | password | this source. |
3+
| test2.cpp:44:2:44:8 | call to fprintf | test2.cpp:44:37:44:45 | thepasswd | test2.cpp:44:37:44:45 | thepasswd | This write into file 'log' may contain unencrypted data from $@. | test2.cpp:44:37:44:45 | thepasswd | this source. |
4+
| test2.cpp:45:2:45:8 | call to fprintf | test2.cpp:45:38:45:47 | accountkey | test2.cpp:45:38:45:47 | accountkey | This write into file 'log' may contain unencrypted data from $@. | test2.cpp:45:38:45:47 | accountkey | this source. |
5+
| test2.cpp:50:2:50:8 | call to fprintf | test2.cpp:50:41:50:53 | passwd_config | test2.cpp:50:41:50:53 | passwd_config | This write into file 'log' may contain unencrypted data from $@. | test2.cpp:50:41:50:53 | passwd_config | this source. |
6+
| test2.cpp:54:2:54:8 | call to fprintf | test2.cpp:54:41:54:52 | widepassword | test2.cpp:54:41:54:52 | widepassword | This write into file 'log' may contain unencrypted data from $@. | test2.cpp:54:41:54:52 | widepassword | this source. |
7+
| test2.cpp:55:2:55:8 | call to fprintf | test2.cpp:55:40:55:51 | widepassword | test2.cpp:55:40:55:51 | widepassword | This write into file 'log' may contain unencrypted data from $@. | test2.cpp:55:40:55:51 | widepassword | this source. |
8+
| test2.cpp:57:2:57:8 | call to fprintf | test2.cpp:57:39:57:49 | call to getPassword | test2.cpp:57:39:57:49 | call to getPassword | This write into file 'log' may contain unencrypted data from $@. | test2.cpp:57:39:57:49 | call to getPassword | this source. |
9+
| test2.cpp:65:3:65:9 | call to fprintf | test2.cpp:62:18:62:25 | password | test2.cpp:65:31:65:34 | cpy1 | This write into file 'log' may contain unencrypted data from $@. | test2.cpp:62:18:62:25 | password | this source. |
10+
| test2.cpp:73:3:73:9 | call to fprintf | test2.cpp:72:15:72:24 | password | test2.cpp:73:30:73:32 | *buf | This write into file 'log' may contain unencrypted data from $@. | test2.cpp:72:17:72:24 | password | this source. |
11+
| test2.cpp:99:3:99:9 | call to fprintf | test2.cpp:98:45:98:52 | password | test2.cpp:99:27:99:32 | *buffer | This write into file 'log' may contain unencrypted data from $@. | test2.cpp:98:45:98:52 | password | this source. |
12+
| test2.cpp:154:2:154:8 | call to fprintf | test2.cpp:153:31:153:38 | password | test2.cpp:154:21:154:22 | *pw | This write into file 'log' may contain unencrypted data from $@. | test2.cpp:153:31:153:38 | password | this source. |
13+
| test2.cpp:174:2:174:8 | call to fprintf | test2.cpp:173:28:173:35 | password | test2.cpp:174:26:174:30 | *call to c_str | This write into file 'log' may contain unencrypted data from $@. | test2.cpp:173:28:173:35 | password | this source. |
14+
| test.cpp:45:3:45:7 | call to fputs | test.cpp:45:9:45:19 | thePassword | test.cpp:45:9:45:19 | thePassword | This write into file 'file' may contain unencrypted data from $@. | test.cpp:45:9:45:19 | thePassword | this source. |
15+
| test.cpp:70:35:70:35 | call to operator<< | test.cpp:70:38:70:48 | thePassword | test.cpp:70:38:70:48 | thePassword | This write into file 'mystream' may contain unencrypted data from $@. | test.cpp:70:38:70:48 | thePassword | this source. |
16+
| test.cpp:73:37:73:41 | call to write | test.cpp:70:38:70:48 | thePassword | test.cpp:73:43:73:53 | thePassword | This write into file 'mystream' may contain unencrypted data from $@. | test.cpp:70:38:70:48 | thePassword | this source. |
17+
| test.cpp:73:37:73:41 | call to write | test.cpp:73:43:73:53 | thePassword | test.cpp:73:43:73:53 | thePassword | This write into file 'mystream' may contain unencrypted data from $@. | test.cpp:73:43:73:53 | thePassword | this source. |
18+
| test.cpp:73:37:73:41 | call to write | test.cpp:73:63:73:73 | thePassword | test.cpp:73:43:73:53 | thePassword | This write into file 'mystream' may contain unencrypted data from $@. | test.cpp:73:63:73:73 | thePassword | this source. |
119
edges
220
| test2.cpp:62:18:62:25 | password | test2.cpp:62:18:62:25 | password | provenance | |
321
| test2.cpp:62:18:62:25 | password | test2.cpp:65:31:65:34 | cpy1 | provenance | |
422
| test2.cpp:72:15:72:24 | password | test2.cpp:73:30:73:32 | *buf | provenance | DataFlowFunction |
523
| test2.cpp:98:45:98:52 | password | test2.cpp:99:27:99:32 | *buffer | provenance | TaintFunction |
24+
| test2.cpp:153:31:153:38 | password | test2.cpp:153:40:153:44 | *call to c_str | provenance | TaintFunction |
25+
| test2.cpp:153:40:153:44 | *call to c_str | test2.cpp:154:21:154:22 | *pw | provenance | |
26+
| test2.cpp:173:28:173:35 | password | test2.cpp:173:28:173:35 | password | provenance | |
27+
| test2.cpp:173:28:173:35 | password | test2.cpp:174:26:174:30 | *call to c_str | provenance | TaintFunction |
628
| test.cpp:70:38:70:48 | thePassword | test.cpp:73:43:73:53 | thePassword | provenance | |
729
| test.cpp:73:63:73:73 | thePassword | test.cpp:73:43:73:53 | thePassword | provenance | |
830
nodes
@@ -20,25 +42,15 @@ nodes
2042
| test2.cpp:73:30:73:32 | *buf | semmle.label | *buf |
2143
| test2.cpp:98:45:98:52 | password | semmle.label | password |
2244
| test2.cpp:99:27:99:32 | *buffer | semmle.label | *buffer |
45+
| test2.cpp:153:31:153:38 | password | semmle.label | password |
46+
| test2.cpp:153:40:153:44 | *call to c_str | semmle.label | *call to c_str |
47+
| test2.cpp:154:21:154:22 | *pw | semmle.label | *pw |
48+
| test2.cpp:173:28:173:35 | password | semmle.label | password |
49+
| test2.cpp:173:28:173:35 | password | semmle.label | password |
50+
| test2.cpp:174:26:174:30 | *call to c_str | semmle.label | *call to c_str |
2351
| test.cpp:45:9:45:19 | thePassword | semmle.label | thePassword |
2452
| test.cpp:70:38:70:48 | thePassword | semmle.label | thePassword |
2553
| test.cpp:70:38:70:48 | thePassword | semmle.label | thePassword |
2654
| test.cpp:73:43:73:53 | thePassword | semmle.label | thePassword |
2755
| test.cpp:73:63:73:73 | thePassword | semmle.label | thePassword |
2856
subpaths
29-
#select
30-
| test2.cpp:43:2:43:8 | call to fprintf | test2.cpp:43:36:43:43 | password | test2.cpp:43:36:43:43 | password | This write into file 'log' may contain unencrypted data from $@. | test2.cpp:43:36:43:43 | password | this source. |
31-
| test2.cpp:44:2:44:8 | call to fprintf | test2.cpp:44:37:44:45 | thepasswd | test2.cpp:44:37:44:45 | thepasswd | This write into file 'log' may contain unencrypted data from $@. | test2.cpp:44:37:44:45 | thepasswd | this source. |
32-
| test2.cpp:45:2:45:8 | call to fprintf | test2.cpp:45:38:45:47 | accountkey | test2.cpp:45:38:45:47 | accountkey | This write into file 'log' may contain unencrypted data from $@. | test2.cpp:45:38:45:47 | accountkey | this source. |
33-
| test2.cpp:50:2:50:8 | call to fprintf | test2.cpp:50:41:50:53 | passwd_config | test2.cpp:50:41:50:53 | passwd_config | This write into file 'log' may contain unencrypted data from $@. | test2.cpp:50:41:50:53 | passwd_config | this source. |
34-
| test2.cpp:54:2:54:8 | call to fprintf | test2.cpp:54:41:54:52 | widepassword | test2.cpp:54:41:54:52 | widepassword | This write into file 'log' may contain unencrypted data from $@. | test2.cpp:54:41:54:52 | widepassword | this source. |
35-
| test2.cpp:55:2:55:8 | call to fprintf | test2.cpp:55:40:55:51 | widepassword | test2.cpp:55:40:55:51 | widepassword | This write into file 'log' may contain unencrypted data from $@. | test2.cpp:55:40:55:51 | widepassword | this source. |
36-
| test2.cpp:57:2:57:8 | call to fprintf | test2.cpp:57:39:57:49 | call to getPassword | test2.cpp:57:39:57:49 | call to getPassword | This write into file 'log' may contain unencrypted data from $@. | test2.cpp:57:39:57:49 | call to getPassword | this source. |
37-
| test2.cpp:65:3:65:9 | call to fprintf | test2.cpp:62:18:62:25 | password | test2.cpp:65:31:65:34 | cpy1 | This write into file 'log' may contain unencrypted data from $@. | test2.cpp:62:18:62:25 | password | this source. |
38-
| test2.cpp:73:3:73:9 | call to fprintf | test2.cpp:72:15:72:24 | password | test2.cpp:73:30:73:32 | *buf | This write into file 'log' may contain unencrypted data from $@. | test2.cpp:72:17:72:24 | password | this source. |
39-
| test2.cpp:99:3:99:9 | call to fprintf | test2.cpp:98:45:98:52 | password | test2.cpp:99:27:99:32 | *buffer | This write into file 'log' may contain unencrypted data from $@. | test2.cpp:98:45:98:52 | password | this source. |
40-
| test.cpp:45:3:45:7 | call to fputs | test.cpp:45:9:45:19 | thePassword | test.cpp:45:9:45:19 | thePassword | This write into file 'file' may contain unencrypted data from $@. | test.cpp:45:9:45:19 | thePassword | this source. |
41-
| test.cpp:70:35:70:35 | call to operator<< | test.cpp:70:38:70:48 | thePassword | test.cpp:70:38:70:48 | thePassword | This write into file 'mystream' may contain unencrypted data from $@. | test.cpp:70:38:70:48 | thePassword | this source. |
42-
| test.cpp:73:37:73:41 | call to write | test.cpp:70:38:70:48 | thePassword | test.cpp:73:43:73:53 | thePassword | This write into file 'mystream' may contain unencrypted data from $@. | test.cpp:70:38:70:48 | thePassword | this source. |
43-
| test.cpp:73:37:73:41 | call to write | test.cpp:73:43:73:53 | thePassword | test.cpp:73:43:73:53 | thePassword | This write into file 'mystream' may contain unencrypted data from $@. | test.cpp:73:43:73:53 | thePassword | this source. |
44-
| test.cpp:73:37:73:41 | call to write | test.cpp:73:63:73:73 | thePassword | test.cpp:73:43:73:53 | thePassword | This write into file 'mystream' may contain unencrypted data from $@. | test.cpp:73:63:73:73 | thePassword | this source. |
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
query: Security/CWE/CWE-311/CleartextFileWrite.ql
2-
postprocess: utils/test/InlineExpectationsTestQuery.ql
2+
postprocess:
3+
- utils/test/PrettyPrintModels.ql
4+
- utils/test/InlineExpectationsTestQuery.ql

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

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,3 +110,66 @@ void test_gets()
110110
gets(password); // $ Alert[cpp/cleartext-storage-buffer] // BAD
111111
}
112112
}
113+
114+
namespace std
115+
{
116+
template<class CharT> struct char_traits;
117+
template<class T> class allocator;
118+
119+
template<class CharT, class Traits = char_traits<CharT>>
120+
class basic_string_view
121+
{
122+
public:
123+
const CharT* data() const;
124+
};
125+
126+
template<class CharT, class Traits = char_traits<CharT>, class Allocator = allocator<CharT>>
127+
class basic_string
128+
{
129+
public:
130+
const CharT* data() const;
131+
size_t size() const;
132+
basic_string();
133+
basic_string& operator+=(CharT);
134+
const CharT* c_str() const;
135+
const CharT* begin() const;
136+
const CharT* end() const;
137+
138+
operator basic_string_view<CharT, Traits>() const;
139+
};
140+
141+
using string = basic_string<char>;
142+
using string_view = basic_string_view<char>;
143+
}
144+
145+
struct StringCredentials
146+
{
147+
std::string password;
148+
std::string username;
149+
};
150+
151+
void test_source_glvalue(FILE* log, const StringCredentials& credentials)
152+
{
153+
const char* pw = credentials.password.c_str(); // $ Source[cpp/cleartext-storage-file]
154+
fprintf(log, "%s", pw); // $ Alert[cpp/cleartext-storage-file]
155+
}
156+
157+
std::string copy_characters(std::string s)
158+
{
159+
std::string result;
160+
for (char ch : s)
161+
result += ch;
162+
return result;
163+
}
164+
165+
void test_character_iteration(FILE* log, const StringCredentials& credentials)
166+
{
167+
std::string by_value = copy_characters(credentials.password); // $ MISSING: Source[cpp/cleartext-storage-file]
168+
fprintf(log, "%s", by_value.c_str()); // $ MISSING: Alert[cpp/cleartext-storage-file]
169+
}
170+
171+
void test_reference(FILE* log, std::string s) {
172+
const std::string& password = s;
173+
const std::string& copy = password; // $ Source[cpp/cleartext-storage-file]
174+
fprintf(log, "%s", copy.c_str()); // $ Alert[cpp/cleartext-storage-file]
175+
}

0 commit comments

Comments
 (0)