131 lines
4.5 KiB
Java
131 lines
4.5 KiB
Java
import java.util.ArrayList;
|
|
import java.util.List;
|
|
|
|
/**
|
|
* Test for esp-idf-0001: CWE-312 WiFi password logged verbatim via ESP_LOGD
|
|
* in components/esp_wifi/src/smartconfig.c handler_got_ssid_passwd().
|
|
*
|
|
* Pattern:
|
|
* ESP_LOGD(TAG, "PASSWORD:%s", password)
|
|
*
|
|
* When debug logging is enabled the WiFi PSK (pre-shared key) is emitted
|
|
* verbatim to serial/JTAG output. Any listener on those interfaces obtains
|
|
* the plaintext credential without any further effort.
|
|
*
|
|
* Fix: remove the ESP_LOGD("PASSWORD:%s", ...) line. SSID logging (non-secret)
|
|
* is acceptable; PSK logging is not.
|
|
*
|
|
* Compile and run (no build tool required):
|
|
* javac defects/esp-idf-0001/test/EspIdf0001Test.java -d /tmp/esp-idf-0001
|
|
* java -cp /tmp/esp-idf-0001 EspIdf0001Test
|
|
*/
|
|
public class EspIdf0001Test {
|
|
|
|
private static int passed = 0;
|
|
private static int failed = 0;
|
|
|
|
// --- Simulated log collector ---
|
|
|
|
static class LogCollector {
|
|
private final List<String> lines = new ArrayList<>();
|
|
|
|
void logd(String tag, String fmt, Object... args) {
|
|
lines.add(String.format(fmt, args));
|
|
}
|
|
|
|
boolean containsText(String text) {
|
|
for (String line : lines) {
|
|
if (line.contains(text)) return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
int size() { return lines.size(); }
|
|
}
|
|
|
|
// --- Defective: logs password in DEBUG output ---
|
|
|
|
static void handleGotSsidPasswdDefective(String ssid, String password, LogCollector log) {
|
|
log.logd("smartconfig", "SSID:%s", ssid);
|
|
log.logd("smartconfig", "PASSWORD:%s", password); // CWE-312 site
|
|
log.logd("smartconfig", "Phone ip: 192.168.1.1");
|
|
}
|
|
|
|
// --- Fixed: password line removed ---
|
|
|
|
static void handleGotSsidPasswdFixed(String ssid, String password, LogCollector log) {
|
|
log.logd("smartconfig", "SSID:%s", ssid);
|
|
// PASSWORD log line removed — fix for esp-idf-0001
|
|
log.logd("smartconfig", "Phone ip: 192.168.1.1");
|
|
}
|
|
|
|
// --- Tests ---
|
|
|
|
static void testDefectiveLogsPassword() {
|
|
LogCollector log = new LogCollector();
|
|
String password = "MySecretWiFiPSK123";
|
|
handleGotSsidPasswdDefective("MyNet", password, log);
|
|
check("defective must log the password (confirms CWE-312 site is present)",
|
|
log.containsText(password));
|
|
}
|
|
|
|
static void testFixedDoesNotLogPassword() {
|
|
LogCollector log = new LogCollector();
|
|
String password = "MySecretWiFiPSK123";
|
|
handleGotSsidPasswdFixed("MyNet", password, log);
|
|
check("fixed must NOT log the WiFi PSK in any log line",
|
|
!log.containsText(password));
|
|
}
|
|
|
|
static void testFixedStillLogsSsid() {
|
|
LogCollector log = new LogCollector();
|
|
handleGotSsidPasswdFixed("HomeNetwork_5GHz", "secret", log);
|
|
check("SSID (non-sensitive) must still appear in logs after fix",
|
|
log.containsText("HomeNetwork_5GHz"));
|
|
}
|
|
|
|
static void testFixedHasFewerLines() {
|
|
LogCollector defLog = new LogCollector();
|
|
LogCollector fixLog = new LogCollector();
|
|
handleGotSsidPasswdDefective("net", "pw", defLog);
|
|
handleGotSsidPasswdFixed("net", "pw", fixLog);
|
|
check("fixed version produces fewer log lines than defective",
|
|
fixLog.size() < defLog.size());
|
|
}
|
|
|
|
static void testPasswordNotLeakedAcrossMultipleCalls() {
|
|
// Simulate multiple smartconfig events — none should leak password
|
|
String[] passwords = {"PSK-alpha", "PSK-beta", "PSK-gamma"};
|
|
for (String pw : passwords) {
|
|
LogCollector log = new LogCollector();
|
|
handleGotSsidPasswdFixed("net", pw, log);
|
|
check("password '" + pw + "' must not appear in any log line",
|
|
!log.containsText(pw));
|
|
}
|
|
}
|
|
|
|
// --- Harness ---
|
|
|
|
static void check(String desc, boolean cond) {
|
|
if (cond) {
|
|
System.out.println(" PASS: " + desc);
|
|
passed++;
|
|
} else {
|
|
System.out.println(" FAIL: " + desc);
|
|
failed++;
|
|
}
|
|
}
|
|
|
|
public static void main(String[] args) {
|
|
System.out.println("=== EspIdf0001Test (CWE-312 WiFi PSK logged) ===\n");
|
|
|
|
testDefectiveLogsPassword();
|
|
testFixedDoesNotLogPassword();
|
|
testFixedStillLogsSsid();
|
|
testFixedHasFewerLines();
|
|
testPasswordNotLeakedAcrossMultipleCalls();
|
|
|
|
System.out.println("\n--- " + passed + " passed, " + failed + " failed ---");
|
|
if (failed > 0) System.exit(1);
|
|
}
|
|
}
|