From c36e91855fb9e0cf31b525a6fa1e3e54fb0408c3 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 19 Feb 2025 18:12:40 +0000 Subject: [PATCH 1/3] C++: Fix a test case. --- .../CWE/CWE-078/semmle/ExecTainted/test.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-078/semmle/ExecTainted/test.cpp b/cpp/ql/test/query-tests/Security/CWE/CWE-078/semmle/ExecTainted/test.cpp index 720ad7708bc..d00578144b5 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-078/semmle/ExecTainted/test.cpp +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-078/semmle/ExecTainted/test.cpp @@ -14,7 +14,7 @@ extern void encodeShellString(char *shellStr, int maxChars, const char* cStr); int main(int argc, char** argv) { char *userName = argv[2]; - + { // BAD: a string from the user is injected directly into // a command. @@ -23,10 +23,10 @@ int main(int argc, char** argv) { system(command1); } - { + { // GOOD: the user string is encoded by a library routine. char userNameQuoted[1000] = {0}; - encodeShellString(userNameQuoted, 1000, userName); + encodeShellString(userNameQuoted, 1000, userName); char command2[1000] = {0}; sprintf(command2, "userinfo -v %s", userNameQuoted); system(command2); @@ -36,16 +36,16 @@ int main(int argc, char** argv) { void test2(char* arg2) { // GOOD?: the user string is the *first* part of the command, like $CC in many environments char *envCC = getenv("CC"); - + char command[1000]; - sprintf("%s %s", envCC, arg2); + sprintf(command, "%s %s", envCC, arg2); system(command); } void test3(char* arg1) { // GOOD?: the user string is a `$CFLAGS` environment variable char *envCflags = getenv("CFLAGS"); - + char command[1000]; sprintf(command, "%s %s", arg1, envCflags); system(command); @@ -160,7 +160,7 @@ void test15(FILE *f) { fread(temp, 1, 10, f); int x = atoi(temp); - + char temp2[10]; sprintf(temp2, "%d", x); sprintf(command, "tail -n %s foo.log", temp2); From 3954f5e45eefedb4c0fe06e39bd7e398ba399f72 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 19 Feb 2025 18:24:50 +0000 Subject: [PATCH 2/3] C++: Add some test cases. --- .../semmle/ExecTainted/ExecTainted.expected | 358 ++++++++++-------- .../CWE/CWE-078/semmle/ExecTainted/test.cpp | 39 ++ 2 files changed, 244 insertions(+), 153 deletions(-) diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-078/semmle/ExecTainted/ExecTainted.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-078/semmle/ExecTainted/ExecTainted.expected index 586aacd2819..18dd45752cc 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-078/semmle/ExecTainted/ExecTainted.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-078/semmle/ExecTainted/ExecTainted.expected @@ -7,68 +7,88 @@ edges | test.cpp:47:21:47:26 | *call to getenv | test.cpp:50:35:50:43 | *envCflags | provenance | | | test.cpp:50:11:50:17 | sprintf output argument | test.cpp:51:10:51:16 | *command | provenance | | | test.cpp:50:35:50:43 | *envCflags | test.cpp:50:11:50:17 | sprintf output argument | provenance | Config | -| test.cpp:62:9:62:16 | fread output argument | test.cpp:64:20:64:27 | *filename | provenance | | -| test.cpp:64:11:64:17 | strncat output argument | test.cpp:65:10:65:16 | *command | provenance | | -| test.cpp:64:20:64:27 | *filename | test.cpp:64:11:64:17 | strncat output argument | provenance | Config | -| test.cpp:82:9:82:16 | fread output argument | test.cpp:84:20:84:27 | *filename | provenance | | -| test.cpp:84:11:84:17 | strncat output argument | test.cpp:85:32:85:38 | *command | provenance | | -| test.cpp:84:20:84:27 | *filename | test.cpp:84:11:84:17 | strncat output argument | provenance | Config | -| test.cpp:91:9:91:16 | fread output argument | test.cpp:93:17:93:24 | *filename | provenance | | -| test.cpp:93:11:93:14 | strncat output argument | test.cpp:94:45:94:48 | *path | provenance | | -| test.cpp:93:17:93:24 | *filename | test.cpp:93:11:93:14 | strncat output argument | provenance | Config | -| test.cpp:106:20:106:38 | *call to getenv | test.cpp:107:33:107:36 | *path | provenance | TaintFunction | -| test.cpp:107:31:107:31 | call to operator+ | test.cpp:107:31:107:31 | call to operator+ | provenance | | -| test.cpp:107:31:107:31 | call to operator+ | test.cpp:108:18:108:22 | *call to c_str | provenance | TaintFunction | -| test.cpp:107:33:107:36 | *path | test.cpp:107:31:107:31 | call to operator+ | provenance | Config | -| test.cpp:113:20:113:38 | *call to getenv | test.cpp:114:19:114:22 | *path | provenance | TaintFunction | -| test.cpp:114:10:114:23 | call to operator+ | test.cpp:114:25:114:29 | *call to c_str | provenance | TaintFunction | -| test.cpp:114:10:114:23 | call to operator+ | test.cpp:114:25:114:29 | *call to c_str | provenance | TaintFunction | -| test.cpp:114:17:114:17 | call to operator+ | test.cpp:114:10:114:23 | call to operator+ | provenance | | -| test.cpp:114:19:114:22 | *path | test.cpp:114:10:114:23 | call to operator+ | provenance | Config | -| test.cpp:114:19:114:22 | *path | test.cpp:114:17:114:17 | call to operator+ | provenance | Config | -| test.cpp:119:20:119:38 | *call to getenv | test.cpp:120:19:120:22 | *path | provenance | TaintFunction | -| test.cpp:120:17:120:17 | call to operator+ | test.cpp:120:10:120:30 | *call to data | provenance | TaintFunction | -| test.cpp:120:19:120:22 | *path | test.cpp:120:17:120:17 | call to operator+ | provenance | Config | -| test.cpp:140:9:140:11 | fread output argument | test.cpp:142:31:142:33 | *str | provenance | | -| test.cpp:142:11:142:17 | sprintf output argument | test.cpp:143:10:143:16 | *command | provenance | | -| test.cpp:142:31:142:33 | *str | test.cpp:142:11:142:17 | sprintf output argument | provenance | Config | -| test.cpp:174:9:174:16 | fread output argument | test.cpp:177:20:177:27 | *filename | provenance | | -| test.cpp:174:9:174:16 | fread output argument | test.cpp:180:22:180:29 | *filename | provenance | | -| test.cpp:177:13:177:17 | strncat output argument | test.cpp:178:22:178:26 | *flags | provenance | | -| test.cpp:177:13:177:17 | strncat output argument | test.cpp:178:22:178:26 | *flags | provenance | | -| test.cpp:177:20:177:27 | *filename | test.cpp:177:13:177:17 | strncat output argument | provenance | Config | -| test.cpp:177:20:177:27 | *filename | test.cpp:177:13:177:17 | strncat output argument | provenance | TaintFunction | -| test.cpp:178:13:178:19 | strncat output argument | test.cpp:183:32:183:38 | *command | provenance | | -| test.cpp:178:13:178:19 | strncat output argument | test.cpp:183:32:183:38 | *command | provenance | | -| test.cpp:178:22:178:26 | *flags | test.cpp:178:13:178:19 | strncat output argument | provenance | Config | -| test.cpp:178:22:178:26 | *flags | test.cpp:178:13:178:19 | strncat output argument | provenance | TaintFunction | -| test.cpp:180:13:180:19 | strncat output argument | test.cpp:183:32:183:38 | *command | provenance | | -| test.cpp:180:22:180:29 | *filename | test.cpp:180:13:180:19 | strncat output argument | provenance | Config | -| test.cpp:186:47:186:54 | *filename | test.cpp:187:18:187:25 | *filename | provenance | | -| test.cpp:187:11:187:15 | strncat output argument | test.cpp:188:20:188:24 | *flags | provenance | | -| test.cpp:187:11:187:15 | strncat output argument | test.cpp:188:20:188:24 | *flags | provenance | | -| test.cpp:187:18:187:25 | *filename | test.cpp:187:11:187:15 | strncat output argument | provenance | Config | -| test.cpp:187:18:187:25 | *filename | test.cpp:187:11:187:15 | strncat output argument | provenance | TaintFunction | -| test.cpp:188:11:188:17 | strncat output argument | test.cpp:186:19:186:25 | *command | provenance | | -| test.cpp:188:11:188:17 | strncat output argument | test.cpp:186:19:186:25 | *command | provenance | | -| test.cpp:188:11:188:17 | strncat output argument | test.cpp:186:19:186:25 | *command [Return] | provenance | | -| test.cpp:188:11:188:17 | strncat output argument | test.cpp:186:19:186:25 | *command [Return] | provenance | | -| test.cpp:188:20:188:24 | *flags | test.cpp:188:11:188:17 | strncat output argument | provenance | Config | -| test.cpp:188:20:188:24 | *flags | test.cpp:188:11:188:17 | strncat output argument | provenance | TaintFunction | -| test.cpp:194:9:194:16 | fread output argument | test.cpp:196:26:196:33 | *filename | provenance | | -| test.cpp:196:10:196:16 | concat output argument | test.cpp:198:32:198:38 | *command | provenance | | -| test.cpp:196:10:196:16 | concat output argument | test.cpp:198:32:198:38 | *command | provenance | | -| test.cpp:196:26:196:33 | *filename | test.cpp:186:47:186:54 | *filename | provenance | | -| test.cpp:196:26:196:33 | *filename | test.cpp:196:10:196:16 | concat output argument | provenance | Config | -| test.cpp:196:26:196:33 | *filename | test.cpp:196:10:196:16 | concat output argument | provenance | TaintFunction | -| test.cpp:218:9:218:16 | fread output argument | test.cpp:220:19:220:26 | *filename | provenance | | -| test.cpp:220:10:220:16 | strncat output argument | test.cpp:220:10:220:16 | strncat output argument | provenance | TaintFunction | -| test.cpp:220:10:220:16 | strncat output argument | test.cpp:220:10:220:16 | strncat output argument | provenance | TaintFunction | -| test.cpp:220:10:220:16 | strncat output argument | test.cpp:222:32:222:38 | *command | provenance | | -| test.cpp:220:10:220:16 | strncat output argument | test.cpp:222:32:222:38 | *command | provenance | | -| test.cpp:220:19:220:26 | *filename | test.cpp:220:10:220:16 | strncat output argument | provenance | Config | -| test.cpp:220:19:220:26 | *filename | test.cpp:220:10:220:16 | strncat output argument | provenance | Config | -| test.cpp:220:19:220:26 | *filename | test.cpp:220:19:220:26 | *filename | provenance | | +| test.cpp:63:9:63:16 | fread output argument | test.cpp:65:20:65:27 | *filename | provenance | | +| test.cpp:65:11:65:17 | strncat output argument | test.cpp:66:10:66:16 | *command | provenance | | +| test.cpp:65:20:65:27 | *filename | test.cpp:65:11:65:17 | strncat output argument | provenance | Config | +| test.cpp:83:9:83:16 | fread output argument | test.cpp:85:20:85:27 | *filename | provenance | | +| test.cpp:85:11:85:17 | strncat output argument | test.cpp:86:32:86:38 | *command | provenance | | +| test.cpp:85:20:85:27 | *filename | test.cpp:85:11:85:17 | strncat output argument | provenance | Config | +| test.cpp:92:9:92:16 | fread output argument | test.cpp:94:17:94:24 | *filename | provenance | | +| test.cpp:94:11:94:14 | strncat output argument | test.cpp:95:45:95:48 | *path | provenance | | +| test.cpp:94:17:94:24 | *filename | test.cpp:94:11:94:14 | strncat output argument | provenance | Config | +| test.cpp:107:20:107:38 | *call to getenv | test.cpp:108:33:108:36 | *path | provenance | TaintFunction | +| test.cpp:108:31:108:31 | call to operator+ | test.cpp:108:31:108:31 | call to operator+ | provenance | | +| test.cpp:108:31:108:31 | call to operator+ | test.cpp:109:18:109:22 | *call to c_str | provenance | TaintFunction | +| test.cpp:108:33:108:36 | *path | test.cpp:108:31:108:31 | call to operator+ | provenance | Config | +| test.cpp:114:20:114:38 | *call to getenv | test.cpp:115:19:115:22 | *path | provenance | TaintFunction | +| test.cpp:115:10:115:23 | call to operator+ | test.cpp:115:25:115:29 | *call to c_str | provenance | TaintFunction | +| test.cpp:115:10:115:23 | call to operator+ | test.cpp:115:25:115:29 | *call to c_str | provenance | TaintFunction | +| test.cpp:115:17:115:17 | call to operator+ | test.cpp:115:10:115:23 | call to operator+ | provenance | | +| test.cpp:115:19:115:22 | *path | test.cpp:115:10:115:23 | call to operator+ | provenance | Config | +| test.cpp:115:19:115:22 | *path | test.cpp:115:17:115:17 | call to operator+ | provenance | Config | +| test.cpp:120:20:120:38 | *call to getenv | test.cpp:121:19:121:22 | *path | provenance | TaintFunction | +| test.cpp:121:17:121:17 | call to operator+ | test.cpp:121:10:121:30 | *call to data | provenance | TaintFunction | +| test.cpp:121:19:121:22 | *path | test.cpp:121:17:121:17 | call to operator+ | provenance | Config | +| test.cpp:141:9:141:11 | fread output argument | test.cpp:143:31:143:33 | *str | provenance | | +| test.cpp:143:11:143:17 | sprintf output argument | test.cpp:144:10:144:16 | *command | provenance | | +| test.cpp:143:31:143:33 | *str | test.cpp:143:11:143:17 | sprintf output argument | provenance | Config | +| test.cpp:175:9:175:16 | fread output argument | test.cpp:178:20:178:27 | *filename | provenance | | +| test.cpp:175:9:175:16 | fread output argument | test.cpp:181:22:181:29 | *filename | provenance | | +| test.cpp:178:13:178:17 | strncat output argument | test.cpp:179:22:179:26 | *flags | provenance | | +| test.cpp:178:13:178:17 | strncat output argument | test.cpp:179:22:179:26 | *flags | provenance | | +| test.cpp:178:20:178:27 | *filename | test.cpp:178:13:178:17 | strncat output argument | provenance | Config | +| test.cpp:178:20:178:27 | *filename | test.cpp:178:13:178:17 | strncat output argument | provenance | TaintFunction | +| test.cpp:179:13:179:19 | strncat output argument | test.cpp:184:32:184:38 | *command | provenance | | +| test.cpp:179:13:179:19 | strncat output argument | test.cpp:184:32:184:38 | *command | provenance | | +| test.cpp:179:22:179:26 | *flags | test.cpp:179:13:179:19 | strncat output argument | provenance | Config | +| test.cpp:179:22:179:26 | *flags | test.cpp:179:13:179:19 | strncat output argument | provenance | TaintFunction | +| test.cpp:181:13:181:19 | strncat output argument | test.cpp:184:32:184:38 | *command | provenance | | +| test.cpp:181:22:181:29 | *filename | test.cpp:181:13:181:19 | strncat output argument | provenance | Config | +| test.cpp:187:47:187:54 | *filename | test.cpp:188:18:188:25 | *filename | provenance | | +| test.cpp:188:11:188:15 | strncat output argument | test.cpp:189:20:189:24 | *flags | provenance | | +| test.cpp:188:11:188:15 | strncat output argument | test.cpp:189:20:189:24 | *flags | provenance | | +| test.cpp:188:18:188:25 | *filename | test.cpp:188:11:188:15 | strncat output argument | provenance | Config | +| test.cpp:188:18:188:25 | *filename | test.cpp:188:11:188:15 | strncat output argument | provenance | TaintFunction | +| test.cpp:189:11:189:17 | strncat output argument | test.cpp:187:19:187:25 | *command | provenance | | +| test.cpp:189:11:189:17 | strncat output argument | test.cpp:187:19:187:25 | *command | provenance | | +| test.cpp:189:11:189:17 | strncat output argument | test.cpp:187:19:187:25 | *command [Return] | provenance | | +| test.cpp:189:11:189:17 | strncat output argument | test.cpp:187:19:187:25 | *command [Return] | provenance | | +| test.cpp:189:20:189:24 | *flags | test.cpp:189:11:189:17 | strncat output argument | provenance | Config | +| test.cpp:189:20:189:24 | *flags | test.cpp:189:11:189:17 | strncat output argument | provenance | TaintFunction | +| test.cpp:195:9:195:16 | fread output argument | test.cpp:197:26:197:33 | *filename | provenance | | +| test.cpp:197:10:197:16 | concat output argument | test.cpp:199:32:199:38 | *command | provenance | | +| test.cpp:197:10:197:16 | concat output argument | test.cpp:199:32:199:38 | *command | provenance | | +| test.cpp:197:26:197:33 | *filename | test.cpp:187:47:187:54 | *filename | provenance | | +| test.cpp:197:26:197:33 | *filename | test.cpp:197:10:197:16 | concat output argument | provenance | Config | +| test.cpp:197:26:197:33 | *filename | test.cpp:197:10:197:16 | concat output argument | provenance | TaintFunction | +| test.cpp:219:9:219:16 | fread output argument | test.cpp:221:19:221:26 | *filename | provenance | | +| test.cpp:221:10:221:16 | strncat output argument | test.cpp:221:10:221:16 | strncat output argument | provenance | TaintFunction | +| test.cpp:221:10:221:16 | strncat output argument | test.cpp:221:10:221:16 | strncat output argument | provenance | TaintFunction | +| test.cpp:221:10:221:16 | strncat output argument | test.cpp:223:32:223:38 | *command | provenance | | +| test.cpp:221:10:221:16 | strncat output argument | test.cpp:223:32:223:38 | *command | provenance | | +| test.cpp:221:19:221:26 | *filename | test.cpp:221:10:221:16 | strncat output argument | provenance | Config | +| test.cpp:221:19:221:26 | *filename | test.cpp:221:10:221:16 | strncat output argument | provenance | Config | +| test.cpp:221:19:221:26 | *filename | test.cpp:221:19:221:26 | *filename | provenance | | +| test.cpp:231:11:231:16 | strncat output argument | test.cpp:232:11:232:16 | strncat output argument | provenance | TaintFunction | +| test.cpp:231:19:231:33 | *call to getenv | test.cpp:231:11:231:16 | strncat output argument | provenance | Config | +| test.cpp:232:11:232:16 | strncat output argument | test.cpp:233:11:233:16 | strncat output argument | provenance | TaintFunction | +| test.cpp:232:11:232:16 | strncat output argument | test.cpp:233:11:233:16 | strncat output argument | provenance | TaintFunction | +| test.cpp:232:19:232:33 | *call to getenv | test.cpp:232:11:232:16 | strncat output argument | provenance | Config | +| test.cpp:233:11:233:16 | strncat output argument | test.cpp:234:10:234:15 | *buffer | provenance | | +| test.cpp:233:11:233:16 | strncat output argument | test.cpp:234:10:234:15 | *buffer | provenance | | +| test.cpp:242:11:242:17 | sprintf output argument | test.cpp:247:5:247:11 | *buffer1 | provenance | | +| test.cpp:242:11:242:17 | sprintf output argument | test.cpp:247:5:247:11 | *buffer1 | provenance | | +| test.cpp:243:5:243:10 | *call to getenv | test.cpp:242:11:242:17 | sprintf output argument | provenance | TaintFunction | +| test.cpp:244:5:244:10 | *call to getenv | test.cpp:242:11:242:17 | sprintf output argument | provenance | Config | +| test.cpp:244:5:244:10 | *call to getenv | test.cpp:242:11:242:17 | sprintf output argument | provenance | TaintFunction | +| test.cpp:245:11:245:17 | sprintf output argument | test.cpp:249:10:249:16 | *buffer2 | provenance | | +| test.cpp:245:11:245:17 | sprintf output argument | test.cpp:249:10:249:16 | *buffer2 | provenance | | +| test.cpp:245:11:245:17 | sprintf output argument | test.cpp:249:10:249:16 | *buffer2 | provenance | | +| test.cpp:247:5:247:11 | *buffer1 | test.cpp:245:11:245:17 | sprintf output argument | provenance | Config | +| test.cpp:247:5:247:11 | *buffer1 | test.cpp:245:11:245:17 | sprintf output argument | provenance | TaintFunction | +| test.cpp:248:5:248:10 | *call to getenv | test.cpp:245:11:245:17 | sprintf output argument | provenance | Config | +| test.cpp:259:13:259:18 | strncat output argument | test.cpp:261:10:261:15 | *buffer | provenance | | +| test.cpp:259:21:259:35 | *call to getenv | test.cpp:259:13:259:18 | strncat output argument | provenance | Config | nodes | test.cpp:15:27:15:30 | **argv | semmle.label | **argv | | test.cpp:16:20:16:26 | *access to array | semmle.label | *access to array | @@ -80,98 +100,130 @@ nodes | test.cpp:50:11:50:17 | sprintf output argument | semmle.label | sprintf output argument | | test.cpp:50:35:50:43 | *envCflags | semmle.label | *envCflags | | test.cpp:51:10:51:16 | *command | semmle.label | *command | -| test.cpp:62:9:62:16 | fread output argument | semmle.label | fread output argument | -| test.cpp:64:11:64:17 | strncat output argument | semmle.label | strncat output argument | -| test.cpp:64:20:64:27 | *filename | semmle.label | *filename | -| test.cpp:65:10:65:16 | *command | semmle.label | *command | -| test.cpp:82:9:82:16 | fread output argument | semmle.label | fread output argument | -| test.cpp:84:11:84:17 | strncat output argument | semmle.label | strncat output argument | -| test.cpp:84:20:84:27 | *filename | semmle.label | *filename | -| test.cpp:85:32:85:38 | *command | semmle.label | *command | -| test.cpp:91:9:91:16 | fread output argument | semmle.label | fread output argument | -| test.cpp:93:11:93:14 | strncat output argument | semmle.label | strncat output argument | -| test.cpp:93:17:93:24 | *filename | semmle.label | *filename | -| test.cpp:94:45:94:48 | *path | semmle.label | *path | -| test.cpp:106:20:106:38 | *call to getenv | semmle.label | *call to getenv | -| test.cpp:107:31:107:31 | call to operator+ | semmle.label | call to operator+ | -| test.cpp:107:31:107:31 | call to operator+ | semmle.label | call to operator+ | -| test.cpp:107:33:107:36 | *path | semmle.label | *path | -| test.cpp:108:18:108:22 | *call to c_str | semmle.label | *call to c_str | -| test.cpp:113:20:113:38 | *call to getenv | semmle.label | *call to getenv | -| test.cpp:114:10:114:23 | call to operator+ | semmle.label | call to operator+ | -| test.cpp:114:10:114:23 | call to operator+ | semmle.label | call to operator+ | -| test.cpp:114:17:114:17 | call to operator+ | semmle.label | call to operator+ | -| test.cpp:114:19:114:22 | *path | semmle.label | *path | -| test.cpp:114:25:114:29 | *call to c_str | semmle.label | *call to c_str | -| test.cpp:114:25:114:29 | *call to c_str | semmle.label | *call to c_str | -| test.cpp:119:20:119:38 | *call to getenv | semmle.label | *call to getenv | -| test.cpp:120:10:120:30 | *call to data | semmle.label | *call to data | -| test.cpp:120:17:120:17 | call to operator+ | semmle.label | call to operator+ | -| test.cpp:120:19:120:22 | *path | semmle.label | *path | -| test.cpp:140:9:140:11 | fread output argument | semmle.label | fread output argument | -| test.cpp:142:11:142:17 | sprintf output argument | semmle.label | sprintf output argument | -| test.cpp:142:31:142:33 | *str | semmle.label | *str | -| test.cpp:143:10:143:16 | *command | semmle.label | *command | -| test.cpp:174:9:174:16 | fread output argument | semmle.label | fread output argument | -| test.cpp:177:13:177:17 | strncat output argument | semmle.label | strncat output argument | -| test.cpp:177:13:177:17 | strncat output argument | semmle.label | strncat output argument | -| test.cpp:177:20:177:27 | *filename | semmle.label | *filename | -| test.cpp:178:13:178:19 | strncat output argument | semmle.label | strncat output argument | -| test.cpp:178:13:178:19 | strncat output argument | semmle.label | strncat output argument | -| test.cpp:178:22:178:26 | *flags | semmle.label | *flags | -| test.cpp:178:22:178:26 | *flags | semmle.label | *flags | -| test.cpp:180:13:180:19 | strncat output argument | semmle.label | strncat output argument | -| test.cpp:180:22:180:29 | *filename | semmle.label | *filename | -| test.cpp:183:32:183:38 | *command | semmle.label | *command | -| test.cpp:183:32:183:38 | *command | semmle.label | *command | -| test.cpp:183:32:183:38 | *command | semmle.label | *command | -| test.cpp:186:19:186:25 | *command | semmle.label | *command | -| test.cpp:186:19:186:25 | *command | semmle.label | *command | -| test.cpp:186:19:186:25 | *command [Return] | semmle.label | *command [Return] | -| test.cpp:186:19:186:25 | *command [Return] | semmle.label | *command [Return] | -| test.cpp:186:47:186:54 | *filename | semmle.label | *filename | -| test.cpp:187:11:187:15 | strncat output argument | semmle.label | strncat output argument | -| test.cpp:187:11:187:15 | strncat output argument | semmle.label | strncat output argument | -| test.cpp:187:18:187:25 | *filename | semmle.label | *filename | -| test.cpp:188:11:188:17 | strncat output argument | semmle.label | strncat output argument | -| test.cpp:188:11:188:17 | strncat output argument | semmle.label | strncat output argument | -| test.cpp:188:20:188:24 | *flags | semmle.label | *flags | -| test.cpp:188:20:188:24 | *flags | semmle.label | *flags | -| test.cpp:194:9:194:16 | fread output argument | semmle.label | fread output argument | -| test.cpp:196:10:196:16 | concat output argument | semmle.label | concat output argument | -| test.cpp:196:10:196:16 | concat output argument | semmle.label | concat output argument | -| test.cpp:196:26:196:33 | *filename | semmle.label | *filename | -| test.cpp:198:32:198:38 | *command | semmle.label | *command | -| test.cpp:198:32:198:38 | *command | semmle.label | *command | -| test.cpp:218:9:218:16 | fread output argument | semmle.label | fread output argument | -| test.cpp:220:10:220:16 | strncat output argument | semmle.label | strncat output argument | -| test.cpp:220:10:220:16 | strncat output argument | semmle.label | strncat output argument | -| test.cpp:220:10:220:16 | strncat output argument | semmle.label | strncat output argument | -| test.cpp:220:10:220:16 | strncat output argument | semmle.label | strncat output argument | -| test.cpp:220:19:220:26 | *filename | semmle.label | *filename | -| test.cpp:220:19:220:26 | *filename | semmle.label | *filename | -| test.cpp:222:32:222:38 | *command | semmle.label | *command | -| test.cpp:222:32:222:38 | *command | semmle.label | *command | +| test.cpp:63:9:63:16 | fread output argument | semmle.label | fread output argument | +| test.cpp:65:11:65:17 | strncat output argument | semmle.label | strncat output argument | +| test.cpp:65:20:65:27 | *filename | semmle.label | *filename | +| test.cpp:66:10:66:16 | *command | semmle.label | *command | +| test.cpp:83:9:83:16 | fread output argument | semmle.label | fread output argument | +| test.cpp:85:11:85:17 | strncat output argument | semmle.label | strncat output argument | +| test.cpp:85:20:85:27 | *filename | semmle.label | *filename | +| test.cpp:86:32:86:38 | *command | semmle.label | *command | +| test.cpp:92:9:92:16 | fread output argument | semmle.label | fread output argument | +| test.cpp:94:11:94:14 | strncat output argument | semmle.label | strncat output argument | +| test.cpp:94:17:94:24 | *filename | semmle.label | *filename | +| test.cpp:95:45:95:48 | *path | semmle.label | *path | +| test.cpp:107:20:107:38 | *call to getenv | semmle.label | *call to getenv | +| test.cpp:108:31:108:31 | call to operator+ | semmle.label | call to operator+ | +| test.cpp:108:31:108:31 | call to operator+ | semmle.label | call to operator+ | +| test.cpp:108:33:108:36 | *path | semmle.label | *path | +| test.cpp:109:18:109:22 | *call to c_str | semmle.label | *call to c_str | +| test.cpp:114:20:114:38 | *call to getenv | semmle.label | *call to getenv | +| test.cpp:115:10:115:23 | call to operator+ | semmle.label | call to operator+ | +| test.cpp:115:10:115:23 | call to operator+ | semmle.label | call to operator+ | +| test.cpp:115:17:115:17 | call to operator+ | semmle.label | call to operator+ | +| test.cpp:115:19:115:22 | *path | semmle.label | *path | +| test.cpp:115:25:115:29 | *call to c_str | semmle.label | *call to c_str | +| test.cpp:115:25:115:29 | *call to c_str | semmle.label | *call to c_str | +| test.cpp:120:20:120:38 | *call to getenv | semmle.label | *call to getenv | +| test.cpp:121:10:121:30 | *call to data | semmle.label | *call to data | +| test.cpp:121:17:121:17 | call to operator+ | semmle.label | call to operator+ | +| test.cpp:121:19:121:22 | *path | semmle.label | *path | +| test.cpp:141:9:141:11 | fread output argument | semmle.label | fread output argument | +| test.cpp:143:11:143:17 | sprintf output argument | semmle.label | sprintf output argument | +| test.cpp:143:31:143:33 | *str | semmle.label | *str | +| test.cpp:144:10:144:16 | *command | semmle.label | *command | +| test.cpp:175:9:175:16 | fread output argument | semmle.label | fread output argument | +| test.cpp:178:13:178:17 | strncat output argument | semmle.label | strncat output argument | +| test.cpp:178:13:178:17 | strncat output argument | semmle.label | strncat output argument | +| test.cpp:178:20:178:27 | *filename | semmle.label | *filename | +| test.cpp:179:13:179:19 | strncat output argument | semmle.label | strncat output argument | +| test.cpp:179:13:179:19 | strncat output argument | semmle.label | strncat output argument | +| test.cpp:179:22:179:26 | *flags | semmle.label | *flags | +| test.cpp:179:22:179:26 | *flags | semmle.label | *flags | +| test.cpp:181:13:181:19 | strncat output argument | semmle.label | strncat output argument | +| test.cpp:181:22:181:29 | *filename | semmle.label | *filename | +| test.cpp:184:32:184:38 | *command | semmle.label | *command | +| test.cpp:184:32:184:38 | *command | semmle.label | *command | +| test.cpp:184:32:184:38 | *command | semmle.label | *command | +| test.cpp:187:19:187:25 | *command | semmle.label | *command | +| test.cpp:187:19:187:25 | *command | semmle.label | *command | +| test.cpp:187:19:187:25 | *command [Return] | semmle.label | *command [Return] | +| test.cpp:187:19:187:25 | *command [Return] | semmle.label | *command [Return] | +| test.cpp:187:47:187:54 | *filename | semmle.label | *filename | +| test.cpp:188:11:188:15 | strncat output argument | semmle.label | strncat output argument | +| test.cpp:188:11:188:15 | strncat output argument | semmle.label | strncat output argument | +| test.cpp:188:18:188:25 | *filename | semmle.label | *filename | +| test.cpp:189:11:189:17 | strncat output argument | semmle.label | strncat output argument | +| test.cpp:189:11:189:17 | strncat output argument | semmle.label | strncat output argument | +| test.cpp:189:20:189:24 | *flags | semmle.label | *flags | +| test.cpp:189:20:189:24 | *flags | semmle.label | *flags | +| test.cpp:195:9:195:16 | fread output argument | semmle.label | fread output argument | +| test.cpp:197:10:197:16 | concat output argument | semmle.label | concat output argument | +| test.cpp:197:10:197:16 | concat output argument | semmle.label | concat output argument | +| test.cpp:197:26:197:33 | *filename | semmle.label | *filename | +| test.cpp:199:32:199:38 | *command | semmle.label | *command | +| test.cpp:199:32:199:38 | *command | semmle.label | *command | +| test.cpp:219:9:219:16 | fread output argument | semmle.label | fread output argument | +| test.cpp:221:10:221:16 | strncat output argument | semmle.label | strncat output argument | +| test.cpp:221:10:221:16 | strncat output argument | semmle.label | strncat output argument | +| test.cpp:221:10:221:16 | strncat output argument | semmle.label | strncat output argument | +| test.cpp:221:10:221:16 | strncat output argument | semmle.label | strncat output argument | +| test.cpp:221:19:221:26 | *filename | semmle.label | *filename | +| test.cpp:221:19:221:26 | *filename | semmle.label | *filename | +| test.cpp:223:32:223:38 | *command | semmle.label | *command | +| test.cpp:223:32:223:38 | *command | semmle.label | *command | +| test.cpp:231:11:231:16 | strncat output argument | semmle.label | strncat output argument | +| test.cpp:231:19:231:33 | *call to getenv | semmle.label | *call to getenv | +| test.cpp:232:11:232:16 | strncat output argument | semmle.label | strncat output argument | +| test.cpp:232:11:232:16 | strncat output argument | semmle.label | strncat output argument | +| test.cpp:232:19:232:33 | *call to getenv | semmle.label | *call to getenv | +| test.cpp:233:11:233:16 | strncat output argument | semmle.label | strncat output argument | +| test.cpp:233:11:233:16 | strncat output argument | semmle.label | strncat output argument | +| test.cpp:234:10:234:15 | *buffer | semmle.label | *buffer | +| test.cpp:234:10:234:15 | *buffer | semmle.label | *buffer | +| test.cpp:242:11:242:17 | sprintf output argument | semmle.label | sprintf output argument | +| test.cpp:242:11:242:17 | sprintf output argument | semmle.label | sprintf output argument | +| test.cpp:243:5:243:10 | *call to getenv | semmle.label | *call to getenv | +| test.cpp:244:5:244:10 | *call to getenv | semmle.label | *call to getenv | +| test.cpp:245:11:245:17 | sprintf output argument | semmle.label | sprintf output argument | +| test.cpp:245:11:245:17 | sprintf output argument | semmle.label | sprintf output argument | +| test.cpp:245:11:245:17 | sprintf output argument | semmle.label | sprintf output argument | +| test.cpp:247:5:247:11 | *buffer1 | semmle.label | *buffer1 | +| test.cpp:247:5:247:11 | *buffer1 | semmle.label | *buffer1 | +| test.cpp:248:5:248:10 | *call to getenv | semmle.label | *call to getenv | +| test.cpp:249:10:249:16 | *buffer2 | semmle.label | *buffer2 | +| test.cpp:249:10:249:16 | *buffer2 | semmle.label | *buffer2 | +| test.cpp:249:10:249:16 | *buffer2 | semmle.label | *buffer2 | +| test.cpp:259:13:259:18 | strncat output argument | semmle.label | strncat output argument | +| test.cpp:259:21:259:35 | *call to getenv | semmle.label | *call to getenv | +| test.cpp:261:10:261:15 | *buffer | semmle.label | *buffer | subpaths -| test.cpp:196:26:196:33 | *filename | test.cpp:186:47:186:54 | *filename | test.cpp:186:19:186:25 | *command | test.cpp:196:10:196:16 | concat output argument | -| test.cpp:196:26:196:33 | *filename | test.cpp:186:47:186:54 | *filename | test.cpp:186:19:186:25 | *command | test.cpp:196:10:196:16 | concat output argument | -| test.cpp:196:26:196:33 | *filename | test.cpp:186:47:186:54 | *filename | test.cpp:186:19:186:25 | *command [Return] | test.cpp:196:10:196:16 | concat output argument | -| test.cpp:196:26:196:33 | *filename | test.cpp:186:47:186:54 | *filename | test.cpp:186:19:186:25 | *command [Return] | test.cpp:196:10:196:16 | concat output argument | +| test.cpp:197:26:197:33 | *filename | test.cpp:187:47:187:54 | *filename | test.cpp:187:19:187:25 | *command | test.cpp:197:10:197:16 | concat output argument | +| test.cpp:197:26:197:33 | *filename | test.cpp:187:47:187:54 | *filename | test.cpp:187:19:187:25 | *command | test.cpp:197:10:197:16 | concat output argument | +| test.cpp:197:26:197:33 | *filename | test.cpp:187:47:187:54 | *filename | test.cpp:187:19:187:25 | *command [Return] | test.cpp:197:10:197:16 | concat output argument | +| test.cpp:197:26:197:33 | *filename | test.cpp:187:47:187:54 | *filename | test.cpp:187:19:187:25 | *command [Return] | test.cpp:197:10:197:16 | concat output argument | #select | test.cpp:23:12:23:19 | command1 | test.cpp:15:27:15:30 | **argv | test.cpp:23:12:23:19 | *command1 | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:15:27:15:30 | **argv | user input (a command-line argument) | test.cpp:22:13:22:20 | sprintf output argument | sprintf output argument | | test.cpp:51:10:51:16 | command | test.cpp:47:21:47:26 | *call to getenv | test.cpp:51:10:51:16 | *command | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:47:21:47:26 | *call to getenv | user input (an environment variable) | test.cpp:50:11:50:17 | sprintf output argument | sprintf output argument | -| test.cpp:65:10:65:16 | command | test.cpp:62:9:62:16 | fread output argument | test.cpp:65:10:65:16 | *command | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:62:9:62:16 | fread output argument | user input (string read by fread) | test.cpp:64:11:64:17 | strncat output argument | strncat output argument | -| test.cpp:85:32:85:38 | command | test.cpp:82:9:82:16 | fread output argument | test.cpp:85:32:85:38 | *command | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:82:9:82:16 | fread output argument | user input (string read by fread) | test.cpp:84:11:84:17 | strncat output argument | strncat output argument | -| test.cpp:94:45:94:48 | path | test.cpp:91:9:91:16 | fread output argument | test.cpp:94:45:94:48 | *path | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:91:9:91:16 | fread output argument | user input (string read by fread) | test.cpp:93:11:93:14 | strncat output argument | strncat output argument | -| test.cpp:108:18:108:22 | call to c_str | test.cpp:106:20:106:38 | *call to getenv | test.cpp:108:18:108:22 | *call to c_str | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:106:20:106:38 | *call to getenv | user input (an environment variable) | test.cpp:107:31:107:31 | call to operator+ | call to operator+ | -| test.cpp:114:25:114:29 | call to c_str | test.cpp:113:20:113:38 | *call to getenv | test.cpp:114:25:114:29 | *call to c_str | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:113:20:113:38 | *call to getenv | user input (an environment variable) | test.cpp:114:10:114:23 | call to operator+ | call to operator+ | -| test.cpp:114:25:114:29 | call to c_str | test.cpp:113:20:113:38 | *call to getenv | test.cpp:114:25:114:29 | *call to c_str | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:113:20:113:38 | *call to getenv | user input (an environment variable) | test.cpp:114:17:114:17 | call to operator+ | call to operator+ | -| test.cpp:120:25:120:28 | call to data | test.cpp:119:20:119:38 | *call to getenv | test.cpp:120:10:120:30 | *call to data | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:119:20:119:38 | *call to getenv | user input (an environment variable) | test.cpp:120:17:120:17 | call to operator+ | call to operator+ | -| test.cpp:143:10:143:16 | command | test.cpp:140:9:140:11 | fread output argument | test.cpp:143:10:143:16 | *command | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:140:9:140:11 | fread output argument | user input (string read by fread) | test.cpp:142:11:142:17 | sprintf output argument | sprintf output argument | -| test.cpp:183:32:183:38 | command | test.cpp:174:9:174:16 | fread output argument | test.cpp:183:32:183:38 | *command | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:174:9:174:16 | fread output argument | user input (string read by fread) | test.cpp:177:13:177:17 | strncat output argument | strncat output argument | -| test.cpp:183:32:183:38 | command | test.cpp:174:9:174:16 | fread output argument | test.cpp:183:32:183:38 | *command | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:174:9:174:16 | fread output argument | user input (string read by fread) | test.cpp:178:13:178:19 | strncat output argument | strncat output argument | -| test.cpp:183:32:183:38 | command | test.cpp:174:9:174:16 | fread output argument | test.cpp:183:32:183:38 | *command | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:174:9:174:16 | fread output argument | user input (string read by fread) | test.cpp:180:13:180:19 | strncat output argument | strncat output argument | -| test.cpp:198:32:198:38 | command | test.cpp:194:9:194:16 | fread output argument | test.cpp:198:32:198:38 | *command | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:194:9:194:16 | fread output argument | user input (string read by fread) | test.cpp:187:11:187:15 | strncat output argument | strncat output argument | -| test.cpp:198:32:198:38 | command | test.cpp:194:9:194:16 | fread output argument | test.cpp:198:32:198:38 | *command | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:194:9:194:16 | fread output argument | user input (string read by fread) | test.cpp:188:11:188:17 | strncat output argument | strncat output argument | -| test.cpp:222:32:222:38 | command | test.cpp:218:9:218:16 | fread output argument | test.cpp:222:32:222:38 | *command | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:218:9:218:16 | fread output argument | user input (string read by fread) | test.cpp:220:10:220:16 | strncat output argument | strncat output argument | -| test.cpp:222:32:222:38 | command | test.cpp:218:9:218:16 | fread output argument | test.cpp:222:32:222:38 | *command | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:218:9:218:16 | fread output argument | user input (string read by fread) | test.cpp:220:10:220:16 | strncat output argument | strncat output argument | +| test.cpp:66:10:66:16 | command | test.cpp:63:9:63:16 | fread output argument | test.cpp:66:10:66:16 | *command | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:63:9:63:16 | fread output argument | user input (string read by fread) | test.cpp:65:11:65:17 | strncat output argument | strncat output argument | +| test.cpp:86:32:86:38 | command | test.cpp:83:9:83:16 | fread output argument | test.cpp:86:32:86:38 | *command | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:83:9:83:16 | fread output argument | user input (string read by fread) | test.cpp:85:11:85:17 | strncat output argument | strncat output argument | +| test.cpp:95:45:95:48 | path | test.cpp:92:9:92:16 | fread output argument | test.cpp:95:45:95:48 | *path | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:92:9:92:16 | fread output argument | user input (string read by fread) | test.cpp:94:11:94:14 | strncat output argument | strncat output argument | +| test.cpp:109:18:109:22 | call to c_str | test.cpp:107:20:107:38 | *call to getenv | test.cpp:109:18:109:22 | *call to c_str | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:107:20:107:38 | *call to getenv | user input (an environment variable) | test.cpp:108:31:108:31 | call to operator+ | call to operator+ | +| test.cpp:115:25:115:29 | call to c_str | test.cpp:114:20:114:38 | *call to getenv | test.cpp:115:25:115:29 | *call to c_str | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:114:20:114:38 | *call to getenv | user input (an environment variable) | test.cpp:115:10:115:23 | call to operator+ | call to operator+ | +| test.cpp:115:25:115:29 | call to c_str | test.cpp:114:20:114:38 | *call to getenv | test.cpp:115:25:115:29 | *call to c_str | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:114:20:114:38 | *call to getenv | user input (an environment variable) | test.cpp:115:17:115:17 | call to operator+ | call to operator+ | +| test.cpp:121:25:121:28 | call to data | test.cpp:120:20:120:38 | *call to getenv | test.cpp:121:10:121:30 | *call to data | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:120:20:120:38 | *call to getenv | user input (an environment variable) | test.cpp:121:17:121:17 | call to operator+ | call to operator+ | +| test.cpp:144:10:144:16 | command | test.cpp:141:9:141:11 | fread output argument | test.cpp:144:10:144:16 | *command | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:141:9:141:11 | fread output argument | user input (string read by fread) | test.cpp:143:11:143:17 | sprintf output argument | sprintf output argument | +| test.cpp:184:32:184:38 | command | test.cpp:175:9:175:16 | fread output argument | test.cpp:184:32:184:38 | *command | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:175:9:175:16 | fread output argument | user input (string read by fread) | test.cpp:178:13:178:17 | strncat output argument | strncat output argument | +| test.cpp:184:32:184:38 | command | test.cpp:175:9:175:16 | fread output argument | test.cpp:184:32:184:38 | *command | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:175:9:175:16 | fread output argument | user input (string read by fread) | test.cpp:179:13:179:19 | strncat output argument | strncat output argument | +| test.cpp:184:32:184:38 | command | test.cpp:175:9:175:16 | fread output argument | test.cpp:184:32:184:38 | *command | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:175:9:175:16 | fread output argument | user input (string read by fread) | test.cpp:181:13:181:19 | strncat output argument | strncat output argument | +| test.cpp:199:32:199:38 | command | test.cpp:195:9:195:16 | fread output argument | test.cpp:199:32:199:38 | *command | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:195:9:195:16 | fread output argument | user input (string read by fread) | test.cpp:188:11:188:15 | strncat output argument | strncat output argument | +| test.cpp:199:32:199:38 | command | test.cpp:195:9:195:16 | fread output argument | test.cpp:199:32:199:38 | *command | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:195:9:195:16 | fread output argument | user input (string read by fread) | test.cpp:189:11:189:17 | strncat output argument | strncat output argument | +| test.cpp:223:32:223:38 | command | test.cpp:219:9:219:16 | fread output argument | test.cpp:223:32:223:38 | *command | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:219:9:219:16 | fread output argument | user input (string read by fread) | test.cpp:221:10:221:16 | strncat output argument | strncat output argument | +| test.cpp:223:32:223:38 | command | test.cpp:219:9:219:16 | fread output argument | test.cpp:223:32:223:38 | *command | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:219:9:219:16 | fread output argument | user input (string read by fread) | test.cpp:221:10:221:16 | strncat output argument | strncat output argument | +| test.cpp:234:10:234:15 | buffer | test.cpp:231:19:231:33 | *call to getenv | test.cpp:234:10:234:15 | *buffer | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:231:19:231:33 | *call to getenv | user input (an environment variable) | test.cpp:231:11:231:16 | strncat output argument | strncat output argument | +| test.cpp:234:10:234:15 | buffer | test.cpp:232:19:232:33 | *call to getenv | test.cpp:234:10:234:15 | *buffer | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:232:19:232:33 | *call to getenv | user input (an environment variable) | test.cpp:232:11:232:16 | strncat output argument | strncat output argument | +| test.cpp:249:10:249:16 | buffer2 | test.cpp:243:5:243:10 | *call to getenv | test.cpp:249:10:249:16 | *buffer2 | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:243:5:243:10 | *call to getenv | user input (an environment variable) | test.cpp:245:11:245:17 | sprintf output argument | sprintf output argument | +| test.cpp:249:10:249:16 | buffer2 | test.cpp:244:5:244:10 | *call to getenv | test.cpp:249:10:249:16 | *buffer2 | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:244:5:244:10 | *call to getenv | user input (an environment variable) | test.cpp:242:11:242:17 | sprintf output argument | sprintf output argument | +| test.cpp:249:10:249:16 | buffer2 | test.cpp:244:5:244:10 | *call to getenv | test.cpp:249:10:249:16 | *buffer2 | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:244:5:244:10 | *call to getenv | user input (an environment variable) | test.cpp:245:11:245:17 | sprintf output argument | sprintf output argument | +| test.cpp:249:10:249:16 | buffer2 | test.cpp:248:5:248:10 | *call to getenv | test.cpp:249:10:249:16 | *buffer2 | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:248:5:248:10 | *call to getenv | user input (an environment variable) | test.cpp:245:11:245:17 | sprintf output argument | sprintf output argument | +| test.cpp:261:10:261:15 | buffer | test.cpp:259:21:259:35 | *call to getenv | test.cpp:261:10:261:15 | *buffer | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:259:21:259:35 | *call to getenv | user input (an environment variable) | test.cpp:259:13:259:18 | strncat output argument | strncat output argument | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-078/semmle/ExecTainted/test.cpp b/cpp/ql/test/query-tests/Security/CWE/CWE-078/semmle/ExecTainted/test.cpp index d00578144b5..8c7651f3275 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-078/semmle/ExecTainted/test.cpp +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-078/semmle/ExecTainted/test.cpp @@ -54,6 +54,7 @@ void test3(char* arg1) { typedef unsigned long size_t; typedef void FILE; size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream); +char *strncpy(char *s1, const char *s2, size_t n); char *strncat(char *s1, const char *s2, size_t n); void test4(FILE *f) { @@ -222,4 +223,42 @@ void test19(FILE *f) { execl("/bin/sh", "sh", "-c", command); } +void test20() { + // BAD: the user strings `var_b`, `var_c` are injected directly into a command + char buffer[1024 * 4]; + + strncpy(buffer, getenv("var_a"), 1024); + strncat(buffer, getenv("var_b"), 1024); + strncat(buffer, getenv("var_c"), 1024); + strncat(buffer, " ", 1024); + system(buffer); +} + +void test21() { + // BAD: the user strings `var_b`, `var_c` are injected directly into a command + char buffer1[1024]; + char buffer2[1024]; + + sprintf(buffer1, "%s %s", + getenv("var_a"), + getenv("var_b")); + sprintf(buffer2, "%s %s %s", + " ", + buffer1, + getenv("var_c")); + system(buffer2); +} + +void test22() { + // BAD: the user strings `var_a` are injected directly into a command + char buffer[1024 * 11]; + int i; + + strncpy(buffer, "command ", 1024); + for (i = 0; i < 10; i++) { + strncat(buffer, getenv("var_a"), 1024); + } + system(buffer); +} + // open question: do we want to report certain sources even when they're the start of the string? From b6f90555668c0e40a660a510c719b9d661749d51 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 19 Feb 2025 18:09:18 +0000 Subject: [PATCH 3/3] C++: Add and correct some QLDoc. --- cpp/ql/src/Security/CWE/CWE-078/ExecTainted.ql | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/cpp/ql/src/Security/CWE/CWE-078/ExecTainted.ql b/cpp/ql/src/Security/CWE/CWE-078/ExecTainted.ql index f6dd3b6f212..a609724937a 100644 --- a/cpp/ql/src/Security/CWE/CWE-078/ExecTainted.ql +++ b/cpp/ql/src/Security/CWE/CWE-078/ExecTainted.ql @@ -49,11 +49,17 @@ predicate interestingConcatenation(DataFlow::Node incoming, DataFlow::Node outgo call.getTarget() = op and op.hasQualifiedName("std", "operator+") and op.getType().(UserType).hasQualifiedName("std", "basic_string") and - incoming.asIndirectArgument() = call.getArgument(1) and // left operand + incoming.asIndirectArgument() = call.getArgument(1) and // right operand call = outgoing.asInstruction().getUnconvertedResultExpression() ) } +/** + * A state will represent the most recent concatenation that occurred in the data flow. + * - `TConcatState` if the concetenation has not yet occurred. + * - `TExecState(incoming, outgoing)`, representing the concatenation of data from `incoming` + * into result `outgoing`. + */ newtype TState = TConcatState() or TExecState(DataFlow::Node incoming, DataFlow::Node outgoing) { @@ -74,7 +80,9 @@ class ExecState extends TExecState { DataFlow::Node getOutgoingNode() { result = outgoing } - /** Holds if this is a possible `ExecState` for `sink`. */ + /** + * Holds if this is a possible `ExecState` at `sink`, that is, if `outgoing` flows to `sink`. + */ predicate isFeasibleForSink(DataFlow::Node sink) { ExecState::flow(outgoing, sink) } string toString() { result = "ExecState" } @@ -110,6 +118,12 @@ module ExecStateConfig implements DataFlow::ConfigSig { module ExecState = TaintTracking::Global; +/** + * A full `TaintTracking` configuration from source to concatenation to sink, using a flow + * state to remember the concatenation. It's important that we track flow to the sink even though + * as soon as we reach the concatenation we know it will get there (due to the check of + * `isFeasibleForSink`), because this way we get a complete flow path. + */ module ExecTaintConfig implements DataFlow::StateConfigSig { class FlowState = TState;