fix(audit): address code review - header validation, touch targets, env.demo cleanup

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-03-09 23:33:43 +00:00
parent 3b491ea84c
commit 653c137222
3 changed files with 14 additions and 4 deletions
-2
View File
@@ -96,8 +96,6 @@ MAX_UPLOAD_SIZE=1073741824
# Allowed request headers (use * to allow all)
# CORS_ALLOWED_HEADERS=*
# **Rate Limiting** (see SECURITY_AUDIT.md and docs/API.md)
# **Audit Logging & SIEM Integration** (see docs/ConfigurationGuide.md#audit-logging)
# Enable HTTP request audit logging middleware
AUDIT_LOGGING_ENABLED=true
+13 -1
View File
@@ -12,6 +12,7 @@ Supported SIEM transports:
import json
import logging
import re
import socket
import threading
from datetime import datetime, timezone
@@ -297,13 +298,24 @@ def _send_http(payload: dict[str, Any]) -> None:
headers["Authorization"] = f"Bearer {token}"
# Parse custom headers (comma-separated "Key:Value" pairs).
# Reject headers that could override security-critical ones already set,
# and validate that header names contain only RFC 7230 token characters.
_PROTECTED_HEADERS = {"authorization", "content-type", "host"}
_VALID_HEADER_NAME = re.compile(r"^[A-Za-z0-9!#$%&'*+\-.^_`|~]+$")
raw_custom = settings.audit_siem_http_custom_headers
if raw_custom:
for raw_pair in raw_custom.split(","):
pair = raw_pair.strip()
if ":" in pair:
k, _, v = pair.partition(":")
headers[k.strip()] = v.strip()
name = k.strip()
if not name or not _VALID_HEADER_NAME.match(name):
logger.warning("Skipping invalid SIEM custom header name: %r", name)
continue
if name.lower() in _PROTECTED_HEADERS:
logger.warning("Skipping protected SIEM custom header: %r", name)
continue
headers[name] = v.strip()
# Wrap in Splunk HEC-style envelope when URL contains ``/services/collector``.
body: dict[str, Any]
+1 -1
View File
@@ -72,7 +72,7 @@
<label for="filter-resource" class="block text-xs font-medium text-gray-500 dark:text-gray-400 mb-1">Resource Type</label>
<input id="filter-resource" type="text" x-model.debounce.300ms="filters.resource_type" @input="fetchLogs()"
placeholder="e.g. document, user"
class="w-full rounded-md border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-white text-sm">
class="w-full rounded-md border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-white text-sm min-h-[44px]">
</div>
</div>
</section>