fix: resolve 20 security vulnerabilities from comprehensive audit
Critical (1-3): - Replace hardcoded admin credentials with secure auto-generation (seed.py) - Enforce SECRET_KEY configuration, fail in production if missing (config.py) - Add Zip Slip and Zip Bomb protection to all ZIP import services High/Medium (4-9): - Add 50MB file size limit and extension whitelist to evidence uploads - Configure CORS origins via environment variable instead of hardcoded - Migrate JWT storage from localStorage to HttpOnly cookies (frontend+backend) - Add rate limiting (5/min) on login endpoint via slowapi - Replace generic dict payloads with Pydantic schemas (mass assignment) Medium (10-17): - Check is_active on login to prevent disabled users from authenticating - Sanitize exception messages in API responses (system, data_sources) - Escape LIKE wildcards in all ilike search filters across 8 routers - Run Docker container as non-root user (appuser) - Make MINIO_SECURE configurable via environment variable - Add password complexity policy (12+ chars, upper/lower/digit/special) - Implement JWT token revocation via in-memory blacklist + reduce TTL to 15min - Replace xml.etree with defusedxml to prevent Billion Laughs attacks Low (18-20): - Add security headers to Nginx (CSP, X-Frame-Options, HSTS-ready, etc.) - Disable Swagger UI/ReDoc/OpenAPI in production - Restrict /health endpoint to internal networks via Nginx ACL Also: rewrite install.sh as interactive wizard for guided deployment, fix test-from-template validation error (technique_id UUID vs MITRE ID)
This commit is contained in:
@@ -5,10 +5,12 @@ and managing the template ↔ detection rule associations.
|
||||
"""
|
||||
|
||||
import logging
|
||||
import uuid
|
||||
from typing import Optional
|
||||
from datetime import datetime
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException, Query
|
||||
from pydantic import BaseModel
|
||||
from sqlalchemy import func
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
@@ -20,6 +22,18 @@ from app.models.test_template import TestTemplate
|
||||
from app.models.test_template_detection_rule import TestTemplateDetectionRule
|
||||
from app.models.test_detection_result import TestDetectionResult
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Pydantic schemas for request validation
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
class DetectionRuleEvaluate(BaseModel):
|
||||
"""Payload for evaluating a detection rule against a test."""
|
||||
test_id: uuid.UUID
|
||||
detection_rule_id: uuid.UUID
|
||||
triggered: Optional[bool] = None
|
||||
notes: Optional[str] = None
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
router = APIRouter(prefix="/detection-rules", tags=["detection-rules"])
|
||||
@@ -53,7 +67,8 @@ def list_detection_rules(
|
||||
query = query.filter(DetectionRule.severity == severity)
|
||||
|
||||
if search:
|
||||
pattern = f"%{search}%"
|
||||
from app.utils import escape_like
|
||||
pattern = f"%{escape_like(search)}%"
|
||||
query = query.filter(
|
||||
DetectionRule.title.ilike(pattern)
|
||||
| DetectionRule.description.ilike(pattern)
|
||||
@@ -294,27 +309,15 @@ def get_detection_rules_for_test(
|
||||
|
||||
@router.post("/evaluate")
|
||||
def evaluate_detection_rule(
|
||||
payload: dict,
|
||||
payload: DetectionRuleEvaluate,
|
||||
db: Session = Depends(get_db),
|
||||
current_user: User = Depends(require_any_role("blue_tech", "blue_lead")),
|
||||
):
|
||||
"""Save or update the evaluation result for a detection rule on a test.
|
||||
|
||||
Body:
|
||||
{
|
||||
"test_id": "...",
|
||||
"detection_rule_id": "...",
|
||||
"triggered": true | false | null,
|
||||
"notes": "optional notes"
|
||||
}
|
||||
"""
|
||||
test_id = payload.get("test_id")
|
||||
detection_rule_id = payload.get("detection_rule_id")
|
||||
triggered = payload.get("triggered")
|
||||
notes = payload.get("notes")
|
||||
|
||||
if not test_id or not detection_rule_id:
|
||||
raise HTTPException(status_code=400, detail="test_id and detection_rule_id are required")
|
||||
"""Save or update the evaluation result for a detection rule on a test."""
|
||||
test_id = payload.test_id
|
||||
detection_rule_id = payload.detection_rule_id
|
||||
triggered = payload.triggered
|
||||
notes = payload.notes
|
||||
|
||||
# Check test exists
|
||||
from app.models.test import Test
|
||||
|
||||
Reference in New Issue
Block a user