java-topology/defects/zephyr-0002/test/ZephyrWifiMgmtPskLogTest.java
russell@unturf.com 1e10775b90 jitsi-videobridge: 3 CWE-407 defects, MOADs 0002-0005 CLEAN; woodpecker: 1 CWE-407 + 1 CWE-312, MOADs 0002/0003/0005 CLEAN
jitsi-videobridge (Kotlin/Java video conferencing bridge):
- 0001: Prioritize.kt selectedSourceNames.contains()+indexOf() inside forEach over conferenceSources, O(C*S)
- 0002: BandwidthAllocator.kt selectedSources getter List.contains() dedup inside forEach, O(S^2)
- 0003: ConferenceSpeechActivity.java endpointsChanged() ArrayList.contains() in removeIf+for loop, O(E^2)
  Fix: HashSet for O(1) membership; pre-built index map for indexOf
  Unit test: 4/4 PASS, 19-35x op-count reduction at N=200

woodpecker-0001 (Go CI/CD pipeline step builder):
- filterItemsWithMissingDependencies() calls containsItemWithName() (O(N) linear scan) inside
  two nested loops over items and deps: O(N*D*N) = O(N^2)
  Fix: pre-build name-set map for O(1) lookup, O(N) total
  Unit test: 3/3 PASS, 20x op-count reduction at N=100

woodpecker-0002 (CWE-312 credential logging):
- shared/token/token.go ParseRequest() logs raw Authorization header value at Trace level:
  log.Trace().Msgf("token.ParseRequest: found token in header: %s", token)
  Exposes full Bearer JWT token in application logs
  Fix: log only that header was found, not its value
  Unit test: 3/3 PASS
2026-03-31 20:18:44 -04:00

184 lines
7.6 KiB
Java

