2026-07-12 09:39:55 +01:00
|
|
|
from pathlib import Path
|
|
|
|
|
|
2026-07-12 20:57:55 +01:00
|
|
|
ROOT = Path(__file__).resolve().parents[2]
|
2026-07-12 09:39:55 +01:00
|
|
|
PENTEST = ROOT / "skills/pentest"
|
|
|
|
|
EXPLOITATION = PENTEST / "playbooks/exploitation.md"
|
|
|
|
|
REPORTING = PENTEST / "playbooks/reporting.md"
|
|
|
|
|
TEMPLATE = PENTEST / "templates/report-template.md"
|
|
|
|
|
STANDARDS = PENTEST / "references/standards.md"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_standards_define_attack_chain_record_contract():
|
|
|
|
|
text = STANDARDS.read_text(encoding="utf-8").lower()
|
|
|
|
|
required = [
|
|
|
|
|
"attack-chain correlation",
|
|
|
|
|
"chain_id",
|
|
|
|
|
"step_id",
|
|
|
|
|
"prerequisite_findings",
|
|
|
|
|
"resulting_access",
|
|
|
|
|
"chain impact",
|
|
|
|
|
]
|
|
|
|
|
for phrase in required:
|
|
|
|
|
assert phrase in text
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_exploitation_keeps_chain_steps_individually_approved():
|
|
|
|
|
text = EXPLOITATION.read_text(encoding="utf-8").lower()
|
|
|
|
|
required = [
|
|
|
|
|
"attack-chain correlation",
|
|
|
|
|
"do not automatically chain",
|
|
|
|
|
"each step",
|
|
|
|
|
"new approval",
|
|
|
|
|
"chain_id",
|
|
|
|
|
"prerequisite_findings",
|
|
|
|
|
]
|
|
|
|
|
for phrase in required:
|
|
|
|
|
assert phrase in text
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_reporting_requires_chain_rollup_without_replacing_atomic_findings():
|
|
|
|
|
text = REPORTING.read_text(encoding="utf-8").lower()
|
|
|
|
|
required = [
|
|
|
|
|
"attack chain roll-up",
|
|
|
|
|
"atomic findings",
|
|
|
|
|
"prerequisite findings",
|
|
|
|
|
"chain impact",
|
|
|
|
|
"must not replace",
|
|
|
|
|
]
|
|
|
|
|
for phrase in required:
|
|
|
|
|
assert phrase in text
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_template_has_attack_chain_correlation_section():
|
|
|
|
|
text = TEMPLATE.read_text(encoding="utf-8").lower()
|
|
|
|
|
required = [
|
|
|
|
|
"## attack chain correlation",
|
|
|
|
|
"chain id",
|
|
|
|
|
"step id",
|
|
|
|
|
"prerequisite findings",
|
|
|
|
|
"resulting access",
|
|
|
|
|
"chain impact",
|
|
|
|
|
]
|
|
|
|
|
for phrase in required:
|
|
|
|
|
assert phrase in text
|