openoffice: 2 defects (MOAD-0001 xestyle O(N²) border/fill dedup, MOAD-0004 WebDAV credential logging); scribus: MOADs 0002-0005 CLEAN
This commit is contained in:
parent
bc17a5e700
commit
595e96ffe1
9 changed files with 587 additions and 0 deletions
Binary file not shown.
|
|
@ -0,0 +1,126 @@
|
|||
import java.util.*;
|
||||
import java.util.regex.*;
|
||||
|
||||
/**
|
||||
* openoffice-0002: CurlSession::curlDebugOutput CWE-312 credential logging
|
||||
*
|
||||
* Models the HTTP header sanitization logic from curlDebugOutput (CurlSession.cxx).
|
||||
* Verifies that credential-bearing headers (Authorization, Proxy-Authorization,
|
||||
* Cookie, etc.) have their values redacted before logging, while non-sensitive
|
||||
* headers pass through unmodified.
|
||||
*
|
||||
* This is a unit test for the MOAD-0004 fix: lcl_IsCredentialHeader() +
|
||||
* lcl_RedactHeader() added to CurlSession.cxx.
|
||||
*/
|
||||
public class OpenOfficeWebDAVCredentialLogTest {
|
||||
|
||||
// ---- Model of the fix ----
|
||||
|
||||
static boolean isCredentialHeader(String header) {
|
||||
int colon = header.indexOf(':');
|
||||
if (colon <= 0) return false;
|
||||
String name = header.substring(0, colon).trim().toLowerCase();
|
||||
return name.equals("authorization")
|
||||
|| name.equals("proxy-authorization")
|
||||
|| name.equals("x-auth-token")
|
||||
|| name.equals("www-authenticate")
|
||||
|| name.equals("proxy-authenticate")
|
||||
|| name.equals("cookie")
|
||||
|| name.equals("set-cookie");
|
||||
}
|
||||
|
||||
static String redactHeader(String header) {
|
||||
int colon = header.indexOf(':');
|
||||
if (colon <= 0) return header;
|
||||
return header.substring(0, colon) + ": <redacted>";
|
||||
}
|
||||
|
||||
/** Defective logger: logs header verbatim */
|
||||
static String defectiveLogHeader(String header) {
|
||||
return "[CurlHDR ->] " + header;
|
||||
}
|
||||
|
||||
/** Fixed logger: sanitizes credential headers */
|
||||
static String fixedLogHeader(String header) {
|
||||
if (isCredentialHeader(header)) {
|
||||
return "[CurlHDR ->] " + redactHeader(header);
|
||||
}
|
||||
return "[CurlHDR ->] " + header;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println("=== openoffice-0002: WebDAV credential header redaction ===\n");
|
||||
|
||||
// Test cases: (header, shouldBeRedacted)
|
||||
Object[][] cases = {
|
||||
// Credential headers — must be redacted
|
||||
{ "Authorization: Basic dXNlcjpteXBhc3N3b3Jk", true },
|
||||
{ "Authorization: Digest username=\"user\", realm=\"realm\", response=\"abc123\"", true },
|
||||
{ "Proxy-Authorization: Basic cHJveHk6cGFzcw==", true },
|
||||
{ "Cookie: session=abc123; token=secretvalue", true },
|
||||
{ "Set-Cookie: auth_token=xyz789; HttpOnly", true },
|
||||
{ "X-Auth-Token: sk-live-abc123secret", true },
|
||||
{ "WWW-Authenticate: Basic realm=\"WebDAV\"", true },
|
||||
{ "Proxy-Authenticate: Digest realm=\"proxy\"", true },
|
||||
// Non-credential headers — must pass through unmodified
|
||||
{ "Content-Type: application/xml", false },
|
||||
{ "DAV: 1, 2, ordered-collections", false },
|
||||
{ "Host: dav.example.com", false },
|
||||
{ "User-Agent: OpenOffice/4.2", false },
|
||||
{ "Content-Length: 512", false },
|
||||
{ "Transfer-Encoding: chunked", false },
|
||||
};
|
||||
|
||||
int pass = 0, fail = 0;
|
||||
|
||||
for (Object[] tc : cases) {
|
||||
String header = (String) tc[0];
|
||||
boolean shouldRedact = (boolean) tc[1];
|
||||
|
||||
String defOut = defectiveLogHeader(header);
|
||||
String fixOut = fixedLogHeader(header);
|
||||
|
||||
boolean defContainsCred = !defOut.contains("<redacted>") && shouldRedact;
|
||||
boolean fixCorrect;
|
||||
|
||||
if (shouldRedact) {
|
||||
// Fixed output must contain <redacted> and NOT the original value after colon
|
||||
fixCorrect = fixOut.contains("<redacted>") && !fixOut.contains(header.substring(header.indexOf(':') + 1).trim());
|
||||
} else {
|
||||
// Fixed output must be identical to defective (non-sensitive header)
|
||||
fixCorrect = fixOut.equals(defOut);
|
||||
}
|
||||
|
||||
String status = fixCorrect ? "PASS" : "FAIL";
|
||||
if (fixCorrect) pass++; else fail++;
|
||||
|
||||
System.out.printf("[%s] %s%n", status, header.substring(0, Math.min(60, header.length())));
|
||||
if (!fixCorrect) {
|
||||
System.out.printf(" defective: %s%n", defOut);
|
||||
System.out.printf(" fixed: %s%n", fixOut);
|
||||
}
|
||||
}
|
||||
|
||||
System.out.printf("%n%d/%d tests passed%n", pass, pass + fail);
|
||||
|
||||
// Key assertion: Authorization: Basic base64 credential must not appear in fixed log
|
||||
String basicAuthHeader = "Authorization: Basic dXNlcjpteXBhc3N3b3Jk";
|
||||
String defLog = defectiveLogHeader(basicAuthHeader);
|
||||
String fixLog = fixedLogHeader(basicAuthHeader);
|
||||
|
||||
assert defLog.contains("dXNlcjpteXBhc3N3b3Jk") :
|
||||
"Defective log should contain credential (demonstrates the bug)";
|
||||
assert !fixLog.contains("dXNlcjpteXBhc3N3b3Jk") :
|
||||
"Fixed log must NOT contain base64 credential";
|
||||
assert fixLog.contains("<redacted>") :
|
||||
"Fixed log must contain <redacted> placeholder";
|
||||
|
||||
// Cookie session token must be redacted
|
||||
String cookieHeader = "Cookie: session=abc123; token=secretvalue";
|
||||
assert !fixedLogHeader(cookieHeader).contains("secretvalue") :
|
||||
"Fixed log must not expose cookie secret values";
|
||||
|
||||
assert fail == 0 : fail + " test(s) failed";
|
||||
System.out.println("\nALL ASSERTIONS PASS");
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue