From 673b25e0b063ef73bf33559089c94a53ee602da0 Mon Sep 17 00:00:00 2001 From: Knacky Date: Wed, 27 May 2026 03:58:30 +0200 Subject: [PATCH] fix(backend): PATCH technique_ids returns 503 when MITRE bundle not loaded Added bundle-loaded guard in _resolve_technique_ids() before attempting any lookup; matches behavior of GET /api/mitre/matrix and GET /api/mitre/techniques. Added corresponding test case. Co-Authored-By: Claude Sonnet 4.6 --- backend/app/services/simulation_workflow.py | 3 +++ backend/tests/test_simulations_techniques.py | 21 ++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/backend/app/services/simulation_workflow.py b/backend/app/services/simulation_workflow.py index 2c8ddd7..2df406d 100644 --- a/backend/app/services/simulation_workflow.py +++ b/backend/app/services/simulation_workflow.py @@ -55,6 +55,9 @@ def _resolve_technique_ids( """ from backend.app.services import mitre as mitre_svc + if not mitre_svc.mitre_loaded: + return None, (jsonify({"error": "mitre bundle not loaded"}), 503) + # Dedup, preserve order. seen: dict[str, None] = dict.fromkeys(technique_ids) resolved: list[dict[str, str]] = [] diff --git a/backend/tests/test_simulations_techniques.py b/backend/tests/test_simulations_techniques.py index 5212577..f515965 100644 --- a/backend/tests/test_simulations_techniques.py +++ b/backend/tests/test_simulations_techniques.py @@ -305,6 +305,27 @@ def test_technique_ids_empty_does_not_trigger_auto_transition( assert resp.get_json()["status"] == "pending" +# --------------------------------------------------------------------------- +# Bundle not loaded — 503 on technique_ids PATCH +# --------------------------------------------------------------------------- + + +def test_patch_technique_ids_bundle_not_loaded_returns_503( + client: FlaskClient, redteam_token: str +) -> None: + """When MITRE bundle is absent, PATCH with technique_ids must return 503.""" + mitre_svc.mitre_loaded = False + mitre_svc._index = [] + mitre_svc._name_by_id = {} + + eng = _make_engagement(client, redteam_token) + sim = _make_sim(client, redteam_token, eng["id"]) + + resp = _patch(client, redteam_token, sim["id"], {"technique_ids": ["T1059"]}) + assert resp.status_code == 503 + assert resp.get_json()["error"] == "mitre bundle not loaded" + + # --------------------------------------------------------------------------- # SOC cannot patch technique_ids (it's a redteam field) # ---------------------------------------------------------------------------