java-topology/defects/musescore-0002/test/MuseScore0002Test.java
russell@unturf.com bbf4510d9d musescore+mixxx: 5-MOAD scan; 2 musescore defects, mixxx CLEAN
musescore-0001: CWE-407 pastedHarmony dedup uses std::vector+std::find
  O(A*H) in Read400/Read410/Read460::pasteStaff; fix: unordered_set O(A).
  100.5x op-count speedup at H=200 harmonies pasted. 1/1 PASS.

musescore-0002: CWE-312 OAuth access+refresh tokens logged verbatim via
  LOGD() in AbstractCloudService::onUserAuthorized(); fix: redact values.
  1/1 PASS.

mixxx: all 5 MOADs CLEAN. Only std::find on a 6-item capped list; all
  cache lookups use QHash/QSet O(1); GlobalTrackCache properly mutex-locked;
  no thread_local misuse; no credential values in log calls.
2026-03-31 21:18:03 -04:00

62 lines
2.7 KiB
Java

/**
* musescore-0002: CWE-312 OAuth access+refresh tokens logged verbatim.
*
* In AbstractCloudService::onUserAuthorized(), after a successful OAuth2
* authorization, both the access token and refresh token are logged at
* DEBUG level:
*
* LOGD() << "========== access " << m_accessToken
* << " ========= refresh " << m_refreshToken;
*
* This exposes long-lived credentials (refresh tokens don't expire until
* revoked) to any log collection pipeline, crash reporter, or developer
* who inspects a debug log file.
*
* Fix: redact token values in the log message.
*/
public class MuseScore0002Test {
// Simulate the defective log line (token values in output)
static String logDefective(String accessToken, String refreshToken) {
return "========== access " + accessToken + " ========= refresh " + refreshToken;
}
// Simulate the fixed log line (values redacted)
static String logFixed(String accessToken, String refreshToken) {
return "========== access [REDACTED] ========= refresh [REDACTED]";
}
public static void main(String[] args) {
System.out.println("musescore-0002: CWE-312 OAuth token logging");
String accessToken = "ya29.a0AfH6SMBx_REAL_ACCESS_TOKEN_abc123";
String refreshToken = "1//0gXYZ_REAL_REFRESH_TOKEN_longerlived";
// Defective: token appears in log
String defectiveLine = logDefective(accessToken, refreshToken);
assert defectiveLine.contains(accessToken) :
"defective log must contain access token value";
assert defectiveLine.contains(refreshToken) :
"defective log must contain refresh token value";
System.out.println(" Defective log: " + defectiveLine);
// Fixed: token does NOT appear in log
String fixedLine = logFixed(accessToken, refreshToken);
assert !fixedLine.contains(accessToken) :
"fixed log must NOT contain access token value";
assert !fixedLine.contains(refreshToken) :
"fixed log must NOT contain refresh token value";
assert fixedLine.contains("[REDACTED]") :
"fixed log must contain REDACTED marker";
System.out.println(" Fixed log: " + fixedLine);
// The fixed line must still convey the structure (for debugging flow)
assert fixedLine.contains("access") : "fixed log must retain 'access' label";
assert fixedLine.contains("refresh") : "fixed log must retain 'refresh' label";
System.out.println(" PASS: defective log exposes token values");
System.out.println(" PASS: fixed log redacts token values");
System.out.println(" PASS: fixed log retains structural labels");
System.out.println("PASS");
}
}