diff --git a/__pycache__/validate_pocs.cpython-312.pyc b/__pycache__/validate_pocs.cpython-312.pyc new file mode 100644 index 0000000..afa4dcd Binary files /dev/null and b/__pycache__/validate_pocs.cpython-312.pyc differ diff --git a/curl-smtp-expn-recipient-crlf-injection/__pycache__/run_demo.cpython-312.pyc b/curl-smtp-expn-recipient-crlf-injection/__pycache__/run_demo.cpython-312.pyc new file mode 100644 index 0000000..e769b67 Binary files /dev/null and b/curl-smtp-expn-recipient-crlf-injection/__pycache__/run_demo.cpython-312.pyc differ diff --git a/discourse-scoped-api-key-preauth-bypass/__pycache__/poc.cpython-312.pyc b/discourse-scoped-api-key-preauth-bypass/__pycache__/poc.cpython-312.pyc new file mode 100644 index 0000000..7f939b0 Binary files /dev/null and b/discourse-scoped-api-key-preauth-bypass/__pycache__/poc.cpython-312.pyc differ diff --git a/ffmpeg-rasc-dlta-calc-poc/poc/__pycache__/rasc_dlta_os_helper.cpython-312.pyc b/ffmpeg-rasc-dlta-calc-poc/poc/__pycache__/rasc_dlta_os_helper.cpython-312.pyc new file mode 100644 index 0000000..ebf5461 Binary files /dev/null and b/ffmpeg-rasc-dlta-calc-poc/poc/__pycache__/rasc_dlta_os_helper.cpython-312.pyc differ diff --git a/firefox-152.0.5-backup-nss-rce-poc/__pycache__/build_backup.cpython-312.pyc b/firefox-152.0.5-backup-nss-rce-poc/__pycache__/build_backup.cpython-312.pyc new file mode 100644 index 0000000..61277ad Binary files /dev/null and b/firefox-152.0.5-backup-nss-rce-poc/__pycache__/build_backup.cpython-312.pyc differ diff --git a/firefox-152.0.5-backup-nss-rce-poc/__pycache__/server.cpython-312.pyc b/firefox-152.0.5-backup-nss-rce-poc/__pycache__/server.cpython-312.pyc new file mode 100644 index 0000000..531ea1a Binary files /dev/null and b/firefox-152.0.5-backup-nss-rce-poc/__pycache__/server.cpython-312.pyc differ diff --git a/floci-apigateway-vtl-rce-poc/__pycache__/poc.cpython-312.pyc b/floci-apigateway-vtl-rce-poc/__pycache__/poc.cpython-312.pyc new file mode 100644 index 0000000..46720a1 Binary files /dev/null and b/floci-apigateway-vtl-rce-poc/__pycache__/poc.cpython-312.pyc differ diff --git a/libssh2-publickey-list-calc-poc/__pycache__/replay-calc-poc.cpython-312.pyc b/libssh2-publickey-list-calc-poc/__pycache__/replay-calc-poc.cpython-312.pyc new file mode 100644 index 0000000..0476bba Binary files /dev/null and b/libssh2-publickey-list-calc-poc/__pycache__/replay-calc-poc.cpython-312.pyc differ diff --git a/libssh2-publickey-list-calc-poc/poc/__pycache__/live_publickey_server.cpython-312.pyc b/libssh2-publickey-list-calc-poc/poc/__pycache__/live_publickey_server.cpython-312.pyc new file mode 100644 index 0000000..cd7b42e Binary files /dev/null and b/libssh2-publickey-list-calc-poc/poc/__pycache__/live_publickey_server.cpython-312.pyc differ diff --git a/nghttp2-nghttpx-upgrade-queue-poison-poc/__pycache__/poc.cpython-312.pyc b/nghttp2-nghttpx-upgrade-queue-poison-poc/__pycache__/poc.cpython-312.pyc new file mode 100644 index 0000000..b1f9f70 Binary files /dev/null and b/nghttp2-nghttpx-upgrade-queue-poison-poc/__pycache__/poc.cpython-312.pyc differ diff --git a/openssh-agent-lock-provider-bypass/__pycache__/poc.cpython-312.pyc b/openssh-agent-lock-provider-bypass/__pycache__/poc.cpython-312.pyc new file mode 100644 index 0000000..205e570 Binary files /dev/null and b/openssh-agent-lock-provider-bypass/__pycache__/poc.cpython-312.pyc differ diff --git a/postgres-ri-owner-switched-cast-poc/__pycache__/poc.cpython-312.pyc b/postgres-ri-owner-switched-cast-poc/__pycache__/poc.cpython-312.pyc new file mode 100644 index 0000000..d028a17 Binary files /dev/null and b/postgres-ri-owner-switched-cast-poc/__pycache__/poc.cpython-312.pyc differ diff --git a/redis-vset-duplicate-hnsw-id-rce-poc/__pycache__/poc.cpython-312.pyc b/redis-vset-duplicate-hnsw-id-rce-poc/__pycache__/poc.cpython-312.pyc new file mode 100644 index 0000000..5bdc324 Binary files /dev/null and b/redis-vset-duplicate-hnsw-id-rce-poc/__pycache__/poc.cpython-312.pyc differ diff --git a/tests/__pycache__/test_validate_pocs.cpython-312.pyc b/tests/__pycache__/test_validate_pocs.cpython-312.pyc new file mode 100644 index 0000000..e335d90 Binary files /dev/null and b/tests/__pycache__/test_validate_pocs.cpython-312.pyc differ diff --git a/tests/test_validate_pocs.py b/tests/test_validate_pocs.py new file mode 100644 index 0000000..44f499e --- /dev/null +++ b/tests/test_validate_pocs.py @@ -0,0 +1,26 @@ +import unittest +from pathlib import Path + +import validate_pocs + + +class ValidatePocsTest(unittest.TestCase): + def setUp(self) -> None: + self.repo_root = Path(__file__).resolve().parents[1] + + def test_discovery_finds_expected_targets(self) -> None: + python_targets = validate_pocs.discover_python_targets(self.repo_root) + package_targets = validate_pocs.discover_package_targets(self.repo_root) + + self.assertTrue(any(path.name == "run_demo.py" for path in python_targets)) + self.assertTrue(any(path.name == "package.json" for path in package_targets)) + self.assertGreater(len(python_targets), 20) + self.assertGreater(len(package_targets), 0) + + def test_validation_succeeds(self) -> None: + result = validate_pocs.validate_repo(self.repo_root) + self.assertEqual(result["errors"], []) + + +if __name__ == "__main__": + unittest.main() diff --git a/validate_pocs.py b/validate_pocs.py new file mode 100644 index 0000000..a263dd7 --- /dev/null +++ b/validate_pocs.py @@ -0,0 +1,84 @@ +#!/usr/bin/env python3 +"""Validate the repository's PoC entrypoints and manifests.""" + +from __future__ import annotations + +import argparse +import json +import py_compile +import sys +from pathlib import Path +from typing import List, Dict, Tuple + + +EXCLUDED_DIRS = {".git", "__pycache__"} + + +def discover_python_targets(root: Path) -> List[Path]: + return sorted( + path + for path in root.rglob("*.py") + if not any(part in EXCLUDED_DIRS for part in path.parts) + ) + + +def discover_package_targets(root: Path) -> List[Path]: + return sorted( + path + for path in root.rglob("package.json") + if not any(part in EXCLUDED_DIRS for part in path.parts) + ) + + +def validate_repo(root: Path) -> Dict[str, object]: + python_targets = discover_python_targets(root) + package_targets = discover_package_targets(root) + errors: List[str] = [] + + for path in python_targets: + try: + py_compile.compile(str(path), doraise=True) + except py_compile.PyCompileError as exc: # pragma: no cover - exercised in tests when broken code exists + errors.append(f"{path.relative_to(root)}: {exc}") + + for path in package_targets: + try: + data = json.loads(path.read_text(encoding="utf-8")) + except json.JSONDecodeError as exc: + errors.append(f"{path.relative_to(root)}: invalid JSON ({exc})") + continue + + scripts = data.get("scripts") + if isinstance(scripts, dict) and "poc" in scripts: + if not isinstance(scripts["poc"], str) or not scripts["poc"].strip(): + errors.append(f"{path.relative_to(root)}: scripts.poc must be a non-empty string") + + return { + "root": str(root), + "python_files": len(python_targets), + "package_json_files": len(package_targets), + "errors": errors, + } + + +def main(argv: List[str] | None = None) -> int: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--root", type=Path, default=Path(__file__).resolve().parent) + args = parser.parse_args(argv) + + result = validate_repo(args.root.resolve()) + for error in result["errors"]: + print(error, file=sys.stderr) + + print( + f"validated {result['python_files']} Python files and {result['package_json_files']} package manifests" + ) + if result["errors"]: + print("validation failed", file=sys.stderr) + return 1 + print("validation succeeded") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main())