diff --git a/README.md b/README.md index 04d54e3..8a2fe74 100644 --- a/README.md +++ b/README.md @@ -117,7 +117,6 @@ Each log entry is a single-line JSON object with a flat structure: "http_version": "HTTP/1.1", "header_X-Request-Id": "abcd-1234", "header_User-Agent": "curl/7.70.0" - } } ``` @@ -135,7 +134,9 @@ Each log entry is a single-line JSON object with a flat structure: | `path` | String | Request path | | `host` | String | Host header value | | `http_version` | String | HTTP protocol version | -| `headers` | Object | Configured HTTP headers | +| `header_` | String | Flattened HTTP headers (e.g., `header_X-Request-Id`) | + +**Note:** Headers are logged as flat fields at the root level (not nested). Sensitive headers are automatically excluded. ## Unix Socket Consumer @@ -147,7 +148,7 @@ import socket import os import json -SOCKET_PATH = "/var/run/mod_reqin_log.sock" +SOCKET_PATH = os.environ.get("MOD_REQIN_LOG_SOCKET", "/var/run/mod_reqin_log.sock") # Remove existing socket file if os.path.exists(SOCKET_PATH): @@ -157,7 +158,8 @@ if os.path.exists(SOCKET_PATH): server = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) server.bind(SOCKET_PATH) server.listen(5) -os.chmod(SOCKET_PATH, 0o666) +# Set secure permissions: owner and group only (not world-writable) +os.chmod(SOCKET_PATH, 0o660) print(f"Listening on {SOCKET_PATH}") @@ -178,13 +180,37 @@ while True: conn.close() ``` +**Note:** Ensure the Apache user is in the socket file's group to allow connections. + ## Security Considerations -⚠️ **Important**: This module logs all HTTP requests transparently. +### Built-in Sensitive Headers Blacklist -- **Do not log sensitive headers**: Avoid including `Authorization`, `Cookie`, `X-Api-Key`, or other sensitive headers in `JsonSockLogHeaders` -- **Socket permissions**: Ensure the Unix socket has appropriate file permissions -- **Log consumer security**: Protect the socket consumer from unauthorized access +⚠️ **The module automatically blocks logging of sensitive headers:** + +The following headers are **always excluded** from logs to prevent credential leakage: +- `Authorization` +- `Cookie`, `Set-Cookie` +- `X-Api-Key`, `X-Auth-Token` +- `Proxy-Authorization` +- `WWW-Authenticate` + +These headers are silently skipped (logged at DEBUG level only). + +### Socket Security + +- **Socket permissions**: Default to `0o660` (owner and group only) +- **Recommended path**: `/var/run/mod_reqin_log.sock` (not `/tmp`) +- **Environment variable**: Use `MOD_REQIN_LOG_SOCKET` to configure path +- **Group membership**: Ensure Apache user is in the socket's group + +### Additional Hardening + +- **Socket path length**: Validated against system limit (108 bytes max) +- **JSON size limit**: 64KB max per log line (prevents memory DoS) +- **NULL pointer checks**: All connection/request fields validated +- **Thread safety**: Mutex protects socket FD in worker/event MPMs +- **Error logging**: Generic messages in error_log, details at DEBUG level ## Troubleshooting diff --git a/architecture.yml b/architecture.yml index 3ebb28c..02deee4 100644 --- a/architecture.yml +++ b/architecture.yml @@ -198,11 +198,12 @@ configuration: - JsonSockLogEnabled must be On. - JsonSockLogSocket must be set to a non-empty path. header_handling: - - No built-in blacklist; admin is fully responsible for excluding - sensitive headers (Authorization, Cookie, etc.). + - Built-in blacklist prevents logging of sensitive headers by default. + - Blacklisted headers: Authorization, Cookie, Set-Cookie, X-Api-Key, + X-Auth-Token, Proxy-Authorization, WWW-Authenticate. + - Blacklisted headers are silently skipped (logged at DEBUG level only). - If a configured header is absent in a request, the corresponding - JSON key may be omitted or set to null (implementation choice, but - must be consistent). + JSON key is omitted from the log entry. - Header values are truncated to JsonSockLogMaxHeaderValueLen characters. io: @@ -274,9 +275,19 @@ constraints: - Avoid reconnect attempts on every request via time-based backoff. security: notes: - - Module does not anonymize IPs nor scrub headers; it is intentionally - transparent. Data protection and header choices are delegated to configuration. + - Module includes built-in blacklist of sensitive headers to prevent + accidental credential leakage (Authorization, Cookie, X-Api-Key, etc.). + - Socket permissions default to 0o660 (owner+group only) for security. + - Recommended socket path: /var/run/mod_reqin_log.sock (not /tmp). + - Use environment variable MOD_REQIN_LOG_SOCKET to configure socket path. + - Module does not anonymize IPs; data protection is delegated to configuration. - No requests are rejected due to logging failures. + hardening: + - Socket path length validated against system limit (108 bytes). + - JSON log line size limited to 64KB to prevent memory exhaustion DoS. + - NULL pointer checks on all connection/request fields. + - Thread-safe socket FD access via mutex (worker/event MPMs). + - Error logging reduced to prevent information disclosure. robustness: requirements: - Logging failures must not crash Apache worker processes.