
Ein kontextuelles Sicherheits-Audit-System für Forschungsartefakte
SAFE führt eine kontrollierte, repository-bewusste Sicherheitsbewertung von Semgrep- und Trivy-Befunden in Forschungsartefakten durch.
Es unterstützt zwei unabhängige Klassifikationsaufgaben: direkte binäre Vorhersage (SECURITY_RELEVANT oder NON_SECURITY) und die detaillierte multiclass-kontextuelle Taxonomie (drei Labels — siehe Drei Labels). Jede Aufgabe kann im Zero-Shot- oder Agentic-Modus ausgeführt werden.
Es erwartet lediglich:
artifact_id enthält.artifact_id verschlüsselt ist.Es trainiert nicht mit oder optimiert gegen gelabelte Bewertungsdaten. Gelabelte Daten werden nur nach der Inferenz verwendet, um Vorhersagen zu bewerten, und werden vom Klassifikator nie gesehen. SAFE führt niemals Artefaktcode aus; Repository-Text wird als nicht vertrauenswürdige Evidenz behandelt, nicht als Anweisungen.
Diese Veröffentlichung enthält den vollständigen safe_audit-Quellcode, die CLI und Tests sowie ein eigenständiges mit drei vollständig synthetischen Beispielartefakten, die Sie ohne externe Daten Ende-zu-Ende ausführen können. Sie schließt das reale Forschungsartefakt-Korpus, Ground-Truth-Labels und Bewertungsbefunde aus, die im Papier verwendet wurden.
Schnellstart: Führen Sie nach der Installation die Demo aus — sie funktioniert sofort ohne Dateneinrichtung. config.example.yaml, das später unter Konfiguration behandelt wird, ist eine Vorlage für Ihre eigenen Befunde/Artefakte und wird erst nach der Bearbeitung ausgeführt.
cd path/to/safe-artifact-auditor
python3 -m venv .venv
source .venv/bin/activate
pip install -e .
Legen Sie den API-Schlüssel fest:
export OPENAI_API_KEY="your-key"
Für einen Organisations-LiteLLM-Proxy verwenden Sie stattdessen config.litellm.example.yaml — es ist inline kommentiert. Anmeldeinformationen und benutzerdefinierte Header-Werte werden aus Umgebungsvariablen gelesen und niemals in SAFE-Konfigurations- oder Ergebnisdateien gespeichert.
demo/ enthält drei kleine, vollständig synthetische Beispielartefakte — keines davon abgeleitet von oder entsprechend einem realen veröffentlichten Forschungsartefakt — eines pro Taxonomie-Label, sodass Gutachter die vollständige Pipeline ohne externe Daten ausführen können:
demo-contextual-risk/ — ein Spielzeug-Federated-Learning-Checkpoint-Aggregator, der einen von einer aufruferseitig bereitgestellten URL heruntergeladenen Checkpoint mit torch.load deserialisiert. Nicht vertrauenswürdige, netzwerkbezogene Eingaben erreichen eine unsichere Deserialisierungs-Senke, die SAFE voraussichtlich als CONTEXTUAL_RISK klassifiziert.demo-hardening-recommendation/ — eine Spielzeug-Benchmark-Harness, die subprocess.run(..., shell=True) gegen Befehlszeilen ausführt, die alle hartcodierte Python-Literale sind, ohne aufruferkontrollierte Eingaben. SAFE wird voraussichtlich als HARDENING_RECOMMENDATION klassifiziert: Das Shell-Muster ist real und erwähnenswert, aber nichts Externes kann es erreichen oder beeinflussen.demo-false-positive/ — ein Test-Fixture-Generator, der an eine ältere Pillow-Version mit einer hypothetischen Dekompressionsbomben-Advisory gebunden ist. Der Code erstellt nur neue In-Memory-Bilder und öffnet niemals externe Daten, sodass der tatsächliche Codepfad der Advisory nie erreicht wird. SAFE wird voraussichtlich als FALSE_POSITIVE klassifiziert.demo/findings.csv enthält einen Befund pro Artefakt, und demo/demo-zero-shot.yaml / demo/demo-agentic.yaml sind sofort ausführbare Konfigurationen (artifact_root: . löst relativ zur Konfigurationsdatei auf, führen Sie sie also aus demo/ heraus aus):
cd demo
safe-audit run --config demo-zero-shot.yaml
safe-audit run --config demo-agentic.yaml
Ergebnisse landen in demo/runs/demo-zero-shot/ bzw. demo/runs/demo-agentic/ (siehe Ausgabe).
CONTEXTUAL_RISKHARDENING_RECOMMENDATIONFALSE_POSITIVEEs wird keine zusätzliche Kategorie und keine deterministische Label-Änderungsregel verwendet. Ein dokumentierter, isolierter Forschungs-/Sicherheitsmechanismus im eigenen Code eines Artefakts wird als HARDENING_RECOMMENDATION klassifiziert, da die zugrunde liegende Praxis auch dann real ist, wenn die Isolation die realistische Ausnutzbarkeit einschränkt.
SECURITY_RELEVANT: ein gültiges kontextuelles Risiko oder Härtungsbedenken, einschließlich absichtlichem, isoliertem Sicherheitsforschungsverhalten.NON_SECURITY: ein falscher, nicht übereinstimmender, nicht anwendbarer, fehlender oder nachweislich ungenutzter betroffener-Funktions-Befund.Der Bewerter leitet auch eine binäre Ansicht aus Mehrklassen-Vorhersagen ab: FALSE_POSITIVE wird zu NON_SECURITY; jedes andere Mehrklassen-Label wird zu SECURITY_RELEVANT. Direkte und abgeleitete binäre Ergebnisse bleiben explizit getrennt.
project/
├── config.yaml
├── data/
│ └── findings.csv
└── artifacts/
├── artifact_001/
├── artifact_002/
└── artifact_003/
Die Zuordnung ist exakt: artifact_id = artifact_001 löst zu artifacts/artifact_001/ auf.
Erforderliche CSV-Spalten:
artifact_id;tool;finding_id
Optionale Spalten:
artifact_id;tool;finding_id;category;severity_raw;file;line;message;package;version;cwe;cvss;scanner_applicable
Eine anfängliche unbenannte Indexspalte wird ignoriert. Zusätzliche Spalten werden vom Eingabemodell beibehalten.
Beispiel:
artifact_id;tool;finding_id;category;severity_raw;file;line;message;package;version;cwe;cvss;scanner_applicable
artifact_001;semgrep;python.lang.security.audit.subprocess-shell-true;code;HIGH;src/probe.py;42;Shell command uses shell=True;;;;CWE-78;;yes
artifact_002;trivy;DEMO-CVE-0001;dependency;HIGH;;;Affected package (illustrative, not a real CVE);example-lib;1.2.0;CWE-502;8.1;yes
scripts/run_scanners.py und scripts/build_findings_csv.py erzeugen die oben beschriebene findings.csv und Artefaktstruktur direkt aus Ihrem eigenen Code, unter Verwendung von Semgrep und Trivy.
Semgrep installieren (funktioniert auf jedem Betriebssystem gleich, einschließlich Linux):
pip install semgrep
Trivy unter Linux installieren — entweder über das apt-Repository (Debian/Ubuntu):
sudo apt-get install wget gnupg
wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | gpg --dearmor | sudo tee /usr/share/keyrings/trivy.gpg > /dev/null
echo "deb [signed-by=/usr/share/keyrings/trivy.gpg] https://aquasecurity.github.io/trivy-repo/deb generic main" | sudo tee -a /etc/apt/sources.list.d/trivy.list
sudo apt-get update
sudo apt-get install trivy
oder über das offizielle Installationsskript, das auf jeder Linux-Distribution funktioniert und eine Binärversion in /usr/local/bin installiert (keine Root-Pakete erforderlich, außer sudo für dieses Verzeichnis):
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sudo sh -s -- -b /usr/local/bin
Stellen Sie sicher, dass beide auf PATH sind, bevor Sie fortfahren:
semgrep --version
trivy --version
Legen Sie dann ein Verzeichnis pro Artefakt unter einem artifact_root/ an und führen Sie aus:
python scripts/run_scanners.py artifact_root --output scan-output
python scripts/build_findings_csv.py scan-output --output data/findings.csv
Der erste Befehl führt Semgrep und Trivy (Schwachstellen- und Geheimnis-Scanning) gegen jedes Artefaktverzeichnis aus und speichert das rohe Scanner-JSON. Der zweite parst dieses JSON in eine SAFE-kompatible findings.csv (Spalten entsprechen Eingabestruktur; file wird relativ zu jedem Artefaktverzeichnis angegeben). Übergeben Sie --skip-semgrep/--skip-trivy an eines der Skripte, um nur ein Tool auszuführen. --config auf run_scanners.py pinnt ein bestimmtes Semgrep-Regelset anstelle des Standard-auto, was praktisch, aber nicht reproduzierbar gepinnt ist.
Dieser Abschnitt dient der Ausführung von SAFE gegen Ihre eigene Befunde-CSV und Artefaktordner (siehe Eingabestruktur oben). Wenn Sie nur sehen möchten, wie SAFE läuft, verwenden Sie stattdessen Demo — config.example.yaml unten ist eine Vorlage und wird nicht wie besehen ausgeführt.
Kopieren Sie config.example.yaml:
cp config.example.yaml config.yaml
Bearbeiten Sie dann input_csv und artifact_root (und optional paper_root), um auf Ihre eigenen Daten zu verweisen, bevor Sie ausführen.
Wichtige Einstellungen:
model / provider: exakte OpenAI-Modellkennung (oder LiteLLM-Alias) und openai oder litellm mit Proxy-URL und Name der Anmeldeinformations-Umgebungsvariable.analysis_mode: zero_shot oder agentic.classification_task: binary oder multiclass; unabhängig von analysis_mode.max_agent_steps: nur in einer Agentic-Konfiguration erforderlich.max_workers / max_output_tokens / max_schema_retries: Parallelität, Ausgabeobergrenze pro Antwort und Modellaufruf-Wiederholungsbudget für schemaungültige Antworten.resume / resume_policy: incomplete wiederholt Fehler, fehlende Artefakte und nicht versuchte Befunde; failed_only wiederholt nur Fehler, während aufgezeichnete Erfolge beibehalten werden.cost: optionale Live-Kostenabrechnung und max_run_cost_usd-Beendigung.Das Standardmodell ist gpt-5.6-sol. Ändern Sie es explizit, wenn Verfügbarkeit, Kosten oder Latenzanforderungen abweichen.
safe-audit run --config config.yaml
Oder ohne Installation des Konsolenbefehls:
PYTHONPATH=src python -m safe_audit.cli run --config config.yaml
Für einen ausführbaren, passenden Vergleich mit den enthaltenen synthetischen Daten siehe Demo (demo/demo-zero-shot.yaml und demo/demo-agentic.yaml). Sie unterscheiden sich nur in analysis_mode und run_name. Zero-Shot führt einen Modellaufruf über die Basisevidenz durch. Der Agentic-Modus startet mit derselben Evidenz und kann begrenzte schreibgeschützte Repository-Tools aufrufen, bevor er dasselbe strukturierte Ergebnis zurückgibt.
runs/<run_name>/
├── config.resolved.yaml
├── run_metadata.json
├── summary.json
├── results.jsonl
├── results.csv
├── profiles/
├── evidence/
├── raw/<finding_uid>/
│ ├── 0001-request.json
│ ├── 0001-response.json (oder 0001-error.json)
│ └── final-output.txt
└── logs/
├── events.jsonl
├── result_attempts.jsonl
└── run_sessions.jsonl
results.csv ist für die Analyse gedacht. results.jsonl bewahrt die vollständigen strukturierten Datensätze. Evidenz und rohe Modellausgaben unterstützen Auditierung und Fehleranalyse. Beide sind kanonisch: Sie enthalten nur den neuesten Datensatz für jeden Befund, während logs/result_attempts.jsonl append-only ist und jeden historischen Ausgang bewahrt.
Beim Fortsetzen parst SAFE zuerst die gespeicherten Rohantworten jedes fehlgeschlagenen Befunds mit dem aktuellen strikten Parser neu; eine eindeutig gültige Klassifikation wird ohne API-Aufruf wiederhergestellt. Nur nicht wiederherstellbare Fehler werden für die Modellinferenz geplant. Für eine nur-fehlerhafte Fortsetzung einer teilweise abgeschlossenen Ausführung behalten Sie dieselben output_root und run_name bei und setzen:
resume: true
resume_policy: failed_only
Um Vorhersagen gegen eine gelabelte Gold-CSV (mit einer security_label- oder security_class-Spalte) zu bewerten:
safe-audit evaluate --results runs/<run_name>/results.jsonl --gold GOLD.csv --output runs/<run_name>/evaluation.json
PYTHONPATH=src python -m unittest discover -s tests -v
Die Testsuite verwendet einen Fake-Provider und benötigt daher keinen API-Schlüssel.