
AI 에이전트가 실제 보안 취약점을 수정하는 성능을 평가하기 위한 벤치마크입니다.
tasks/{CVE-ID}/tasks/CVE-2026-33175/
├── meta.json # GHSA ID, CWE, CVSS, repo URL, vulnerable and fixed SHAs
├── setup.sh # Clones repo, checks out the vulnerable SHA, installs dependencies
├── run_tests.sh # Injects test_security.py into the repo and runs pytest
├── test_security.py # Security tests (xfail on vulnerable code, pass on the fix)
├── advisory.md # Full GHSA advisory (richest prompt)
├── diagnose.md # Behavioural description only — no file or function names
├── locate.md # File and function only — no description of the flaw
└── Dockerfile # Optional; only present when the task needs extra system deps
meta.json 예시:
{
"ghsa_id": "GHSA-xxxx-xxxx-xxxx",
"cwe": ["CWE-287"],
"cvss": 9.1,
"repo": {
"url": "https://github.com/org/project",
"vulnerable_sha": "abc123^",
"fixed_sha": "abc123"
}
}
setup.sh는 멱등적이므로 다시 실행해도 안전합니다. test_security.py는 실행 중에는 에이전트에게 숨겨져 있으며, 에이전트가 작업을 마친 후에만 주입됩니다.
python build.py
다음을 빌드합니다:
cve-bench/base) — Python 3.12, git, poetry 및 하네스.cve-bench/{task-id}) — 기본 이미지를 확장하고, 작업 디렉터리를 복사한 다음 setup.sh를 실행합니다.옵션:
# Build specific tasks only
python build.py --task CVE-2026-33175 CVE-2026-42561
# Skip rebuilding the base image
python build.py --skip-base
작업 이미지는 병렬로 빌드됩니다(최대 5개 워커). 작업 디렉터리에 Dockerfile이 포함된 경우 일반적인 docker/task.Dockerfile 대신 해당 파일이 사용됩니다.
벤치마크를 실행하기 전에 각 작업의 보안 테스트가 취약한 코드와 수정된 코드를 올바르게 구분하는지 확인하세요:
python validate.py
각 작업에 대해 작업 컨테이너 내부에서 세 가지 단계가 실행됩니다:
| 단계 | 검사 내용 |
|---|---|
| vulnerable | 보안 테스트가 취약한 SHA에서 실패(또는 xfail)해야 함 |
| fixed | 보안 테스트가 수정된 SHA에서 통과해야 함 |
| regression | 비보안 테스트가 수정된 SHA에서 통과해야 함 |
결과는 실시간 테이블로 표시됩니다. 어떤 작업이라도 어떤 단계에서 실패하면 종료 코드는 1입니다.
# Validate specific tasks only
python validate.py --task CVE-2026-33175 GHSA-r758-8hxw-4845
# Skip rebuilding images before validation
python validate.py --skip-build
python benchmark.py --model openai:gpt-5.5 poolside:laguna-m.1 --prompt-type advisory
옵션:
| 플래그 | 설명 | 기본값 |
|---|---|---|
--model | 하나 이상의 provider:model-id 문자열 | 구성된 모든 모델 |
--prompt-type | advisory, diagnose, locate 또는 임의의 조합 | 세 가지 모두 |
--task | 하나 이상의 작업 ID | 모든 작업 |
--clean | 시작 전에 선택된 범위의 기존 결과 삭제 | 꺼짐 |
지원되는 공급자:
| 제공자 | 형식 | API 키 환경 변수 |
|---|---|---|
| OpenAI | openai:gpt-5.5 | OPENAI_API_KEY |
| Anthropic | anthropic:claude-haiku-4-5-20251001 | ANTHROPIC_API_KEY |
| Poolside | poolside:laguna-m.1 | POOLSIDE_API_KEY |
각 실행은 results/에 JSON 결과 파일을 생성합니다:
results/{task-id}__{provider}:{model}__{prompt-type}.json
기존 결과 파일은 자동으로 건너뜁니다. 실행은 작업 전반에 걸쳐 동시에 수행되며(최대 20개 워커), 429 오류를 방지하기 위해 공급자별 속도 제한(공급자당 동시 활성 요청 1개)이 적용됩니다.
각 결과 파일은 다음 구조를 가진 JSON 객체입니다:
{
"cve_id": "CVE-2026-33175",
"model_id": "openai:gpt-5.5",
"prompt_type": "advisory",
"timestamp": "2026-05-01T12:00:00",
"model_duration_s": 142.3,
"test_duration_s": 8.1,
"turns": [
{
"tool_calls_and_results": [...],
"input_tokens": 12400,
"output_tokens": 310
}
],
"tests": [
{
"kind": "security",
"name": "test_email_verified",
"outcome": "passed"
}
]
}
tests[].kind는 "security"(test_security.py에서 유래) 또는 "regression"(프로젝트 자체 테스트 스위트에서 유래) 중 하나입니다. 모든 보안 테스트가 통과하고 회귀 테스트가 하나도 실패하지 않는 경우에만 해당 실행이 해결된 것으로 간주됩니다.
python generate_charts.py
results/의 모든 결과 파일을 읽고 SVG 차트를 docs/images/charts/에 작성합니다. Bokeh의 헤드리스 내보내기에는 Chrome/Chromium이 필요합니다(chromedriver-binary 사용).
하네스는 각 Docker 컨테이너 내부에서 python -m harness.run으로 실행됩니다. 프롬프트 로드, 에이전트 루프 실행, 결과 파일 작성을 담당합니다.
src/harness/
├── run.py # Entry point; parses args, wires components, calls BenchmarkRunner
├── client/
│ ├── factory.py # Parses provider:model-id, returns the correct LLMClient
│ ├── _client.py # Abstract LLMClient, ToolCall and LLMTurn dataclasses
│ ├── anthropic.py # Anthropic SDK integration
│ └── oai.py # OpenAI SDK integration (also used for Poolside)
├── agent/
│ ├── core.py # Agentic loop: calls client, dispatches tool calls, threads messages
│ └── runner.py # Wraps Agent, tracks timing and turn list
├── bench/
│ ├── runner.py # Orchestrates setup → agent → security tests → regression tests
│ ├── result.py # BenchmarkResult and TestResult dataclasses, JSON serialisation
│ └── repository.py # Writes result files to disk
└── task/
├── tools.py # Tool implementations: ListFiles, ReadFile, SearchInFiles,
│ # EditFile, CreateFile, DeleteFile, RunPytest
└── prompt_loader.py # Reads advisory.md / diagnose.md / locate.md
에이전트가 사용할 수 있는 도구:
| 도구 | 설명 |
|---|---|
list_files | 저장소의 파일 및 디렉터리 나열 |
read_file | 파일 내용 읽기, 선택적으로 줄 범위 지정 |
search_in_files | 코드베이스 전체에서 정규식 검색, 선택적 파일 글로브 지원 |
edit_file | 기존 파일의 줄 범위 교체 |
create_file | 새 파일 생성 |
delete_file | 파일 삭제 |
run_pytest | 프로젝트의 테스트 스위트 실행, JSON 보고서 반환 |
모든 도구는 디렉터리 트래버설을 방지하기 위해 저장소 루트를 기준으로 경로를 검증합니다. 에이전트는 test_security.py 또는 git 히스토리에 접근할 수 없습니다.
에이전트 루프는 최대 20턴 동안 실행됩니다. 턴 상한에 도달하면 실행은 그 상태 그대로 기록되며, 에이전트가 저장소를 남겨둔 상태를 기준으로 보안 테스트가 계속 실행됩니다.
tasks/{CVE-ID}/를 만들고 meta.json, setup.sh, run_tests.sh, test_security.py, advisory.md, diagnose.md, locate.md를 추가합니다.setup.sh와 run_tests.sh를 실행 가능하게 만듭니다(chmod +x).python validate.py --task {CVE-ID}.python build.py --task {CVE-ID}.이 작업은 독립적인 연구로 수행되었습니다. 연구를 수행하고 이 저장소를 준비하는 당시, 필자는 어떠한 기관에도 소속되어 있지 않았습니다.
@misc{gattipinheiro2026cvebench,
author = {Gatti Pinheiro, Giovanni},
title = {{CVE-Bench}: Benchmarking {LLM} Agents on Real-World Security Vulnerability Fixes},
year = {2026},
howpublished = {\url{https://giovannigatti.github.io/cve-bench}},
note = {Code available at \url{https://github.com/GiovanniGatti/cve-bench}}
}
MIT — LICENSE를 참조하세요.