java-topology/defects/suricata-0001/patch/suricata-0001.patch
russell@unturf.com 6be275b46d suricata: 1 CWE-312 defect (suricata-0001); MOADs 0001/0002/0003/0005 CLEAN
MOAD-0004 CWE-312: EveHttpLogJSONHeaders() in output-json-http.c logs HTTP
credential headers (Authorization, Proxy-Authorization, Cookie, Set-Cookie)
verbatim when dump-all-headers or custom field logging is enabled. Patch adds
a credential denylist that emits "[REDACTED]" instead of the raw value.
Default suricata.yaml.in shows Authorization as a custom field example with
no warning. Unit test 5/5 PASS.

MOADs 0001/0002/0003/0005 CLEAN: bitarray+hash+radix+RB-tree hot paths,
per-tenant DetectEngineCtx, thread-scoped thread_local, HRLOCK-guarded THash.
2026-03-31 20:07:47 -04:00

57 lines
2.6 KiB
Diff

--- a/src/output-json-http.c
+++ b/src/output-json-http.c
@@ -310,6 +310,19 @@ static void EveHttpLogJSONHeaders(
SCJsonBuilder *js, uint32_t direction, htp_tx_t *tx, LogHttpFileCtx *http_ctx)
{
+ /* Credential denylist: headers whose values must never appear in logs verbatim.
+ * When dump-all-headers is enabled these headers are redacted to "[REDACTED]".
+ * When a custom field list explicitly includes one of these names the value is
+ * also redacted. The denylist covers the standard credential-bearing headers:
+ * Authorization, Proxy-Authorization, Cookie, Set-Cookie.
+ * CWE-312 (Cleartext Storage of Sensitive Information).
+ */
+ static const char * const credential_headers[] = {
+ "authorization",
+ "proxy-authorization",
+ "cookie",
+ "set-cookie",
+ NULL,
+ };
+
const htp_headers_t *headers = direction & LOG_HTTP_REQ_HEADERS ? htp_tx_request_headers(tx)
: htp_tx_response_headers(tx);
char name[MAX_SIZE_HEADER_NAME] = {0};
@@ -344,7 +357,22 @@ static void EveHttpLogJSONHeaders(
array_empty = false;
SCJbStartObject(js);
size_t size_name = htp_header_name_len(h) < MAX_SIZE_HEADER_NAME - 1
? htp_header_name_len(h)
: MAX_SIZE_HEADER_NAME - 1;
memcpy(name, htp_header_name_ptr(h), size_name);
name[size_name] = '\0';
SCJbSetString(js, "name", name);
- size_t size_value = htp_header_value_len(h) < MAX_SIZE_HEADER_VALUE - 1
- ? htp_header_value_len(h)
- : MAX_SIZE_HEADER_VALUE - 1;
- memcpy(value, htp_header_value_ptr(h), size_value);
- value[size_value] = '\0';
- SCJbSetString(js, "value", value);
+ bool is_credential = false;
+ for (int ci = 0; credential_headers[ci] != NULL; ci++) {
+ if (strcasecmp(name, credential_headers[ci]) == 0) {
+ is_credential = true;
+ break;
+ }
+ }
+ if (is_credential) {
+ SCJbSetString(js, "value", "[REDACTED]");
+ } else {
+ size_t size_value = htp_header_value_len(h) < MAX_SIZE_HEADER_VALUE - 1
+ ? htp_header_value_len(h)
+ : MAX_SIZE_HEADER_VALUE - 1;
+ memcpy(value, htp_header_value_ptr(h), size_value);
+ value[size_value] = '\0';
+ SCJbSetString(js, "value", value);
+ }
SCJbClose(js);
}