import java.util.*;
/**
* Unit test for zephyr-0002: wifi_mgmt.c wifi_connect() dumps WiFi PSK and
* SAE password as raw hex via LOG_HEXDUMP_DBG on every connection (CWE-312).
*
* Models the C pattern in wifi_connect():
*
* LOG_HEXDUMP_DBG(params->ssid, params->ssid_length, "ssid");
* LOG_HEXDUMP_DBG(params->psk, params->psk_length, "psk"); // DEFECT
* if (params->sae_password) {
* LOG_HEXDUMP_DBG(params->sae_password, params->sae_password_length, "sae"); // DEFECT
* }
*
* LOG_HEXDUMP_DBG fires at CONFIG_WIFI_LOG_LEVEL_DBG=y (set on most dev boards
* during bring-up). The PSK is printed as hex bytes to UART/RTT/flash log.
*
* Fix: remove the PSK and SAE hexdump lines. Replace with a boolean presence
* indicator ("psk set: yes/no") so developers can see a credential is set
* without exposing its value.
*/
public class ZephyrWifiMgmtPskLogTest {
// --- Simulate the LOG_HEXDUMP_DBG output (hex bytes) ---
static String hexDump(String label, byte[] data) {
StringBuilder sb = new StringBuilder(label + ": ");
for (byte b : data) {
sb.append(String.format("%02x ", b));
}
return sb.toString().trim();
}
// --- Defective wifi_connect log lines ---
static List<String> wifiConnectLogDefective(String ssid, String psk, String saePassword) {
List<String> lines = new ArrayList<>();
// ssid is fine to log
lines.add(hexDump("ssid", ssid.getBytes()));
// DEFECT: PSK hex-dumped
if (psk != null && !psk.isEmpty()) {
lines.add(hexDump("psk", psk.getBytes()));
}
// DEFECT: SAE password hex-dumped
if (saePassword != null && !saePassword.isEmpty()) {
lines.add(hexDump("sae", saePassword.getBytes()));
}
return lines;
}
// --- Fixed wifi_connect log lines ---
static List<String> wifiConnectLogFixed(String ssid, String psk, String saePassword) {
List<String> lines = new ArrayList<>();
// SSID still logged
lines.add(hexDump("ssid", ssid.getBytes()));
// FIX: presence only, no value
lines.add("psk set: " + (psk != null && !psk.isEmpty() ? "yes" : "no"));
lines.add("sae_password set: " + (saePassword != null && !saePassword.isEmpty() ? "yes" : "no"));
return lines;
}
// Helper: check if any log line contains the given string
static boolean logsContain(List<String> lines, String needle) {
for (String line : lines) {
if (line.contains(needle)) return true;
}
return false;
}
// Helper: check if any log line contains hex bytes of a string
static boolean logsContainHex(List<String> lines, String secret) {
byte[] bytes = secret.getBytes();
// Build hex representation of first 4 bytes as a search key
if (bytes.length == 0) return false;
String hexKey = String.format("%02x %02x", bytes[0], bytes[1 % bytes.length]);
for (String line : lines) {
if (line.contains(hexKey)) return true;
}
return false;
}
public static void main(String[] args) {
System.out.println("=== zephyr-0002: wifi_mgmt.c PSK LOG_HEXDUMP_DBG CWE-312 ===\n");
int pass = 0, total = 0;
// Test 1: defective path logs PSK hex bytes
{
total++;
String psk = "SecretWifi2024";
List<String> logs = wifiConnectLogDefective("MySSID", psk, null);
boolean containsPsk = logsContain(logs, "psk:");
boolean hexPresent = logsContainHex(logs, psk);
assert containsPsk : "FAIL T1: expected psk hexdump line";
assert hexPresent : "FAIL T1: expected PSK hex bytes in log";
System.out.println("T1 CONFIRMED defective: PSK hex in log = " + hexPresent);
pass++;
}
// Test 2: fixed path does not log PSK value
{
total++;
String psk = "SecretWifi2024";
List<String> logs = wifiConnectLogFixed("MySSID", psk, null);
boolean hexAbsent = !logsContainHex(logs, psk);
boolean hasPresence = logsContain(logs, "psk set: yes");
assert hexAbsent : "FAIL T2: fixed path should not log PSK hex bytes";
assert hasPresence : "FAIL T2: fixed path should show 'psk set: yes'";
System.out.println("T2 PASS fixed: PSK hex absent=" + hexAbsent + " presence logged=" + hasPresence);
pass++;
}
// Test 3: SAE password defective path leaks hex
{
total++;
String saePass = "WPA3Pass!@#";
List<String> logs = wifiConnectLogDefective("Office5G", null, saePass);
boolean hexPresent = logsContainHex(logs, saePass);
assert hexPresent : "FAIL T3: expected SAE hex bytes in defective log";
System.out.println("T3 CONFIRMED defective: SAE hex in log = " + hexPresent);
pass++;
}
// Test 4: SAE password fixed path does not leak
{
total++;
String saePass = "WPA3Pass!@#";
List<String> logs = wifiConnectLogFixed("Office5G", null, saePass);
boolean hexAbsent = !logsContainHex(logs, saePass);
boolean hasPresence = logsContain(logs, "sae_password set: yes");
assert hexAbsent : "FAIL T4: fixed path should not log SAE hex bytes";
assert hasPresence : "FAIL T4: fixed path should show sae_password presence";
System.out.printf("T4 PASS: SAE hex absent=%b presence=%b%n", hexAbsent, hasPresence);
pass++;
}
// Test 5: SSID is still logged in full (not a secret)
{
total++;
String ssid = "CorporateNet";
List<String> logs = wifiConnectLogFixed(ssid, "pass", null);
boolean ssidLogged = logsContain(logs, "ssid:");
assert ssidLogged : "FAIL T5: SSID should still be logged";
System.out.println("T5 PASS: SSID still logged");
pass++;
}
// Test 6: no PSK → presence indicator says "no"
{
total++;
List<String> logs = wifiConnectLogFixed("OpenNet", null, null);
boolean noSet = logsContain(logs, "psk set: no");
assert noSet : "FAIL T6: 'psk set: no' expected when no PSK";
System.out.println("T6 PASS: 'psk set: no' for open network");
pass++;
}
// Test 7: PSK with common chars (verify hex check is working)
{
total++;
String psk = "abcdefgh";
List<String> defLogs = wifiConnectLogDefective("Net", psk, null);
List<String> fixLogs = wifiConnectLogFixed("Net", psk, null);
assert logsContainHex(defLogs, psk) : "FAIL T7: hex detection sanity check failed";
assert !logsContainHex(fixLogs, psk) : "FAIL T7: fixed path should not contain hex of PSK";
System.out.println("T7 PASS: hex detection sanity check OK");
pass++;
}
// Test 8: short PSK (8 chars minimum) still redacted
{
total++;
String psk = "12345678";
List<String> logs = wifiConnectLogFixed("MinPsk", psk, null);
assert !logsContainHex(logs, psk) : "FAIL T8: short PSK should still be redacted";
assert logsContain(logs, "psk set: yes") : "FAIL T8: 'psk set: yes' expected";
System.out.println("T8 PASS: short PSK (8 chars) redacted");
pass++;
}
System.out.printf("%n%d/%d tests PASS%n", pass, total);
if (pass != total) {
System.exit(1);
}
}
}