-
Notifications
You must be signed in to change notification settings - Fork 0
π‘οΈ Sentinel: [MEDIUM] Add HTTP security headers #605
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,14 @@ | ||||||||||||||||||||
| from starlette.middleware.base import BaseHTTPMiddleware | ||||||||||||||||||||
| from fastapi import Request | ||||||||||||||||||||
|
|
||||||||||||||||||||
| class SecurityHeadersMiddleware(BaseHTTPMiddleware): | ||||||||||||||||||||
| """ | ||||||||||||||||||||
| Middleware to add security headers to all responses. | ||||||||||||||||||||
| """ | ||||||||||||||||||||
| async def dispatch(self, request: Request, call_next): | ||||||||||||||||||||
| response = await call_next(request) | ||||||||||||||||||||
| response.headers["X-Content-Type-Options"] = "nosniff" | ||||||||||||||||||||
| response.headers["X-Frame-Options"] = "DENY" | ||||||||||||||||||||
| response.headers["X-XSS-Protection"] = "1; mode=block" | ||||||||||||||||||||
|
||||||||||||||||||||
| response.headers["X-XSS-Protection"] = "1; mode=block" |
Copilot
AI
Feb 23, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider adding a Content-Security-Policy (CSP) header to the backend middleware for defense in depth. While Nginx already sets CSP (frontend/nginx.conf:52), adding it at the backend level ensures API responses are protected even if accessed directly or if the Nginx layer is bypassed. This is especially important for the backend API running on port 8080 which may be accessed directly in development or certain deployment scenarios.
| response.headers["Referrer-Policy"] = "strict-origin-when-cross-origin" | |
| response.headers["Referrer-Policy"] = "strict-origin-when-cross-origin" | |
| if "Content-Security-Policy" not in response.headers: | |
| response.headers[ | |
| "Content-Security-Policy" | |
| ] = "default-src 'none'; frame-ancestors 'none'; base-uri 'none'; form-action 'none'" |
Copilot
AI
Feb 23, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider adding Strict-Transport-Security (HSTS) header for HTTPS deployments. While the current setup uses HTTP (port 80 in Nginx), production deployments should enforce HTTPS. Adding the header conditionally based on the request scheme or environment variable would improve security posture when deployed with TLS. Example: "Strict-Transport-Security: max-age=31536000; includeSubDomains".
Copilot
AI
Feb 23, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Referrer-Policy header value conflicts with the Nginx configuration. The backend sets "strict-origin-when-cross-origin" while Nginx sets "no-referrer-when-downgrade" (frontend/nginx.conf:51). This creates inconsistent security postures. The backend's value is more privacy-preserving and should be aligned across both layers. Consider updating Nginx to match this setting or documenting why different policies are needed.
| response.headers["Referrer-Policy"] = "strict-origin-when-cross-origin" | |
| # NOTE: This must stay aligned with the Referrer-Policy set in Nginx (frontend/nginx.conf). | |
| response.headers["Referrer-Policy"] = "no-referrer-when-downgrade" |
| Original file line number | Diff line number | Diff line change | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,14 @@ | ||||||||||||||||
| from fastapi.testclient import TestClient | ||||||||||||||||
| from src.main import app | ||||||||||||||||
|
|
||||||||||||||||
| client = TestClient(app) | ||||||||||||||||
|
|
||||||||||||||||
| def test_security_headers(): | ||||||||||||||||
|
Comment on lines
+1
to
+6
|
||||||||||||||||
| from fastapi.testclient import TestClient | |
| from src.main import app | |
| client = TestClient(app) | |
| def test_security_headers(): | |
| def test_security_headers(client): |
Copilot
AI
Feb 23, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test should verify that the deprecated X-XSS-Protection header is not present, rather than asserting it equals "1; mode=block". Since this header is deprecated and modern browsers no longer support it, the test should be updated to reflect the corrected implementation once the security header is removed from the middleware.
| assert headers["X-XSS-Protection"] == "1; mode=block" | |
| assert "X-XSS-Protection" not in headers |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The X-Frame-Options header value conflicts with the Nginx configuration. The backend sets "DENY" while Nginx sets "SAMEORIGIN" (frontend/nginx.conf:48). This creates inconsistent behavior where responses from the backend have stricter settings than those served by Nginx. The values should be aligned - either both use "DENY" for maximum security or both use "SAMEORIGIN" for flexibility.