From 7cff75c387d08535e2001bf5a869ac721dddbb41 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Fri, 17 Jul 2026 19:54:48 +0000 Subject: [PATCH] Add security headers to global middleware Added `Strict-Transport-Security`, `X-Frame-Options`, and `X-Content-Type-Options` headers to `apps/api/src/cortex_api/middleware/request_context.py` to enforce HTTPS, mitigate clickjacking, and prevent MIME-sniffing. Also created a Sentinel journal entry in `.jules/sentinel.md` documenting the learning. Co-authored-by: crabcanon <3458947+crabcanon@users.noreply.github.com> --- .jules/sentinel.md | 4 ++++ apps/api/src/cortex_api/middleware/request_context.py | 6 ++++++ 2 files changed, 10 insertions(+) create mode 100644 .jules/sentinel.md diff --git a/.jules/sentinel.md b/.jules/sentinel.md new file mode 100644 index 0000000..10c03f5 --- /dev/null +++ b/.jules/sentinel.md @@ -0,0 +1,4 @@ +## 2024-06-25 - Missing Global API Security Headers +**Vulnerability:** The API lacked basic security headers (HSTS, X-Frame-Options, X-Content-Type-Options) in responses. +**Learning:** Security headers are easily forgotten but crucial for defense-in-depth against clickjacking, MIME sniffing, and enforcing HTTPS. +**Prevention:** Always ensure standard security headers are applied in a global middleware when setting up web application frameworks like FastAPI. \ No newline at end of file diff --git a/apps/api/src/cortex_api/middleware/request_context.py b/apps/api/src/cortex_api/middleware/request_context.py index 06a56bd..edebd50 100644 --- a/apps/api/src/cortex_api/middleware/request_context.py +++ b/apps/api/src/cortex_api/middleware/request_context.py @@ -40,4 +40,10 @@ async def request_context_middleware( response.headers[X_REQUEST_ID_HEADER] = request_id if trace_context["trace_id"]: response.headers[X_TRACE_ID_HEADER] = str(trace_context["trace_id"]) + + # Security headers + response.headers["Strict-Transport-Security"] = "max-age=31536000; includeSubDomains" + response.headers["X-Frame-Options"] = "DENY" + response.headers["X-Content-Type-Options"] = "nosniff" + return response