fix: D3FEND expandable cards, System page cleanup, and multi-source improvements
- Make D3FEND defense cards clickable with expandable details and external link - Fix D3FEND URLs to use PascalCase technique names matching the ontology - Remove duplicate Import Atomic Red Team from System page (use Data Sources) - Add bulk Activate All / Deactivate All buttons with confirmation modal - Fix template admin list to show both active and inactive templates - Add PATCH /test-templates/bulk-activate backend endpoint - Auto-seed data sources on container startup via entrypoint.sh - Fix SigmaHQ, CALDERA, GTFOBins import issues - Register D3FEND sync handler in data sources router - Add CIS Controls v8 compliance framework import - Expand Test Catalog source filters (CALDERA, LOLBAS, GTFOBins) - Campaign Generate from Threat Actor now opens actor selector modal - Add coverage snapshot creation button to Comparison page - Update README with accurate data source and feature documentation
This commit is contained in:
@@ -44,12 +44,12 @@ logger = logging.getLogger(__name__)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
CALDERA_ZIP_URL = (
|
||||
"https://github.com/mitre/caldera"
|
||||
"https://github.com/mitre/stockpile"
|
||||
"/archive/refs/heads/master.zip"
|
||||
)
|
||||
|
||||
_DOWNLOAD_TIMEOUT = 300
|
||||
_ZIP_ROOT_PREFIX = "caldera-master"
|
||||
_ZIP_ROOT_PREFIX = "stockpile-master"
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -144,10 +144,17 @@ def _parse_abilities(abilities_dir: Path) -> list[dict]:
|
||||
logger.debug("Failed to parse %s: %s", yaml_path, exc)
|
||||
continue
|
||||
|
||||
# Stockpile YAML files may contain YAML lists of abilities
|
||||
# (e.g. [- id: ..., - id: ...]) or single-document dicts.
|
||||
# Flatten everything into individual ability dicts.
|
||||
abilities: list[dict] = []
|
||||
for data in data_list:
|
||||
if not isinstance(data, dict):
|
||||
continue
|
||||
if isinstance(data, dict):
|
||||
abilities.append(data)
|
||||
elif isinstance(data, list):
|
||||
abilities.extend(d for d in data if isinstance(d, dict))
|
||||
|
||||
for data in abilities:
|
||||
ability_id = data.get("id", "")
|
||||
if not ability_id:
|
||||
continue
|
||||
@@ -193,7 +200,7 @@ def _parse_abilities(abilities_dir: Path) -> list[dict]:
|
||||
"tool_suggested": executor_str,
|
||||
"attack_procedure": commands[:4000] if commands else None,
|
||||
"atomic_test_id": f"caldera:{ability_id}",
|
||||
"source_url": f"https://github.com/mitre/caldera/tree/master/data/abilities/{tactic}",
|
||||
"source_url": f"https://github.com/mitre/stockpile/tree/master/data/abilities/{tactic}",
|
||||
})
|
||||
|
||||
logger.info("Parsed %d CALDERA abilities total", len(results))
|
||||
|
||||
Reference in New Issue
Block a user