diff --git a/scripts/security/gitea-authenticated-inventory-payload-validator.py b/scripts/security/gitea-authenticated-inventory-payload-validator.py index d654274e..c41bdc43 100644 --- a/scripts/security/gitea-authenticated-inventory-payload-validator.py +++ b/scripts/security/gitea-authenticated-inventory-payload-validator.py @@ -260,6 +260,8 @@ def main() -> int: validation = validate_payload(load_json(args.input)) text = json.dumps(validation, ensure_ascii=False, indent=2) + "\n" if args.output: + if args.output.resolve() == args.input.resolve(): + raise SystemExit("output_must_not_equal_input") args.output.parent.mkdir(parents=True, exist_ok=True) args.output.write_text(text, encoding="utf-8") else: diff --git a/scripts/security/tests/test_gitea_authenticated_inventory_payload_validator.py b/scripts/security/tests/test_gitea_authenticated_inventory_payload_validator.py index 45c300a1..92a95db2 100644 --- a/scripts/security/tests/test_gitea_authenticated_inventory_payload_validator.py +++ b/scripts/security/tests/test_gitea_authenticated_inventory_payload_validator.py @@ -72,6 +72,30 @@ def test_rejects_execution_request(tmp_path: Path) -> None: assert validation["operation_boundaries"]["gitea_write_performed"] is False +def test_output_must_not_overwrite_input(tmp_path: Path) -> None: + payload_path = tmp_path / "inventory.json" + original = json.dumps(valid_payload()) + payload_path.write_text(original, encoding="utf-8") + + result = subprocess.run( + [ + sys.executable, + str(SCRIPT), + "--input", + str(payload_path), + "--output", + str(payload_path), + ], + text=True, + capture_output=True, + check=False, + ) + + assert result.returncode != 0 + assert "output_must_not_equal_input" in result.stderr + assert payload_path.read_text(encoding="utf-8") == original + + def valid_payload() -> dict: repos = [ repo("wooo/awoooi"),