
Pipeline de remédiation des vulnérabilités C/C++ piloté par les preuves + étude de cas http-parser (classe CVE-2024-22019). Cœur Python, console React 19, suite de vérification de 17 tests.
MVP qui normalise les findings de vulnérabilités du code C/C++ de protocoles/plateformes en preuves reproductibles et valide les correctifs candidats dans des copies isolées. code-shield étant un nom de travail présentant un risque avéré de collision de noms, un nom interne neutre a été utilisé pour le package public et la CLI.
Le cœur de l'implémentation actuelle n'est pas un modèle de génération de correctifs, mais la boucle de validation fermée suivante.
sanitizer 또는 SARIF
-> Finding + EvidenceBundle
-> source context
-> manual/external-agent patch
-> 원본 재현
-> build
-> patched reproducer
-> tests
-> static rescan
-> bounded refuzz
-> protocol oracle
-> verified report
Finding, EvidenceBundle, PatchProposal, VerificationReportdetected → reproducible → contextualized → proposed → plausible → verifiedAucune dépendance Python d'exécution.
python3 -m venv .venv
.venv/bin/pip install -e .
.venv/bin/python -m unittest discover -s tests -v
Pour exécuter sans installation :
PYTHONPATH=src python3 -m protocol_remediator --help
PYTHONPATH=src python3 -m unittest discover -s tests -v
La suite dynamique de bout en bout est la matrice de fixtures C/C++ de examples. Elle reproduit réellement CWE-121, CWE-190, CWE-416, CWE-787 et CWE-476 avec Clang ASan/UBSan, puis exécute les six gates pour chaque patch restaurant l'invariant concerné. Les entrées et le périmètre de validation par fixture sont documentés dans examples/README.md.
Pour exécuter uniquement la matrice réelle sans framework de tests unitaires :
PYTHONPATH=src python3 examples/run_fixture_matrix.py
Pour générer et exécuter automatiquement davantage d'exemples variés C/C++ :
PYTHONPATH=src python3 examples/run_generated_corpus.py --count 50
Ce runner n'utilise pas unittest et fait passer chaque projet généré par le même VerificationPipeline. Le résumé des résultats est laissé par défaut dans artifacts/generated-corpus-summary.json.
Le frontend Vite + React + TypeScript, qui permet de consulter l'état actuel de l'implémentation via un tableau de bord opérationnel, se trouve dans frontend. Cette console regroupe sur un seul écran la matrice de fixtures, le corpus généré, les connexions au serveur d'API Hermes, les gates de validation et les invariants de sécurité des preuves.
cd frontend
npm install
npm run dev
Le serveur de développement par défaut est http://127.0.0.1:5173. La build de production se vérifie avec :
cd frontend
npm run build
protocol-remediator ingest-sanitizer \
--log asan.log \
--reproducer crash.input \
--target-name parser \
--revision 0123456789abcdef \
--variant asan-x86_64 \
--output intake/parser-crash
Sortie :
intake/parser-crash/finding.json
intake/parser-crash/evidence.json
protocol-remediator ingest-sarif \
--sarif results.sarif \
--output intake/sarif
protocol-remediator export-sarif \
--finding intake/parser-crash/finding.json \
--finding intake/another/finding.json \
--output artifacts/findings.sarif
protocol-remediator context \
--finding intake/parser-crash/finding.json \
--evidence intake/parser-crash/evidence.json \
--target-root /path/to/target \
--output intake/parser-crash/context.json
protocol-remediator verify \
--config /path/to/target/target.toml \
--finding intake/parser-crash/finding.json \
--evidence intake/parser-crash/evidence.json \
--patch candidate.patch \
--artifacts artifacts
Le code de sortie est 0 si verified, 1 en cas d'échec de validation, et 2 en cas d'erreur de configuration ou d'entrée.
En démarrant le serveur d'API Hermes, remediate peut demander le patch via l'API HTTP au lieu d'une commande locale. L'endpoint par défaut est POST /v1/patches ; il reçoit le finding/evidence/context et l'archive du workspace cible, puis renvoie un diff unifié.
Exemple d'exécution du serveur :
PYTHONPATH=src python3 -m protocol_remediator.hermes_server \
--host 127.0.0.1 \
--port 8765
Après installation, le script console est également disponible.
hermes-agent-server --host 127.0.0.1 --port 8765
Pour connecter une commande backend de production, répétez --backend-command pour chaque argument. Les placeholders {context}, {workspace} et {patch_output} sont pris en charge.
hermes-agent-server \
--backend-command my-patch-agent \
--backend-command --context \
--backend-command {context} \
--backend-command --workspace \
--backend-command {workspace} \
--backend-command --output \
--backend-command {patch_output}
Dans target.toml, le mode Hermes se configure comme suit :
[agent]
mode = "hermes"
url = "http://127.0.0.1:8765"
timeout_seconds = 30
Ensuite, utilisez la commande remediate existante telle quelle.
protocol-remediator remediate \
--config examples/length-prefixed-parser/target.hermes.toml \
--finding artifacts/hermes-cli-input/finding.json \
--evidence artifacts/hermes-cli-input/evidence.json \
--artifacts artifacts/hermes-cli
Pour une vérification de bout en bout en développement, exécutez le runner suivant. Ce runner démarre un serveur Hermes temporaire, reçoit le patch via un client API, puis exécute la boucle de validation complète.
PYTHONPATH=src python3 examples/run_hermes_demo.py
Pour appeler directement une commande locale sans Hermes, spécifiez la commande de l'agent dans target.toml sous forme de tableau de chaînes.
[agent]
mode = "command"
command = [
"my-patch-agent",
"--context",
"{context}",
"--workspace",
"{workspace}",
"--output",
"{patch_output}",
]
timeout_seconds = 900
Exécutez ensuite la commande suivante :
protocol-remediator remediate \
--config /path/to/target/target.toml \
--finding intake/parser-crash/finding.json \
--evidence intake/parser-crash/evidence.json \
--artifacts artifacts
Le cœur n'appelle directement aucune API LLM spécifique. Le contrat est que le backend Hermes ou la commande externe lit le contexte et génère un diff unifié. Le travail de l'agent s'exécute dans une copie temporaire, et non dans la cible d'origine.
Un exemple complet se trouve dans target.toml.
[project]
name = "my-protocol"
language = "c++"
root = "."
[executor]
mode = "docker"
image = "my-frozen-toolchain@sha256:..."
timeout_seconds = 300
network = false
[reproduction]
failure_regex = "AddressSanitizer|heap-buffer-overflow"
[verification]
required_gates = [
"build",
"reproducer",
"tests",
"rescan",
"refuzz",
"protocol",
]
[gates]
build = [["cmake", "-S", ".", "-B", "build"], ["cmake", "--build", "build"]]
reproducer = [["./build/fuzz_target", "{reproducer}"]]
tests = [["ctest", "--test-dir", "build", "--output-on-failure"]]
rescan = [["./tools/run-sast", "--fail-on-new"]]
refuzz = [["./tools/refuzz", "--seconds", "60"]]
protocol = [["./tools/protocol-oracle"]]
Chaque commande est un tableau d'arguments et non une chaîne shell. Placeholders pris en charge :
{workspace} : chemin temporaire de la cible tel que visible par l'exécuteur{reproducer} : chemin du reproducer copié dans la cible temporaire après vérification du checksumbuild et reproducer sont toujours requis. Par défaut, les six gates sont toutes obligatoires. Si une gate n'est pas utilisable en raison des caractéristiques de la cible, vous devez l'ajuster explicitement dans required_gates ; cela reste visible dans le rapport.
Chaque exécution de validation préserve ce qui suit :
artifacts/run_<id>/
candidate.patch
context.json
evidence.input.json
finding.input.json
finding.final.json
patch-proposal.json
patch-stats.json
verification-report.json
verification-report.json contient les sorties des commandes baseline et patched. Comme les PoC ou les journaux peuvent contenir des secrets, une politique d'accès et de conservation distincte doit être appliquée au dépôt d'artefacts.
network=false.allow_local=true et ne doit pas être utilisé avec des cibles non fiables.plausible est l'état où seuls le build et le reproducer d'origine ont réussi.verified n'est pas non plus une preuve d'équivalence de programmes et ne remplace pas l'approbation humaine.Les motivations de la recherche et les décisions de conception sont documentées dans docs/research.