From eda33adafd10ac93017082807f619841190d758d Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 15 May 2026 21:07:45 +0100 Subject: [PATCH 1/3] C++: Add FP. --- .../CWE-311/semmle/tests/CleartextTransmission.expected | 2 ++ .../Security/CWE/CWE-311/semmle/tests/test3.cpp | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/CleartextTransmission.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/CleartextTransmission.expected index fae3d76599a8..641c38108d8a 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/CleartextTransmission.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/CleartextTransmission.expected @@ -138,6 +138,7 @@ nodes | test3.cpp:577:2:577:25 | ... = ... | semmle.label | ... = ... | | test3.cpp:577:8:577:23 | call to get_home_address | semmle.label | call to get_home_address | | test3.cpp:578:14:578:16 | str | semmle.label | str | +| test3.cpp:585:25:585:32 | password | semmle.label | password | subpaths | test3.cpp:138:24:138:32 | password1 | test3.cpp:117:28:117:33 | buffer | test3.cpp:117:13:117:14 | *id | test3.cpp:138:21:138:22 | call to id | #select @@ -181,3 +182,4 @@ subpaths | test3.cpp:559:3:559:6 | call to send | test3.cpp:556:19:556:30 | salaryString | test3.cpp:559:15:559:20 | *buffer | This operation transmits '*buffer', which may contain unencrypted sensitive data from $@. | test3.cpp:556:19:556:30 | salaryString | salaryString | | test3.cpp:572:2:572:5 | call to send | test3.cpp:571:8:571:21 | call to get_home_phone | test3.cpp:572:14:572:16 | str | This operation transmits 'str', which may contain unencrypted sensitive data from $@. | test3.cpp:571:8:571:21 | call to get_home_phone | call to get_home_phone | | test3.cpp:578:2:578:5 | call to send | test3.cpp:577:8:577:23 | call to get_home_address | test3.cpp:578:14:578:16 | str | This operation transmits 'str', which may contain unencrypted sensitive data from $@. | test3.cpp:577:8:577:23 | call to get_home_address | call to get_home_address | +| test3.cpp:585:2:585:7 | call to fscanf | test3.cpp:585:25:585:32 | password | test3.cpp:585:25:585:32 | password | This operation receives into 'password', which may put unencrypted sensitive data into $@. | test3.cpp:585:25:585:32 | password | password | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/test3.cpp b/cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/test3.cpp index f4bfe5ca3405..cc4748c30fe6 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/test3.cpp +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/test3.cpp @@ -577,3 +577,10 @@ void tests3() str = get_home_address(); send(val(), str, strlen(str), val()); // BAD } + +int fscanf(FILE* stream, const char* format, ... ); + +void test_scanf() { + char password[256]; + fscanf(stdin, "%255s", password); // GOOD [FALSE POSITIVE]: this is not a remote source +} \ No newline at end of file From 4396e66f3565a074403849b5da59d64816fcb3da Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 15 May 2026 21:12:34 +0100 Subject: [PATCH 2/3] C++: Fix FP by providing an implementation of 'hasSocketInput'. --- cpp/ql/lib/semmle/code/cpp/models/implementations/Scanf.qll | 4 ++++ .../CWE/CWE-311/semmle/tests/CleartextTransmission.expected | 2 -- .../query-tests/Security/CWE/CWE-311/semmle/tests/test3.cpp | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Scanf.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Scanf.qll index fbef5a8fcac5..f1b3edbe3370 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Scanf.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Scanf.qll @@ -87,6 +87,10 @@ private class FscanfModel extends ScanfFunctionModel, RemoteFlowSourceFunction i output.isParameterDeref(any(int i | i >= this.getArgsStartPosition())) and description = "value read by " + this.getName() } + + override predicate hasSocketInput(FunctionInput input) { + input.isParameterDeref(super.getInputParameterIndex()) + } } /** diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/CleartextTransmission.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/CleartextTransmission.expected index 641c38108d8a..fae3d76599a8 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/CleartextTransmission.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/CleartextTransmission.expected @@ -138,7 +138,6 @@ nodes | test3.cpp:577:2:577:25 | ... = ... | semmle.label | ... = ... | | test3.cpp:577:8:577:23 | call to get_home_address | semmle.label | call to get_home_address | | test3.cpp:578:14:578:16 | str | semmle.label | str | -| test3.cpp:585:25:585:32 | password | semmle.label | password | subpaths | test3.cpp:138:24:138:32 | password1 | test3.cpp:117:28:117:33 | buffer | test3.cpp:117:13:117:14 | *id | test3.cpp:138:21:138:22 | call to id | #select @@ -182,4 +181,3 @@ subpaths | test3.cpp:559:3:559:6 | call to send | test3.cpp:556:19:556:30 | salaryString | test3.cpp:559:15:559:20 | *buffer | This operation transmits '*buffer', which may contain unencrypted sensitive data from $@. | test3.cpp:556:19:556:30 | salaryString | salaryString | | test3.cpp:572:2:572:5 | call to send | test3.cpp:571:8:571:21 | call to get_home_phone | test3.cpp:572:14:572:16 | str | This operation transmits 'str', which may contain unencrypted sensitive data from $@. | test3.cpp:571:8:571:21 | call to get_home_phone | call to get_home_phone | | test3.cpp:578:2:578:5 | call to send | test3.cpp:577:8:577:23 | call to get_home_address | test3.cpp:578:14:578:16 | str | This operation transmits 'str', which may contain unencrypted sensitive data from $@. | test3.cpp:577:8:577:23 | call to get_home_address | call to get_home_address | -| test3.cpp:585:2:585:7 | call to fscanf | test3.cpp:585:25:585:32 | password | test3.cpp:585:25:585:32 | password | This operation receives into 'password', which may put unencrypted sensitive data into $@. | test3.cpp:585:25:585:32 | password | password | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/test3.cpp b/cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/test3.cpp index cc4748c30fe6..35700d229e75 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/test3.cpp +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/test3.cpp @@ -582,5 +582,5 @@ int fscanf(FILE* stream, const char* format, ... ); void test_scanf() { char password[256]; - fscanf(stdin, "%255s", password); // GOOD [FALSE POSITIVE]: this is not a remote source + fscanf(stdin, "%255s", password); // GOOD: this is not a remote source } \ No newline at end of file From 8ce601b1d78ccbdc91621364c343f9a289bf7fa3 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 15 May 2026 21:22:38 +0100 Subject: [PATCH 3/3] C++: Add change notes. --- .../lib/change-notes/2026-05-15-hasSocketInput-for-fscanf.md | 4 ++++ .../src/change-notes/2026-05-15-cleartext-transmission-fp.md | 4 ++++ 2 files changed, 8 insertions(+) create mode 100644 cpp/ql/lib/change-notes/2026-05-15-hasSocketInput-for-fscanf.md create mode 100644 cpp/ql/src/change-notes/2026-05-15-cleartext-transmission-fp.md diff --git a/cpp/ql/lib/change-notes/2026-05-15-hasSocketInput-for-fscanf.md b/cpp/ql/lib/change-notes/2026-05-15-hasSocketInput-for-fscanf.md new file mode 100644 index 000000000000..842d52dd8bfd --- /dev/null +++ b/cpp/ql/lib/change-notes/2026-05-15-hasSocketInput-for-fscanf.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The `RemoteFlowSourceFunction` model for `fscanf` (and variants) now implements `hasSocketInput` to reflect that these functions may read from a socket. \ No newline at end of file diff --git a/cpp/ql/src/change-notes/2026-05-15-cleartext-transmission-fp.md b/cpp/ql/src/change-notes/2026-05-15-cleartext-transmission-fp.md new file mode 100644 index 000000000000..6fcb3e1c88b2 --- /dev/null +++ b/cpp/ql/src/change-notes/2026-05-15-cleartext-transmission-fp.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The 'Cleartext transmission of sensitive information' query (`cpp/cleartext-transmission`) no longer raises an alert on calls to `fscanf` (and variants) when the call reads from an "obviously local" `FILE` stream such as `stdin`. \ No newline at end of file