Skip to content

Commit 1192937

Browse files
committed
C++: Upgrade cpp/cleartext-storage-file to full taint flow.
1 parent 75f3897 commit 1192937

File tree

3 files changed

+26
-5
lines changed

3 files changed

+26
-5
lines changed

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

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,20 @@ import semmle.code.cpp.security.SensitiveExprs
1717
import semmle.code.cpp.security.FileWrite
1818
import semmle.code.cpp.dataflow.DataFlow
1919
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
20+
import semmle.code.cpp.dataflow.TaintTracking
21+
22+
/**
23+
* Taint flow from a sensitive expression to a `FileWrite` sink.
24+
*/
25+
class FromSensitiveConfiguration extends TaintTracking::Configuration {
26+
FromSensitiveConfiguration() { this = "FromSensitiveConfiguration" }
27+
28+
override predicate isSource(DataFlow::Node source) { source.asExpr() instanceof SensitiveExpr }
29+
30+
override predicate isSink(DataFlow::Node sink) {
31+
any(FileWrite w).getASource() = sink.asExpr()
32+
}
33+
}
2034

2135
/**
2236
* An operation on a filename.
@@ -43,9 +57,13 @@ predicate isFileName(GVN gvn) {
4357
)
4458
}
4559

46-
from FileWrite w, SensitiveExpr source, Expr mid, Expr dest
60+
from FromSensitiveConfiguration config, SensitiveExpr source, Expr mid, FileWrite w, Expr dest
4761
where
48-
DataFlow::localFlow(DataFlow::exprNode(source), DataFlow::exprNode(mid)) and
62+
exists(DataFlow::PathNode s, DataFlow::PathNode m |
63+
config.hasFlowPath(s, m) and
64+
s.getNode().asExpr() = source and
65+
m.getNode().asExpr() = mid
66+
) and
4967
mid = w.getASource() and
5068
dest = w.getDest() and
5169
not isFileName(globalValueNumber(source)) and // file names are not passwords

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
| test2.cpp:55:2:55:8 | call to fprintf | This write into file 'log' may contain unencrypted data from $@ | test2.cpp:55:40:55:51 | widepassword | this source. |
66
| test2.cpp:57:2:57:8 | call to fprintf | This write into file 'log' may contain unencrypted data from $@ | test2.cpp:57:39:57:49 | call to getPassword | this source. |
77
| test2.cpp:65:3:65:9 | call to fprintf | This write into file 'log' may contain unencrypted data from $@ | test2.cpp:62:18:62:25 | password | this source. |
8+
| test2.cpp:73:3:73:9 | call to fprintf | This write into file 'log' may contain unencrypted data from $@ | test2.cpp:72:17:72:24 | password | this source. |
9+
| test2.cpp:76:3:76:9 | call to fprintf | This write into file 'log' may contain unencrypted data from $@ | test2.cpp:72:17:72:24 | password | this source. |
10+
| test2.cpp:92:3:92:9 | call to fprintf | This write into file 'log' may contain unencrypted data from $@ | test2.cpp:91:45:91:52 | password | this source. |
811
| test.cpp:45:3:45:7 | call to fputs | This write into file 'file' may contain unencrypted data from $@ | test.cpp:45:9:45:19 | thePassword | this source. |
912
| test.cpp:70:35:70:35 | call to operator<< | This write into file 'mystream' may contain unencrypted data from $@ | test.cpp:70:38:70:48 | thePassword | this source. |
1013
| test.cpp:73:37:73:41 | call to write | This write into file 'mystream' may contain unencrypted data from $@ | test.cpp:73:43:73:53 | thePassword | this source. |

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,10 @@ void tests(FILE *log, myStruct &s)
7070
char buf[1024];
7171

7272
strcpy(buf, s.password);
73-
fprintf(log, "buf = %s\n", buf); // BAD [NOT DETECTED]
73+
fprintf(log, "buf = %s\n", buf); // BAD
7474

7575
strcpy(buf, s.password_hash);
76-
fprintf(log, "buf = %s\n", buf); // GOOD
76+
fprintf(log, "buf = %s\n", buf); // GOOD [FALSE POSITIVE]
7777
}
7878

7979
fprintf(log, "password = %p\n", s.password); // GOOD
@@ -89,6 +89,6 @@ void tests(FILE *log, myStruct &s)
8989
char buffer[1024];
9090

9191
snprintf(buffer, 1024, "password = %s", s.password);
92-
fprintf(log, "log: %s", buffer); // BAD [NOT DETECTED]
92+
fprintf(log, "log: %s", buffer); // BAD
9393
}
9494
}

0 commit comments

Comments
 (0)