Conceptio › Archive › arXiv CS
arXiv CS open access

CyberForge: Verified Vulnerability Injection at Repository Level for Cybersecurity Agent Training

2026 · arxiv_cs
arXiv CS · Papers · 2026
Open Source ↗Direct PDF ↓
cryptographycybersecurityprivacysecurity
Conceptio Open Archive

Analyze & explore related research in Conceptio

Connect this record directly into your research workflow or AI agent. Explore citations across open repositories, query full text, and export structured proof bundles.

CyberForge: Verified Vulnerability Injection at Repository Level for Cybersecurity Agent Training Amine Lbath1,2∗ , Manan Suri1,3∗ , Aurelien Delaitre1 , Vadim Okun1 , Massih-Reza Amini2 , Ram D. Sriram1 , Dinesh Manocha3 1

National Institute of Standards and Technology, 2 Université Grenoble Alpes, CNRS, 3 University of Maryland, College Park

arXiv:2608.06471v1 [cs.CR] 6 Aug 2026

Abstract Despite recent advances, frontier large language model (LLM) agents remain limited in discovering and patching complex vulnerabilities in real-world software. Generally available agents can already aid attackers, who only need to find one exploitable weakness, while defenders must continuously identify and patch all vulnerabilities across fast-growing codebases. Stronger defensive agents would help close this gap, yet the scarcity of security training data with reproducible build and execution environments remains a bottleneck. We present CyberForge, a framework that synthesizes executable, repository-level security training data by injecting vulnerabilities into real C/C++ projects. It validates each instance dynamically: the injected build must pass the project’s unit tests, and generated proof-of-vulnerability (PoV) must trigger on the injected build and not on the clean one. CyberForge is not limited by the availability of disclosed vulnerabilities, therefore it can scale in comparison to data augmentation techniques which rely on historic CVE data. The resulting corpus holds 1 034 validated vulnerabilities across 80 projects and 63 weakness categories, with edit locality similar to real CVE patches under a real-versus-real noise floor. Fine-tuning on trajectories collected over this corpus improves SEC-bench patch repair by +3.3 to +14.7 points, in all six configurations of three model scales and two teachers, with the 31B student reaching its GPT-5.4-mini teacher, 72.7 % against 74.0 %. These gains generalize out of distribution to PatchEval, a corpus containing other programming languages, where every configuration also improves and the 31B student passes its teacher. Code and data are available at https://cyb3rforge.github.io.

1

Introduction

Agentic systems have started finding real vulnerabilities. Anthropic’s Mythos reported thousands of zero-day findings across operating systems and browsers (Anthropic 2026) and most recently, OpenAI disclosed that models under evaluation autonomously found and chained zero-days into a re∗

These authors contributed equally. Disclaimer: Certain trade names and company products are mentioned in the text or identified. In no case does such identification i mply recommendation or endorsement by the National Institute of Standards and Technology (NIST), nor that they are necessarily the best available for the purpose.

mote code execution path on Hugging Face’s production infrastructure (OpenAI 2026). On repository-level benchmarks that ask a model to locate a weakness in a real codebase and demonstrate it with an executable proof-of-vulnerability (PoV), even the strongest systems remain limited (Anthropic 2026; Wang et al. 2026a; Lee et al. 2025). The imbalance this creates favors attackers. An attacker needs one exploitable weakness and can retry indefinitely; a defender has to continuously secure an entire codebase. The balance shifts back only when automated detection and repair become dependable (Potter et al. 2025; Zhuo et al. 2026). Developing such capability in models that defenders can deploy and adapt is the goal of this work. Availability of training data is the binding constraint (Potter et al. 2025; Zhuo et al. 2025a). Software-engineering agents benefited from datasets of packaged repositories with reproducible build and test environments, producing thousands of runnable instances and double-digit gains (Jimenez et al. 2024; Pan et al. 2025; Yang et al. 2025; Jain et al. 2025). Security-agent training lacks a comparable pipeline because its validation problem is more complex. Functional bugs are exposed by tests: the buggy version fails at least one test that the fixed version passes. A vulnerability must instead remain latent under existing tests and normal execution while still being triggerable by adversarial input through a PoV that succeeds only on the vulnerable version. Automating this dual validation at scale, without a human expert in the loop, is what makes security data synthesis harder than its software-engineering analogue. Existing runnable vulnerability datasets are assembled from disclosed Common Vulnerabilities and Exposures (CVEs) and bug-bounty reports, and are mostly built to evaluate rather than to train (Lee et al. 2025; Wang et al. 2026b; Zhang et al. 2025; Ullah et al. 2025). Each disclosure has to be turned into an instance by reconstructing a historical environment, locating the vulnerable state, and recovering a working PoV. Manual setup does not scale, automated replay succeeds only in part (Wang et al. 2026b; Lee et al. 2025). More fundamentally, these resources remain limited by the rate of human vulnerability discovery and public disclosure. Capture-the-flag tasks avoid that dependency but are built in idealized settings and transfer poorly to real software (Wang et al. 2026b; Zhu et al. 2025). Function-level injection techniques can be used to train LLMs to become vulnerability

Table 1: Comparison of CyberForge with related work. Synthetic injection exists at function granularity (VGX, AVIATOR, ProSec) but targets detection models rather than agents and validates without execution. Existing project-level resources are evaluation artifacts whose growth is limited by the rate of public disclosure. No prior system supplies project-level training data from synthetic injection validated by execution. System

Purpose

Scope

Tasks

Bounded by disclosure

Validation

VGX (Nong et al. 2023) AVIATOR (Lbath et al. 2026) ProSec (Xu et al. 2025)

Vuln. detection Vuln. detection Secure gen.

Function Function Function

Detection Detection Alignment

× × ×

Static Static Static

CTF-Dojo (Zhuo et al. 2025b) CyberZero (Zhuo et al. 2025a)

Training Training

CTF CTF

Exploitation Exploitation

✓ ✓

Execution Simulation

SEC-bench (Lee et al. 2025) CyberGym (Wang et al. 2026b) BountyBench (Zhang et al. 2025) CVE-Genie (Ullah et al. 2025) CVE-Factory (Luo et al. 2026)

Evaluation Evaluation Evaluation Evaluation Training

Project Project Project Project Project

PoV, patch Exploitation Detect, exploit, patch Exploitation Patch

✓ ✓ ✓ ✓ ✓

CVE replay CVE replay Bug bounty CVE replay Automated CVE replay

CyberForge (ours)

Training

Project

PoV, patch

×

Differential PoV

detectors, but transfer badly to realistic project level settings (Risse and Böhme 2024; Ding et al. 2024; Lbath et al. 2026). We introduce CyberForge, a scalable framework for generating executable, repository-level, PoV-validated security training data from real-world C/C++ projects. CyberForge creates new training instances by injecting candidate weaknesses into existing codebases. Rather than mining historical disclosures, this framework decouples corpus growth from the rate of human discovery and disclosure, while preserving the properties needed for agent training: realistic codebases, reproducible build and execution environments, and end-toend PoV validation. CyberForge implements two complementary pipelines. Fuzzer-guided injection uses OSS-Fuzz (Google 2016) coverage to find sites reachable by an existing harness, so validation can lean on the harness itself. Agentic in-context injection synthesizes weaknesses beyond harness reach. It combines a workflow of autonomous agents, static analysis tools, in-context examples, and iterative retry to synthesize and validate vulnerabilities end-to-end. Each instance operates on reproducible containerized environments derived from OSS-Fuzz images and is checked by a differential PoV oracle that requires the original and injected build to pass all tests and the PoV to trigger only on the injected build. Across 80 C/C++ projects CyberForge produced 1 034 validated vulnerabilities spanning 63 weakness categories. We fine-tune three open students, Gemma 4 31B, 12B and E4B (Google DeepMind 2026), under two teachers, GPT5.4-mini and Gemma 4 31B itself. All six configurations improve SEC-bench patch repair, by +3.3 to +14.7 points; the strongest raises the 31B student from 58.0 % to 72.7 %, comparable to the GPT-5.4-mini teacher that supervised it. The same training transferred to Go, JavaScript and Python repair on PatchEval, while the training corpus contains none of those languages. Contributions: • A repository-level generation framework. CyberForge synthesizes cybersecurity-agent training data from buildable codebases through vulnerability injection and differential PoV validation, with two complementary pipelines. • Validated corpus of project level vulnerabilties. 1 034 instances over 80 projects and 63 categories, with edit locality inside the noise floor separating two real CVE

corpora. • Downstream performance improvements. SEC-bench score improves in all six student–teacher configurations, by +3.3 to +14.7 points, and the gains hold on PatchEval, an out-of-distribution cross-language benchmark.

2

Related Work

Table 1 compares CyberForge with prior vulnerabilitygeneration, training and evaluation systems. SWE-bench (Jimenez et al. 2024) established repositorylevel evaluation from real pull requests, and SWE-Gym (Pan et al. 2025), SWE-Smith (Yang et al. 2025) and R2EGym (Jain et al. 2025) turned the same idea into training data by synthesizing bugs inside runnable environments. SWESmith is the closest analogue to our injection pipeline, but its oracle does not apply to our case. It accepts an injection once a unit test fails, which signals that a functional bug was introduced. Our criterion is the opposite: the injected build must still pass every unit test, and the weakness may surface only under a PoV input that leaves the clean build unaffected. Cyber-Zero (Zhuo et al. 2025a) synthesizes agent trajectories without executable environments, simulating runtime feedback from CTF writeups. CyberForge keeps execution in the loop, so every trajectory is grounded in a build that actually compiles and a PoV that actually triggers. SEC-bench (Lee et al. 2025), CyberGym (Wang et al. 2026b), BountyBench (Zhang et al. 2025) and CVEGenie (Ullah et al. 2025) assemble runnable instances from disclosed vulnerabilities. They are evaluation artifacts, rather than scalable training pipelines, and remain limited by the supply of publicly disclosed vulnerabilities VGX (Nong et al. 2023) and AVIATOR (Lbath et al. 2026) inject weaknesses at function granularity to train detectors, validating statically or with learned filters rather than by execution. Neither produces a runnable project, and functionlevel supervision has transferred poorly to realistic detection (Risse and Böhme 2024; Ding et al. 2024). CyberForge injects into repository-level buildable projects and dynamically validates instances.

Figure 1: Overview of CyberForge. Two injection pipelines synthesize candidate vulnerable/patch pairs from OSS-Fuzz C/C++ projects; a shared differential PoV oracle admits a pair only if the injected build passes the project’s tests and the PoV triggers on it alone; a teacher model collects verified trajectories for supervised fine-tuning.

3

CyberForge

Figure 1 presents CyberForge, an end-to-end vulnerability injection framework, that includes two complementary pipelines: 1) Fuzzer-guided Injection, which utilizes fuzzer metadata to prompt an LLM agent to inject the vulnerability, and 2) In-context Agentic Injection, which performs iterative injection in a specialized agent workflow. The generated vulnerabilities are validated using a differential oracle, after which the injections are used to mine teacher trajectories using capable models.

3.1

Project Setup

Source and scope. CyberForge targets C/C++ projects enrolled in OSS-Fuzz (Google 2016). Two properties motivate the choice. Memory-safety defects, prevalent in these programming languages, remain the dominant class of critical CVEs in systems software (Xin et al. 2025), and OSS-Fuzz ships per-project Docker images with build scripts, sanitizer configuration and libFuzzer harnesses, which gives reproducible environments without per-project engineering. Environment construction and qualification. For each candidate project, we build a container with a compiled binary, ASAN (Serebryany et al. 2012) and UBSAN (LLVM Project 2026) instrumentation, and the project’s existing harnesses. No project-specific build logic is written, and every step is delegated to the project’s preexisting build.sh. A project enters the pool only if its tests build and run unattended, pass at a 100 % rate on the unmodified codebase, with identical results across five runs. Projects with flaky tests are rejected. This process retained 100 qualified projects, 80 of which eventually contributed at least one validated instance.

3.2

Vulnerability Injection

Pipeline 1: Fuzzer-Guided Injection This pipeline uses the existing fuzzer infrastructure of each OSS-Fuzz project

to identify high-value injection sites, code locations that are both security-relevant and reachable by an existing libFuzzer harness, and then validates injections automatically, eliminating the need for a manually written PoV. Step 1: Reachability extraction. For each project, we parse the offline OSS-Fuzz metadata cache, combining Fuzz Introspector reports, which summarize per-fuzzer reachability and coverage, with harness definitions and per-fuzzer coverage statistics to construct a reachability map of all functions reachable from at least one fuzzing harness. Step 2: Candidate scoring and selection. Each reachable function is scored along two axes and ranked by a weighted combination of these scores. The first is a function score based on reachability kind (runtime vs. static), structural role (e.g., parser entry point, buffer writer, decoder conversion, container access), call depth, fanout (the number of functions it directly calls), and file coverage. The second is a triggerability score estimating how likely an injected fault at that site can be reached and triggered by an existing harness, using parser proximity, path signal strength, guard-to-sink distance (i.e., the proximity between a safety check and the operation it protects), and blocker proximity (i.e., the presence of nearby checks that may prevent malformed inputs from reaching the candidate site). Candidates are further diversified by capping per-file density and round-robin selecting across harness, role, and vulnerability category buckets to avoid duplication. Each selected candidate is annotated with an inferred weakness type (e.g., removed bounds check, unchecked index, copy-size constraint removal) and a confidence tier. Step 3: LLM injection agent. The agent is given the candidate function, the precise site location and downstream operation within it, the inferred vulnerability category, the harness context, and the input format family (e.g., font binary, ZIP archive, UTF-16 text) derived from the harness subsystem.

It also receives vulnerability-category-specific edit guidance specifying allowed modifications (e.g., operator widening, off-by-one bound change) and hard constraints (e.g., no new branches, single-file edit, preserve the downstream operation). The agent introduces one minimal, targeted modification that weakens the existing security check at the identified location. The modified project is compiled and run against unit tests; if either fails, the agent is prompted to retry. Step 4: PoV generation and fuzzer-based validation. Once the injection passes unit tests, the agent produces a PoV script that exercises the injected fault. The PoV is guided by the input format context: the agent is provided with the input model, preferred seed extensions, and PoV-writing constraints derived from the harness. Given this context, the agent must demonstrate the vulnerability via a deterministic one-shot execution rather than open-ended fuzzing. This PoV is validated immediately by the shared differential PoV verifier (§3.3). As a complementary validation path, a post-hoc libFuzzer run is also executed against the injected build. The run uses a format-aware seed corpus: format-specific input generators produce seeds matched to the harness’s input model (e.g., GSUB table mutations for font parsers, ZIP header mutations for archive handlers), which are first replayed individually and then used to seed a timed libFuzzer run. Any input found by the fuzzer that triggers the vulnerable behavior on the new build is recorded as an additional confirmed PoV. Injections for which neither the agent PoV nor the fuzzer produces a trigger unique to the injected build are discarded. Pipeline 2: Agentic In-Context Injection This pipeline complements the other by synthesizing new vulnerabilities beyond those reachable by existing fuzz harness, drawing on candidate sites from two complementary selection strategies. Candidate selection by hybrid retrieval. The first strategy matches the target project against the PrimeVul dataset of C/C++ functions containing historical CVEs (Ding et al. 2024), combining structural and semantic similarity retrieval (Luan et al. 2021; Cambronero et al. 2019). A structural retriever compares functions by the n-grams of their AST node-type sequences (Jiang et al. 2007), so that matches reflect code topology rather than identifier names. A semantic retriever compares dense embeddings of the function text by cosine similarity. Their ranked lists are merged by reciprocal rank fusion (Cormack, Clarke, and Büttcher 2009). A lightweight reranking step then demotes trivial accessor functions and isolated, uncalled helper functions. Each retained match supplies both an injection site in the target project and an aligned example pair (secure, vulnerable) that serves as the in-context template for the injection. Candidate selection by agentic exploration. The second strategy lets specialist LLM agents explore the codebase directly, broadening diversity beyond sites that match known CVE patterns. A planner LLM splits a candidate budget across specialists, each responsible for one family of weaknesses, according to how relevant each family is to the project. Their proposals are then pooled, deduplicated, and

ranked by an LLM score estimating how plausible, reachable, and project-relevant each proposed vulnerability is. Injection stage. Each injection target is specified by the selected code location, the Common Weakness Enumeration (CWE) type, and its call chain and dataflow, recovered with the static-analysis tool CodeQL (GitHub 2024). The agent modifies the project to introduce the vulnerability and produces an injection description. The modified project is then compiled and run against unit tests. Compilation or test failures trigger a revision loop back to this stage. Taint analysis and PoV generation. The project is then analyzed using agent-based taint analysis to identify dataflow paths through which attacker-controlled input can reach the injected vulnerable location, providing valuable context on how to trigger the vulnerability. The PoV generation stage then constructs a proof-of-vulnerability using available signals: ASAN/UBSAN sanitizer reports, observable failure behavior, side effects (file writes, memory leaks), and output differences between the vulnerable and clean builds. Verification and retry. The generated PoV is passed to a verifier, which runs the differential PoV oracle, and checks that the observed behavior is attributable to the injected vulnerability, with the sanitizer reporting the expected type of error at the expected code location, not an unrelated or spurious failure. If verification succeeds, the vulnerable code, its PoV, and the sanitizer report are saved. Otherwise, the loop retries PoV generation; after a fixed number of retries it loops back to the injection stage for a fresh injection.

3.3

Differential Validation

Both pipelines converge on a shared validation criterion. Condition 1: Passing unit tests. A valid injection must not break any existing unit tests on the vulnerable build, as it must be latent: present in the code but not triggered by normal execution paths, reflecting the nature of real-world security weaknesses that survive production testing and code review. Condition 2: Differential PoV validation. The PoV must trigger on the injected build and not on the clean build under identical input. The condition validates injection and PoV jointly, since neither is meaningful without the other.

3.4

Task Formation and Training

Task construction matches SEC-bench (Lee et al. 2025), following the same methodology as (Luo et al. 2026), so that training and evaluation align. The pipeline records full interaction traces from an agent running on this task in autonomy inside the generated dataset. Success is decided by the differential oracle of §3.3 rather than by the agent’s own report, so a trajectory that claims success without passing validation is discarded like any other failure. Applying the methodology from (Pan et al. 2025; Luo et al. 2026), only the successful trajectories are then used to train a model.

4

Experimental Setup

Trajectory Collection For teacher trajectory extraction we used Mini-SWE-Agent (SWE-agent Team 2024), as a

SEC-bench

PatchEval

Model

(%)

Strict (%) PoV (%)

Teachers (reference) GPT-5.4-mini Gemma 4 31B

74.0 58.0

13.0 12.2

15.2 14.4

Gemma 4 E4B (base) CyberForge-E4B

6.0 10.7 ↑4.7

2.6 5.2 ↑2.6

3.9 6.5 ↑2.6

9.3 ↑3.3

9.1 ↑6.5

10.4 ↑6.5

8.7 16.0 ↑7.3

3.9 6.1 ↑2.2

3.9 8.7 ↑4.8

16.7 ↑8.0

12.8 ↑8.9

14.1 ↑10.2

58.0 64.7 ↑6.7

12.2 12.4 ↑0.2

14.4 15.7 ↑1.3

72.7 ↑14.7

14.8 ↑2.6

16.5 ↑2.1

Gemma 4 31B teacher

CyberForge-E4B GPT-5.4-mini teacher

Gemma 4 12B (base) CyberForge-12B Gemma 4 31B teacher

CyberForge-12B GPT-5.4-mini teacher

Gemma 4 31B (base) CyberForge-31B Gemma 4 31B teacher

CyberForge-31B GPT-5.4-mini teacher

lightweight agentic scaffold. To prevent corrupting the run, the execution stays inside the project’s OSS-Fuzz container with no network access, and no access to the reference patch, so it cannot recover the answer it is being trained to derive. Models and training. We fine-tune three open students, Gemma 4 31B, 12B and E4B (Google DeepMind 2026), under two teachers: Gemma 4 31B itself, giving a selfdistillation setting, and GPT-5.4-mini as a stronger teacher. Every run uses the same recipe and the same agentic scaffold at train and test time. We train LoRA adapters (r=32, α=64, dropout 0.05), at learning rate 1×10−4 for three epochs on one H200. Evaluation. The main benchmark is SEC-bench (Lee et al. 2025), with 150 instances from 24 projects, evaluating patch success rates. We also evaluated on PatchEval (ByteDance Security Research 2025), as an out-of-distribution test, with 230 instances in Go, JavaScript and Python, none of which appear in our C/C++ corpus.

5 5.1

Results

SEC-bench score (%)

Table 2: CyberForge, trained at different scales, with different teachers evaluated on SEC-bench (C/C++; in-domain), and PatchEval (Py, JS, Go; out-of-domain).

16.0

16

12.1 12B base

8

3.6

0 220

440

880

training trajectories

Figure 2: Training data scaling evaluated on SEC-bench. Self-distillation and stronger teacher. On PatchEval the GPT-5.4-mini students beat the self-distilled ones at every scale, by 2.4 to 6.7 points. On SEC-bench the advantage grows with scale: 8.0 points at 31B, 0.7 at 12B, and at E4B it reverses, the Gemma teacher reaching 10.7 % against 9.3 %, both still beating their 6.0 % base. Notably, self-distillation helps at every scale, so the corpus carries signal that does not depend only on teacher’s capabilities, paving the way for strong models learning from their own trajectories extracted through our workflow. Fine-tuning steers task resolution toward the teacher. Figure 3 splits each instance a student solves by where the ability came from: the student could already solve it before fine-tuning, its teacher can solve it, or neither can. Every student is steered in varying degree toward tasks its teacher can specifically solve. E4B is steered entirely onto them: all 14 of its solutions are ones the teacher also solves, and none of the nine its base solved survive, yet it picks up only 14 % of what the teacher can do and its base cannot. 31B gives up almost nothing, keeping 79 of its base’s 87, and picks up 62 %, with 12B in between at 31 % kept and 18 % picked up. The smallest student is therefore steered the furthest and gains the least from it, which points to student capacity rather than the corpus as the limit. At 31B the student also moves past both sources, solving 10 instances that neither its base nor its teacher solves. Gemma 4 E4B

Gemma 4 12B

Gemma 4 31B

1

0

1

0 0

0

8

14

0 89

3

transfer 14% · kept 0%

base

4 18

9

7 80

10

transfer 18% · kept 31%

CyberForge student

72

7

20

12

transfer 62% · kept 91%

GPT-5.4-mini teacher

Figure 3: Analysis of teacher transfer, and base retention on SEC-bench.

Fine-Tuning on CyberForge Trajectories

Over the 1 034 generated instances, we collected agent trajectories from two teachers: 1 194 accepted trajectories from GPT-5.4-mini vs. 880 from Gemma 4 31B. Table 2 reports the performance of students trained on these trajectories. Benchmark evaluation. On SEC-bench, all six student– teacher pairs gain from +3.3 to +14.7 points. The largest gain comes from Gemma 4 31B under a GPT-5.4-mini teacher, from 58.0 % to 72.7 %, within 1.3 points of the teacher. The Gemma 4 12B student roughly doubles from 8.7 % to 16.7 %.

The two teachers produce complementary students. Because the two students differ in which instances they solve, running both and keeping the successful run, recovers far more than either alone. Computed post hoc over the same runs and at the cost of a second inference pass, this ensemble scoring reaches 18.0, 25.3 and 82.0 % at E4B, 12B and 31B, 7.3 to 9.3 points above the better single student at every scale. The complementarity is significant enough to be worth more than scale or supervision: two E4B students beat the best sin-

5.2

Validated

68.2 75.5 77.6 77.6

0.0 2.8 3.5 7.5

Generated Corpus

CyberForge made 16 172 injection attempts, of which 1 034 passed validation over 80 projects and 63 weakness categories. Writing a plausible injection is easy; producing one the differential oracle accepts is the hard part. Table 3 ablates Pipeline 2: a naive single-pass agent already compiles and passes unit tests in 68.2 % of attempts, yet none of these pass validation, and the full workflow lifts the rate of plausible injections to 77.6 % while taking validated yield from 0 % to 7.5 %. Pipeline 1 shows the same from the validation side: a post-hoc fuzz-replay stage raises yield substantially with the injection stage untouched. The gain comes from the machinery around the injection, not from better injections.

Each agent turn is one shell command, and a command can do several things at once, so a turn can take more than one label: explore, edit, verify, or the combination edit+verify, which we treat as its own state. Workflow coverage c is the share of instances on which a verify occurs at or after an edit. Step budgets differ across runs, so every turn-indexed quantity uses the first 30 turns, the largest common horizon. Students move toward their teacher’s behavior. Figure 6 compares each run’s trajectory behavior between the base and fine-tuned model. Three of the four metrics measure the same thing: whether the agent finishes an edit → verify cycle and returns something gradeable. Fine-tuning improves all three: each moves toward the teacher’s value, the star, at every scale but one, E4B under the GPT teacher, which stays flat on the verified-final rate and still emits malformed output on 12.7 % of instances. The fourth, atomic edit+verify, tracks which teacher supervised the student, not its scale. Workflow coverage c ↑ better

SEC-bench score ↑ better 100 60

% of 150

Naive single pass Taint analysis only Retry loops only Full workflow

Injected

How Fine-Tuning Changes Agent Behavior

40 20

100

base

75 50

% of 150

Other (injection) (760)

10

tuned

base

Empty-patch rate ↓ better

10

tuned

Atomic edit+verify no preferred direction % of turns

20

No patch (2,064)

20

0 base

Build/apply (3,696)

tuned

Format-error rate ↓ better

Verified-final rate ↑ better

Validated 1,034

P1

50

tuned

25

10,967

75

25 base

% of 150

Configuration

5.3

% of 150

Table 3: Workflow ablation for Pipeline 2.

Pipeline 1 loses 64.2 % of its candidates at the validation stage and Pipeline 2 58.8 % at injection. A PoV that never triggers is the largest single cause of failure in both pipelines (44.6 and 33.1 %). Pipeline 2 additionally fails three times as often at producing a usable patch (24.2 % against 8.7 %), as its injection sites go beyond fuzzer reachability. We measured how closely the released instances resemble the real CVE patches in SEC-bench (Lee et al. 2025), using the two-sample Kolmogorov–Smirnov distance (Smirnov 1948) over the functions an edit touches. The distance is 0.165, against a 0.190 floor measured between two real CVE corpora, which supports the claim our injected vulnerabilities are near-realistic. The protocol is included in the supplement.

% of 150

gle 12B student, 18.0 against 16.7 %, and two 31B students beat the teacher that trained them, 82.0 against 74.0 %. The gains transfer out of distribution. PatchEval holds 230 CVEs in Go, JavaScript and Python, disjoint from the C/C++ training corpus, and scores each patch under a strict criterion and a PoV-blocking one. Every teacher–student pair improves on both: the 12B student by +8.9 strict and +10.2 PoV, and the 31B student reaches 14.8 % strict against the teacher’s 13.0 %. This indicates that our training data enabled the model to generalize the concepts, rather than learning language-specific knowledge. Performance scales with corpus size. In Figure 2, the number of training trajectories varies, holding the student (Gemma 4 12B), the teacher (Gemma 4 31B) and the LoRA recipe fixed. Scores rise monotonically, from 3.6 to 12.1 to 16.0 % as the corpus doubles twice, with no sign of saturation at 880 trajectories. Importantly, at 220 trajectories the student scores below its own base model, so a corpus too small to teach the workflow is worse than no fine-tuning at all.

40 20

0

PoV never fires (6,203)

P2

base

tuned

base

tuned

5,205 PoV on clean too (1,508) Other (validation) (907)

Figure 4: Analysis of the Cyberforge data generation pipeline. Figure 4 shows that the two pipelines fail at different stages:

GPT-5.4-mini (reference) Gemma 4 31B teacher GPT-5.4-mini teacher

Gemma 4 E4B Gemma 4 12B Gemma 4 31B

Figure 6: Visualization of behavorial metrics comparing the base models (open markers) against fine-tuned CyberForge models (filled), with teacher models as anchors.

Teacher Models 150

50

75

0

0

E4B 12B 31B

100

150

50

75

0 100

0

50

75

0 100

0

50

75

150

trajectories still active

GPT-5.4-mini

base

Base Models / Student Models

distribution of actions (%)

Gemma 4 31B 100

150

0

0

1

15

explore

30

edit

verify

1

15

edit+verify

other

30

trajectories still active

1

15

30

fewer than 10 active

Figure 5: Analysis of coarse agent action behavior over 30 turns, demonstrating transfer of agent action density from teacher models to respective Cyberforge student models Two independent channels. The SEC-bench score decomposes exactly as score = c qv + (1 − c) qu , with qv the solve rate among instances that reached an edit → verify cycle and qu the rate among the rest. The two terms move independently and in opposite directions across scales. At 12B coverage quadruples, 20.7 → 82.7 %, while qv is flat, so the gain comes entirely from the model reaching the verification stage. At 31B coverage is already saturated and barely moves, 92.7 → 100.0 %, while qv rises 10.1 points. The same training repairs whichever channel was broken. The 12B base edits without verifying. The mechanism behind the coverage gap is visible turn by turn (Figure 5). The 12B base model spends its trajectory issuing edit commands, a median of 14 per trajectory among those that edit at all, while completing an edit → verify cycle on 20.7 % of instances with a median of zero such cycles. It edits blindly and never checks its work, and its active count falls fastest of any run. Both of its fine-tunes acquire the verification band, and format violations collapse from 38 instances to 2 under the Gemma teacher and 0 under the GPT teacher. Batching is a teacher fingerprint. GPT-5.4-mini writes and tests in a single command in 51 % of its turns, where base models do so in 7 to 11 % of theirs. Students distilled from it move toward it, 12B from 7 to 55 % and 31B from 9 to 22 %, while the Gemma-teacher students at the same scale do not. At 31B, the student taught by GPT closes the gap with its teacher in behavior space as well as in score (c = 100.0 against 98.7 %, qv = 72.7 against 74.3 %): distillation transferred the workflow, not merely the accuracy.

6

Conclusion

We presented CyberForge, which builds security training data by injecting weaknesses into real C/C++ projects. In-

stances are verified through execution: the injected build must pass the project’s own tests, and the proof of vulnerability must trigger on it but not on the clean build. Instances are created rather than mined, so corpus growth is decoupled from the rate of public disclosure. Across 80 OSS-Fuzz projects the two pipelines produced 1 034 validated instances in 63 weakness categories, and the functions their edits touched are distributed about as locally as those of real vulnerabilities. Training on trajectories collected over this corpus improved SEC-bench in all six student–teacher configurations, by +3.3 to +14.7 points, with the 31B student reaching 72.7 % against its teacher’s 74.0 %. The gains transfer across languages: every configuration also improved on PatchEval, which is entirely Go, JavaScript and Python while the training corpus is entirely C/C++. CyberForge gives defenders a scalable source of execution-validated data for training their own security agents.

Ethical Statement CyberForge aims to close the training-data gap on the defensive side of AI-assisted security. All injected vulnerabilities are synthetic modifications of open-source code, not previously unknown bugs in deployed software. Models fine-tuned on CyberForge trajectories have improved cybersecurity capabilities. Our framework does not produce an exploit to actively operationalize a weakness and compromise a system. Instead, it generates a proof of vulnerability (PoV) that demonstrates a weakness exists and is reachable, without delivering a malicious payload. We note that similar capabilities already exist in other models; our contribution is to study the role of targeted training data, not to introduce capabilities that do not otherwise exist.

References Anthropic. 2026. Claude Mythos Preview. https://red. anthropic.com/2026/mythos-preview/. Accessed: May 2026. ByteDance Security Research. 2025. PatchEval: A MultiLanguage Benchmark for Automated Vulnerability Repair. arXiv preprint arXiv:2511.11019. Cambronero, J.; Li, H.; Kim, S.; Sen, K.; and Chandra, S. 2019. When Deep Learning Met Code Search. In Proceedings of the 2019 27th ACM Joint Meeting on European Software Engineering Conference and Symposium on the Foundations of Software Engineering (ESEC/FSE), 964–974. Cormack, G. V.; Clarke, C. L. A.; and Büttcher, S. 2009. Reciprocal Rank Fusion Outperforms Condorcet and Individual Rank Learning Methods. In Proceedings of the 32nd International ACM SIGIR Conference on Research and Development in Information Retrieval, 758–759. Ding, Y.; Fu, Y.; Ibrahim, O.; Sitawarin, C.; Chen, X.; TizpazNiari, S.; Millstein, T.; Ray, B.; and Wang, Y. 2024. PrimeVul: Vulnerability Detection with Code Language Models at Industry Scale. In IEEE Symposium on Security and Privacy (S&P). GitHub. 2024. CodeQL. https://codeql.github.com/. Accessed: 2026-06-28. Google. 2016. OSS-Fuzz: Continuous Fuzzing for Open Source Software. https://github.com/google/oss-fuzz. Google DeepMind. 2026. Gemma 4. https://deepmind. google/models/gemma/gemma-4/. Accessed: 2026-07-01. Jain, N.; et al. 2025. R2E-Gym: Procedural Environments and Hybrid Verifiers for Scaling Open-Weights SWE Agents. In Conference on Language Modeling (COLM). ArXiv:2504.07164. Jiang, L.; Misherghi, G.; Su, Z.; and Glondu, S. 2007. DECKARD: Scalable and Accurate Tree-Based Detection of Code Clones. In Proceedings of the 29th International Conference on Software Engineering (ICSE), 96–105. Jimenez, C. E.; Yang, J.; Wettig, A.; Yao, S.; Narasimhan, K.; and Press, O. 2024. SWE-bench: Can Language Models Resolve Real-World GitHub Issues? In International Conference on Learning Representations (ICLR). Lbath, A.; Amini, M.-R.; Delaitre, A.; and Okun, V. 2026. AVIATOR: Towards AI-Agentic Vulnerability Injection Workflow for High-Fidelity, Large-Scale Code Security Datasets. arXiv preprint arXiv:2508.20866. Lee, H.; et al. 2025. SEC-bench: Automated Benchmarking of LLM Agents on Real-World Software Security Tasks. arXiv preprint arXiv:2506.11791. LLVM Project. 2026. UndefinedBehaviorSanitizer. https: //clang.llvm.org/docs/UndefinedBehaviorSanitizer.html. Clang documentation. Accessed: 2026-07-01. Luan, Y.; Eisenstein, J.; Toutanova, K.; and Collins, M. 2021. Sparse, Dense, and Attentional Representations for Text Retrieval. Transactions of the Association for Computational Linguistics (TACL), 9: 329–345. Luo, X.; Zhang, J.; Zhou, S.; Huang, R.; Xiao, C.; Zhu, Q.; Ma, Z.; Yue, X.; Yue, Y.; Zeng, W.; and Che, W.

2026. CVE-Factory: Scaling Expert-Level Agentic Tasks for Code Security Vulnerability. In Proceedings of the 43rd International Conference on Machine Learning (ICML). ArXiv:2602.03012. Nong, Y.; Fang, R.; Yi, G.; Zhao, K.; Luo, X.; Chen, F.; and Cai, H. 2023. VGX: Large-Scale Sample Generation for Boosting Learning-Based Software Vulnerability Analyses. arXiv preprint arXiv:2310.15436. OpenAI. 2026. OpenAI and Hugging Face partner to address security incident during model evaluation. https://openai.com/index/hugging-face-modelevaluation-security-incident/. Accessed: 2026-07-28. Pan, J.; Wang, X.; Neubig, G.; Jaitly, N.; Ji, H.; Suhr, A.; and Zhang, Y. 2025. Training Software Engineering Agents and Verifiers with SWE-Gym. In International Conference on Machine Learning (ICML). ArXiv:2412.21139. Potter, Y.; Guo, W.; Wang, Z.; Shi, T.; Li, H.; Zhang, A.; Kelley, P. G.; Thomas, K.; and Song, D. 2025. Frontier AI’s Impact on the Cybersecurity Landscape. arXiv preprint arXiv:2504.05408. Risse, N.; and Böhme, M. 2024. Top Score on the Wrong Exam: On Benchmarking in Machine Learning for Vulnerability Detection. arXiv preprint arXiv:2408.12986. Serebryany, K.; Bruening, D.; Potapenko, A.; and Vyukov, D. 2012. AddressSanitizer: A Fast Address Sanity Checker. In Proceedings of the 2012 USENIX Annual Technical Conference (USENIX ATC 12), 309–318. USENIX Association. Smirnov, N. 1948. Table for Estimating the Goodness of Fit of Empirical Distributions. The Annals of Mathematical Statistics, 19(2): 279–281. SWE-agent Team. 2024. mini-swe-agent: The 100 line AI agent that solves GitHub issues. https://github.com/SWEagent/mini-swe-agent. GitHub repository. Ullah, S.; Balasubramanian, P.; Guo, W.; Burnett, A.; Pearce, H.; Kruegel, C.; Vigna, G.; and Stringhini, G. 2025. From CVE Entries to Verifiable Exploits: An Automated MultiAgent Framework for Reproducing CVEs. arXiv preprint arXiv:2509.01835. Wang, Z.; Schiller, N.; Li, H.; He, J.; Holz, T.; and Song, D. 2026a. ExploitGym: Can AI Agents Turn Security Vulnerabilities into Real Attacks? arXiv preprint arXiv:2605.11086. Wang, Z.; Shi, T.; He, J.; Cai, M.; Zhang, J.; and Song, D. 2026b. CyberGym: Evaluating AI Agents’ Real-World Cybersecurity Capabilities at Scale. arXiv:2506.02548. Xin, Z.; Cao, S.; Sun, X.; and Lo, D. 2025. Large Language Model for Vulnerability Detection and Repair: Literature Review and the Road Ahead. ACM Transactions on Software Engineering and Methodology, 34(5): Article 145. Xu, X.; Su, Z.; Guo, J.; Zhang, K.; Wang, Z.; and Zhang, X. 2025. ProSec: Fortifying Code LLMs with Proactive Security Alignment. In International Conference on Machine Learning (ICML). ArXiv:2411.12882. Yang, J.; Lieret, K.; Jimenez, C. E.; Wettig, A.; Khandpur, K.; Zhang, Y.; Hui, B.; Press, O.; Schmidt, L.; and Yang, D. 2025. SWE-smith: Scaling Data for Software Engineering

Agents. In Advances in Neural Information Processing Systems (NeurIPS), Datasets and Benchmarks Track. Spotlight. arXiv:2504.21798. Zhang, A. K.; et al. 2025. BountyBench: Dollar Impact of AI Agent Attackers and Defenders on Real-World Cybersecurity Systems. In Advances in Neural Information Processing Systems (NeurIPS), Datasets and Benchmarks Track. ArXiv:2505.15216. Zhu, Y.; et al. 2025. CVE-Bench: A Benchmark for AI Agents’ Ability to Exploit Real-World Web Application Vulnerabilities. In International Conference on Machine Learning (ICML). Spotlight. arXiv:2503.17332. Zhuo, T. Y.; Ding, Y.; Guo, W.; and Meng, R. 2026. To Defend Against Cyber Attacks, We Must Teach AI Agents to Hack. arXiv preprint arXiv:2602.02595. Zhuo, T. Y.; Wang, D.; Ding, H.; Kumar, V.; and Wang, Z. 2025a. Cyber-Zero: Training Cybersecurity Agents without Runtime. arXiv preprint arXiv:2508.00910. Zhuo, T. Y.; Wang, D.; Ding, H.; Kumar, V.; and Wang, Z. 2025b. Training Language Model Agents to Find Vulnerabilities with CTF-Dojo. arXiv preprint arXiv:2508.18370.

A

The CyberForge Corpus

This section describes the released corpus. An instance is one injected weakness together with the proof of vulnerability that triggers it, admitted only after the differential oracle accepted the pair. Table 4 provides an overview of our generated corpus. Table 4: The CyberForge corpus at a glance. Corpus Validated instances Pipeline 1 (fuzzer-guided) Pipeline 2 (agentic) OSS-Fuzz projects qualified contributing ≥ 1 instance Distinct weakness categories (CWE) Distinct CWE groups By language C++ C

A.1

1 034 643 391 100 80 63 25 Projects

Instances

73 27

697 337

Projects

CyberForge targets C and C++ projects from OSS-Fuzz. A project enters the pool only if its own test suite builds, runs unattended and passes at a 100 % rate on unmodified code. This left 100 qualified projects, 80 of which contributed at least one validated instance. Table 5 lists them.

A.2

Weakness Coverage

The corpus covers 63 CWE types across 25 classes. Table 7 enumerates every CWE type and Figure 7(a) shows the most frequently injected. Memory-safety weaknesses dominate, as they do among real C/C++ disclosures.

The two injection pipelines cover different CWE types, so running both increases coverage and diversity. The fuzzerguided pipeline covers 15 CWE types and relies on the paths recorded by existing libFuzzer harnesses, which favor memory safety weaknesses. The agentic pipeline covers 62 distinct CWE types. It selects sites using static analysis and retrieval, which allow for more freedom regarding the types of vulnerability it can inject. The pipelines’ coverage overlap on 14 CWE types. 46 projects received instances from both pipelines, 7 from the fuzzer-guided pipeline alone, and 27 solely from the agentic pipeline. Table 6: Weakness categories realized in the corpus, grouped by the coarse family the injection pipeline selects over. Groups are ordered by instance count and identifiers within a group by their own instance count. Group

CWE identifiers realized

Post buffer operation

CWE-125, CWE-120, CWE-130, CWE-129, CWE-122, CWE-119, CWE-787, CWE-121, CWE-170, CWE-126, CWE-680, CWE-823 CWE-193, CWE-131, CWE-369 CWE-476, CWE-824 CWE-20 CWE-416, CWE-415 CWE-190, CWE-191, CWE-189, CWE-197, CWE-682 CWE-404, CWE-400, CWE-399, CWE-666, CWE-770 CWE-703, CWE-391, CWE-754 CWE-252, CWE-690 CWE-78, CWE-74, CWE-77, CWE-95 CWE-401 CWE-863, CWE-203, CWE-354, CWE-532 CWE-264, CWE-284 CWE-200, CWE-209 CWE-22 CWE-362 CWE-590, CWE-762 CWE-269, CWE-271 CWE-457 CWE-674 CWE-134 CWE-475 CWE-670 CWE-485 CWE-227 CWE-617, CWE-665

Calculation Invalid pointer Web Expired memory Numeric errors Resource management Unhandled errors Return value Input validation Memory leak Other Access control Confidentiality Path-related Concurrency Memory release Privileges Initialization Loop and recursion Strings API Control flow Encapsulation Function call (none recorded)

A.3

Generated Instance Characteristics

Table 8 reports the size of the artifacts that make up a weakness instance. Injected edits are small and local, which helps them stay latent: 1 025 of 1 034 instances changed a single file, 944 confined the change to one hunk, that is one contiguous block of changed lines with its surrounding context. Every instance ships a PoV script to trigger the vulnerability, which implementation differs depending on the pipeline (Table 9). The fuzzer-guided pipeline replays an input recovered from a seeded libFuzzer session. The agentic pipeline ships a fixed input file the agent constructed, along with a driving program.

Table 5: All 100 qualified OSS-Fuzz projects. L: primary language. Type: application domain. Stars: GitHub stars where applicable. Files and KLoC: C/C++ source files and thousands of lines in the project’s own tree, measured over compiled sources. P1/P2: instances from the fuzzer-guided and agentic pipelines. CWE: distinct weakness categories present. UT: tests in the project’s own suite. Project

L

Type

Stars

arrow C++ Data 16 968 assimp C++ Media 13 101 behaviortreecpp C++ Utility 4 135 binutils C++ System – bluez C Network 1 120 brotli C++ Compr. 14 820 c-blosc C++ Compr. 1 056 c-blosc2 C++ Compr. 581 cgif C Media 150 cjson C++ Data 12 890 coturn C Network 14 261 cryptofuzz C++ Crypto 26 dnsmasq C Network – double-conversion C++ Numeric 1 193 envoy C++ Network 28 669 espeak-ng C++ Text 6 696 exiv2 C++ Media 1 145 ffmpeg C++ Media 62 591 file C++ Utility 1 639 flac C++ Media 2 371 flex C Runtime 4 036 fluent-bit C++ Network 8 001 fmt C++ Utility 23 696 freerdp C Network 13 508 ghostscript C++ Doc – grok C++ Media 290 guetzli C++ Media 12 917 h2o C++ Network 11 521 h3 C Numeric 6 432 haproxy C++ Network 6 742 harfbuzz C++ Text 5 957 hdf5 C Data 962 htslib C++ Data 939 hunspell C++ Text 2 550 icu C++ Text 3 563 jq C Data 35 308 json-c C++ Data 3 286 jsoncpp C++ Data 8 877 jsonnet C++ Runtime 7 549 kamailio C Network 2 891 kimageformats C++ Media – lcms C++ Media 730 leptonica C++ Media 2 068 libarchive C++ Compr. 3 572 libdwarf C System 256 libjxl C++ Media 3 610 liblouis C Text 338 libpng C++ Media 1 636 libredwg C Data 1 513 libsass C++ Runtime 4 325

Files KLoC P1 P2 CWE 6 636 134 1 603 455 111 143 431 73 28 51 228 11 39 893 112 201 1 057 37 156 35 2 198 68 1 462 2 078 967 48 355 174 467 399 1 279 159 56 1 134 57 137 30 104 420 87 35 568 995 284 590 81 36 446 148

4 0 9 300 12 10 373 0 3 2 013 0 0 316 7 4 43 29 10 92 6 7 140 0 12 7 7 5 11 7 23 26 5 16 135 0 0 10 0 6 329 34 5 184 0 0 57 8 8 107 3 3 337 0 0 22 1 0 70 4 4 31 0 3 1 344 6 1 70 29 11 534 0 3 2 086 0 1 437 0 7 10 33 13 164 0 6 36 67 17 303 0 3 166 27 5 1 140 5 0 117 8 2 90 4 12 589 6 3 39 20 13 17 9 5 14 0 2 124 0 2 185 20 3 41 0 0 44 17 1 324 2 8 243 0 6 148 0 3 196 10 9 53 0 0 42 22 2 990 0 0 40 9 17

UT

6 11 9 584 3 13 0 222 7 37 11 73 6 1 643 5 2 017 6 60 15 19 13 16 0 5 5 48 5 9 0 8 7 19 5 6 0 2 779 1 86 6 26 3 203 3 63 12 21 3 155 1 6 4 177 8 10 4 37 14 315 3 4 8 66 2 2 804 5 353 5 139 6 21 11 9 9 26 2 124 2 59 8 45 0 45 5 148 7 121 4 897 3 22 7 13 0 18 6 36 0 254 13 27

Project

L

Type

Stars

libsndfile C Media 1 705 libsrtp C++ Crypto 1 394 libucl C Data 1 739 libvips C++ Media 11 540 libxslt C++ Doc – libyang C Data 426 libzip C++ Compr. 1 033 lighttpd C Network 702 llvm C++ Runtime 39 572 mbedtls C++ Crypto 6 845 mruby C++ Runtime 5 597 njs C++ Runtime 1 588 ntopng C++ Network 8 047 open5gs C Network 2 657 open62541 C++ Network 3 192 opencv C++ Media 90 237 openh264 C++ Media 6 125 openjph C++ Media 291 opensc C++ Crypto 3 061 openssl C Crypto 30 536 openthread C++ Network 3 999 openvpn C Network 14 321 pcapplusplus C++ Network 3 121 pcre2 C++ Utility 1 329 perfetto C++ System – php C++ Runtime 40 267 poppler C++ Doc – protobuf-c C Data 2 985 pupnp C Network 437 qemu C System – qpid-proton C++ Network 249 quickjs C Runtime 10 889 radare2 C++ System 24 462 relic C++ Crypto 513 ruby C++ Runtime 23 666 selinux C System 1 612 serenity C++ System 33 706 simdjson C++ Data 24 102 skia C++ Media – systemd C++ System 16 540 unbound C Network 4 750 unicorn C++ System 9 201 uwebsockets C++ Network 18 937 wamr C Runtime 6 043 wireshark C++ Network – wuffs C++ Media 4 795 xz C++ Compr. 1 624 yajl-ruby C++ Data 1 489 zeek C++ Network 7 830 zlib-ng C++ Compr. 2 056

Files KLoC P1 P2 CWE 133 69 22 464 63 332 217 169 1 948 566 266 121 124 7 526 199 88 217 76 301 1 702 1 089 181 329 62 – 1 096 373 39 140 4 007 105 23 1 180 386 358 275 7 7 619 2 452 215 516 57 130 2 966 14 148 15 2 542 177

65 2 0 30 14 2 19 2 7 258 0 2 51 0 1 213 5 2 23 18 3 100 0 2 805 0 0 649 2 0 180 3 6 94 4 3 57 0 0 1 475 10 1 130 0 4 44 5 2 83 1 5 41 0 3 216 0 2 606 9 3 560 0 3 93 0 0 144 0 4 109 12 0 – 9 1 1 377 0 0 194 0 0 71 17 1 56 20 4 1 483 0 0 37 0 0 80 28 13 643 0 2 166 0 1 187 0 0 110 4 3 2 26 2 2 17 1 165 0 0 827 7 3 188 0 0 451 4 0 16 0 1 117 0 0 5 746 0 13 95 1 2 39 0 6 3 0 0 1 156 0 0 62 6 0

UT

2 143 6 11 6 8 2 7 1 10 4 61 9 183 2 232 0 10 1 133 7 1 773 4 6 024 0 17 5 3 4 15 4 135 5 631 3 82 2 5 6 26 3 9 0 17 4 304 4 4 2 649 0 816 0 15 6 11 6 14 0 213 0 29 16 8 1 575 1 19 0 894 5 68 4 7 5 118 0 8 6 15 0 88 2 11 1 7 0 148 8 9 2 78 3 19 0 416 0 113 2 70

Table 7: All 63 weakness categories realized in the corpus, ordered by instance count. Names follow MITRE. P1/P2: instances per pipeline, with the Pipeline 2 count split by selection strategy into E (agentic exploration) and R (retrieval). Pr.: projects in which the category occurs. CWE

Name

All

P1 P2

E

R Pr.

CWE-125 CWE-193 CWE-476 CWE-120 CWE-130 CWE-129 CWE-20 CWE-122 CWE-119 CWE-416 CWE-787 CWE-121 CWE-190 CWE-703 CWE-252 CWE-404 CWE-415 CWE-131 CWE-401 CWE-191 CWE-22 CWE-400 CWE-690 CWE-189 CWE-200 CWE-362 CWE-369 CWE-399 CWE-78 CWE-134 CWE-170 CWE-197 CWE-264 CWE-269 CWE-284 CWE-391 CWE-457 CWE-590 CWE-617 CWE-666 CWE-674 CWE-754 CWE-770 CWE-824 CWE-863 CWE-126 CWE-203 CWE-209 CWE-227 CWE-271 CWE-354 CWE-475 CWE-485 CWE-532 CWE-665 CWE-670 CWE-680 CWE-682 CWE-74 CWE-762 CWE-77 CWE-823 CWE-95

Out-of-bounds Read Off-by-one Error NULL Pointer Dereference Buffer Copy without Checking Size of Input (’Classic Buffer Overflow’) Improper Handling of Length Parameter Inconsistency Improper Validation of Array Index Improper Input Validation Heap-based Buffer Overflow Improper Restriction of Operations within the Bounds of a Memory Buffer Use After Free Out-of-bounds Write Stack-based Buffer Overflow Integer Overflow or Wraparound Improper Check or Handling of Exceptional Conditions Unchecked Return Value Improper Resource Shutdown or Release Double Free Incorrect Calculation of Buffer Size Improper Release of Memory Before Removing Last Reference (’Memory Leak’) Integer Underflow (Wrap or Wraparound) Improper Limitation of a Pathname to a Restricted Directory (’Path Traversal’) Uncontrolled Resource Consumption (’Resource Exhaustion’) Unchecked Return Value to NULL Pointer Dereference Numeric Errors Information Exposure Concurrent Execution using Shared Resource with Improper Synchronization Divide By Zero Resource Management Errors Improper Neutralization of Special Elements used in an OS Command Uncontrolled Format String Improper Null Termination Numeric Truncation Error Permissions, Privileges, and Access Controls Improper Privilege Management Improper Access Control Unchecked Error Condition Use of Uninitialized Variable Free of Memory not on the Heap Reachable Assertion Operation on Resource in Wrong Phase of Lifetime Uncontrolled Recursion Improper Check for Unusual or Exceptional Conditions Allocation of Resources Without Limits or Throttling Access of Uninitialized Pointer Incorrect Authorization Buffer Over-read Observable Discrepancy Information Exposure Through an Error Message Improper Fulfillment of API Contract (’API Abuse’) Privilege Dropping / Lowering Errors Improper Validation of Integrity Check Value Undefined Behavior for Input to API Insufficient Encapsulation Insertion of Sensitive Information into Log File Improper Initialization Always-Incorrect Control Flow Implementation Integer Overflow to Buffer Overflow Incorrect Calculation Improper Neutralization of Special Elements in Output Used by a Downstream Component (’Injection’) Mismatched Memory Management Routines Improper Neutralization of Special Elements used in a Command Use of Out-of-range Pointer Offset Improper Neutralization of Directives in Dynamically Evaluated Code (’Eval Injection’)

194 147 134 111 60 55 52 39 37 25 21 12 12 11 10 10 10 5 5 4 4 4 4 3 3 3 3 3 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

146 145 115 105 60 50 0 11 0 1 0 3 1 0 0 0 1 0 2 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

14 1 7 3 0 5 48 12 13 6 3 4 4 0 10 10 5 5 1 1 2 3 4 0 1 0 1 0 3 0 2 2 0 0 2 2 1 1 2 2 1 0 2 1 0 1 0 1 1 1 0 1 1 0 1 0 1 0 1 1 1 1 1

34 1 12 3 0 0 4 16 24 18 18 5 7 11 0 0 4 0 2 3 2 1 0 3 2 3 1 3 0 2 0 0 2 2 0 0 1 0 0 0 0 2 0 1 2 0 1 0 0 0 1 0 0 1 0 1 0 1 0 0 0 0 0

48 2 19 6 0 5 52 28 37 24 21 9 11 11 10 10 9 5 3 4 4 4 4 3 3 3 2 3 3 2 2 2 2 2 2 2 2 1 2 2 1 2 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

46 38 41 35 10 22 24 22 24 18 16 9 9 8 6 2 7 4 5 3 4 3 4 3 3 2 3 3 3 2 2 2 1 2 2 1 1 2 2 1 2 1 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

(a)

(b) 194

CWE-125 CWE-193 CWE-476 CWE-120 CWE-130 CWE-129 CWE-20 CWE-122 CWE-119 CWE-416 CWE-787 CWE-190 CWE-121 CWE-703 CWE-415 CWE-404 CWE-252 CWE-401 CWE-131 CWE-400

147 134 111 60 55 52 39 37 25 21 12 12 11 10 10 10 5 5 4

0

50

100

332

heap-buffer-overflow SEGV stack-buffer-overflow deadly-signal memory-leak global-buffer-overflow heap-use-after-free invalid-free/alloc-mismatch out-of-memory assertion-failure container-overflow stack-overflow FPE memcpy-param-overlap stack-buffer-underflow fuzz-target-exited allocation-size-too-big calloc-overflow Pipeline 1 SIGSEGV SEGV Pipeline 2

150

200

138 86 60 38 29 25 15 9 8 5 5 5 4 3 3 2 2 2 1

0

50

instances

100

150

200

250

300

350

instances

Figure 7: What the corpus covers, by pipeline. (a) The 20 most frequent CWE identifiers; Table 7 gives their names. (b) The 20 most frequent runtime fault classes in the sanitizer reports. Table 8: Size of the artifacts that make up an instance. Microaverages over all instances, not grouped by project; the final row is per project. Med.

Mean

p90

Max

Injected diff Lines added Lines deleted Lines changed Hunks Files

1 1 2 1 1

1.19 2.79 3.98 1.52 1.01

2 4 5 1 1

17 643 644 337 3

Verification artifacts PoV entry script (lines) Project test suite (tests)

20 41

22.69 281.60

49 633

185 6 024

Table 9: Form of the released proof of vulnerability. Lines: mean length of the exploit.sh entry point.

A.4

PoV form

All

P1

P2

Lines

fuzz-discovered replay script-constructed input fixed input file

421 341 272

421 222 0

0 119 272

4 36 35

Resemblance to Real Vulnerabilities

The main paper reports a Kolmogorov–Smirnov distance of 0.165 between the injected vulnerabilities and real ones, compared with a real-to-real baseline of 0.190. This section describes how those values were obtained. For an edit statistic, let x1 , . . . , xn denote the observations from the injected corpus and y1 , . . . , ym those from a reference corpus of real vulnerabilities. If Fn and Gm are their empirical distribution functions, the two-sample Kolmogorov–Smirnov statistic is Dn,m = sup Fn (x) − Gm (x) , x

It measures the largest gap between the two empirical distributions. A value of 0 means that the observed distributions coincide, while larger values indicate greater separation. The statistic requires no parametric model, which is useful because patch-size distributions are strongly skewed. The reference corpus contains all 300 SEC-bench realworld instances: 200 from the cve split and 100 from the oss split. We compute the statistic along five axes: functions changed, files changed, hunks, changed lines, and added lines. The first three capture the structure of an edit; the last two capture its size. A KS distance has no universal threshold for similarity. We therefore compare the SEC-bench oss and cve splits against each other. Since both contain real vulnerability patches, but still come from two separate data sources, their distance provides a practical baseline for the variation between two real corpora. An injected-to-real distance near or below this baseline is therefore not, by itself, evidence that the injected edits are distinguishable as artificial. For functions modified, the injected corpus has a distance of 0.165, below the real-to-real baseline of 0.190. The corresponding distances for files touched and hunk count are 0.123 and 0.243, compared with baselines of 0.065 and 0.205. Thus, the injected edits broadly resemble real patches in where and how they are distributed across the codebase.

B

Injection Pipelines

Both pipelines start from a selected candidate location and terminate at the same differential oracle. The fuzzer-guided pipeline (Figure 8) considers only functions reachable from an existing libFuzzer harness and ranks them by triggerability. The model performs a single-shot edit, after which the harness fuzzes the modified project for 90 s using a seeded corpus. A failed candidate is retried once before the pipeline moves on. The agentic pipeline (Figure 9) iteratively injects a weak-

Vulnerability Generation Stage 1: Input

Exploit Validation

Stage 2: Injection

Stage 3: Post-hoc Fuzzing

Stage 4: Verifier

LLM Injection

Post-hoc Fuzzing

Differential Verifier

Scored Location

✓ Crashes on vulnerable

Fuzzer harness Target function Triggerability Bug shape (CWE) fuzzer function scoring

Vulnerability Injection

Vuln. patch

single-shot edit

diff, builds

libFuzzer run

Crash found?

90 s, value profile builtin + curated corpus, replay

Yes

No

✓ Clean on original ✓ Unit tests pass

Verified?

Yes

No

Vuln. Snapshot

replay PoC on vulnerable vs. original build

rediscover a crashing input (PoV)

fail: retry the candidate once, else move to the next

Injection

Input

Fuzzing

Differential Verification

Figure 8: P1: CyberForge’s fuzzer-guided injection pipeline. Vulnerability Generation

Exploit Validation

Stage 1: Input

Stage 2: Injection

Stage 3: Reachability

Stage 4: Exploit

Stage 5: Verifier

Selected Location

Iterative Injection

Taint Analysis

PoV Generation

Differential Verifier

Selected CWE Call chain

Vulnerability Injection

Generated vuln.

Compile & unit tests

sink reachable from entry point

Dataflow Reachability tier from LLM or retrieval

Sink reached?

Yes

PoV oracle ASan, LSan, UBSan, crash side effect, output diff

No edit the sink, compile, run tests

CodeQL call chain

one oracle per weakness

✓ Triggers on vulnerable ✓ Clean on original ✓ Unit tests pass

No < 3 Verified?

Yes

No < 5

exploit on vulnerable vs. original build

Vuln. Snapshot

on failure, re-inject at the same site

Injection

Input

Reachability

Exploit

Differential Verification

Figure 9: P2: CyberForge’s agentic in-context injection pipeline.

ness at a selected location, using compiler and unit-test feedback. Once the project builds and its tests pass, a taintanalysis agent examines CodeQL-extracted dataflow from the source (an entry point through which external input enters the program) to the sink (a code location where that input is used in a potentially unsafe operation). The agent autonomously explores the dataflow graph backward from the sink, iteratively identifies inputs that could trigger the vulnerable behavior, and verifies that an external-input source can still reach the injected sink. If no such path exists, the analysis context is returned to the injection agent as feedback. Otherwise, a proof-of-vulnerability (PoV) agent constructs a trigger using strategies tailored to the weakness type. Both pipelines use Gemma 4 31B through mini-swe-agent. No sampling parameters are overridden, so generation uses the model defaults: temperature 1.0, top-p 0.95, and top-k 64. Each agent invocation is capped at 200 iterations.

C

Generation Cost

This section reports the cost of generating the CyberForge corpus and collecting the teacher trajectories. We account for self-hosted inference in two ways: the electricity consumed during generation and the estimated cost of processing the same number of tokens through a hosted API.

For API-based inference, we report the charges recorded by the provider. The accounting assumes 2×H100 SXM at 700 W, CPU nodes at 400 W, a PUE of 1.3, and average electricity cost at $0.1359/kWh. Hosted inference for a Gemma-class model is priced at OpenRouter’s published rate of $0.09 per million input tokens and $0.34 per million output tokens (2026-07-31). During our experiment GPT-5.4-mini was billed at $0.0375 per million cached input tokens and $2.25 per million output tokens. GPU time covers model inference. CPU time covers the per-project Docker containers used to build each target, run the fuzzing harnesses, and execute the unit tests. Container execution incurs no token cost, but its energy use is included in the metered electricity estimate. By contrast, the APIequivalent estimate prices model tokens only and excludes all container work, so it does not capture the full cost of running the pipeline on hosted infrastructure. Table 10 reports the GPU and CPU time used for vulnerability injection and teacher-trajectory generation. Table 11 reports token usage at each stage of the two pipelines. Table 12 summarizes the estimated cost of CyberForge. Corpus generation consumed $253 in electricity; pricing the same token volume at hosted-inference rates, while retaining the cost of running the containers, raises the estimate to

Cost (cents) 0

25

50

75

250

100

125

0

2

4

μ=11.6m, 43.3¢

6

μ=16.0m, 2.2¢

300

200 150

200

100 100

50 0

0 0

10

20

30

40

0

Teacher: GPT-5.4-mini

20

40

60

80

Teacher: Gemma 4 31B

Duration (min)

Figure 10: Time and cost per teacher trajectory generation run. Duration is read on the lower axis, cost on the upper one. Boxes give the means; axes are clipped at the 99th percentile. GPU electricity cost (cents) 0

5

10 250

μ=19.34m, 4.72¢

250

μ=11.20m, CPU only

μ=0.10m, CPU only 1000

300

200

200

200

150

150 100

100

50

50

0

0 0

25

50

μ=0.11m, CPU only

800 600 400

100

200 0

75

0

Injection agent

20

40

0 0.0

Build and tests

0.2

0.4

0.00

Fuzz replay

0.25

0.50

0.75

Differential check

Duration (min)

Figure 11: Time and cost breakdown of the P1 fuzzer-guided injection pipeline per attempt. The injection agent is the only stage that calls the model; the rest run on CPU. GPU electricity cost (cents) 0

2

4

6

μ=17.5m, 1.77¢

600

0.0

0.2

0.4

0.6

0.8

1.0

500

800

μ=2.1m, 0.47¢

μ=11.5m, CPU only

400

600

300

400

400

200

200

0

0 0

20

40

60

80

200 100 0 0

Injection agent 0

1

2

40

60

0.0

Unit-test suite 3

0

μ=16.1m, 1.80¢

300

20

2

4

500

2.5

5.0

7.5

10.0

12.5

Taint/path analysis 6

μ=35.1m, 3.23¢

400 200

300 200

100

100 0

0 0

20

40

60

PoV agent

80

0

50

100

150

Agentic attempt

Duration (min)

Figure 12: Time and cost per sub-agent of the P2 agentic injection pipeline per attempt.

Table 10: Compute used for corpus generation and teachertrajectory collection. CPU hours are machine-hours over the union of active intervals, so concurrent runs count once. The 2×H100 endpoint was shared across activities, so GPU wall time is not exclusive to one row. Hours

Table 12: CyberForge cost estimation for each task type including CPU electricity cost. Actual: paid electricity price (or token-cost for GPT-5.4-mini). API: token-based cost (estimated for Corpus generation and Gemma teacher). Per instance divides by the 1 034 validated instances.

Electricity

Total

Per instance

Activity

CPU

GPU

CPU

GPU

Parallelism

Activity

Actual

API

Actual

As API

Injection Teacher: Gemma 4 31B Teacher: GPT-5.4-mini

874 97 129

775 97 —

$62 $7 $9

$192 $24 —

4.7–13.0× 6.3× 2.7×

Corpus generation Teacher: GPT-5.4-mini Teacher: Gemma 4 31B

$253 $748 $31

$433 $748 $56

$0.25 $0.72 $0.03

$0.42 $0.72 $0.05

Total

$1 032

$1 237

$1.0

$1.2

Table 11: Token usage for each type of task and phase. Activity / phase Corpus generation P1 injection agent P1 fuzz replay P2 injection agent P2 PoV generation P2 taint analysis P2 other agents

Input

Output

958.8 M 15.47 M no model stage 1 668.2 M 30.84 M 819.3 M 19.55 M 286.7 M 5.58 M 116.1 M 2.00 M

Teacher trajectory collection GPT-5.4-mini 2 871.7 M Gemma 4 31B 526.1 M

143.23 M 4.07 M

Total

220.74 M

7 246.8 M

$433. Collecting the teacher trajectories cost $748, including $738.62 in measured API charges for GPT-5.4-mini and Gemma teacher runs consumed $31 in electricity. The total cost of generating the dataset and collecting teacher trajectories was $1 032, compared with an estimated $1 237 if all inference tokens had been purchased through hosted services. Amortized over the validated corpus, generation cost $0.25 per instance in electricity, or $0.42 when inference is valued at hosted rates. The corresponding fully API-billed costs are $0.87 per instance for SEC-bench and $2.77 for CVE-Genie. Figure 10 gives the distributions for teacher trajectories, which take 9 to 11 minutes at the median. Figure 11 breaks the fuzzer-guided attempt down by stage, where the injection agent and the build-and-test gate dominate and the replay and differential checks take about five seconds each, and Figure 12 the agentic attempt by sub-agent, with a median of 27 minutes. Both exclude the 9.6 % of model calls that returned an error before producing any output.

D

Supervised Fine-Tuning Details

We fine-tune Gemma 4 at three scales (E4B, 12B and 31B) on the teacher trajectories collected over the corpus, training one student per base model and teacher. All students use the same LoRA recipe: the base weights stay frozen and low-rank adapters are attached to the attention and MLP projections of the language model only, leaving the vision tower untouched. Table 13 lists the hyperparameters. Teacher-trajectory cleansing. Raw teacher trajectories are recorded in the teacher’s own generation environment and

Table 13: Fine-tuning configuration, identical across all six student/teacher combinations. Hyperparameter

Value

Base models Adaptation LoRA rank r LoRA α LoRA dropout Adapted modules Precision Attention Learning rate Weight decay Schedule Warmup ratio Optimizer Epochs Batch size Gradient accumulation Gradient clipping Gradient checkpointing Hardware Seed

Gemma 4 E4B / 12B / 31B LoRA, base frozen 32 64 0.05 attention + MLP projections BFloat16 SDPA 1e-4 0.0 Cosine 0.03 AdamW (fused) 3 1 2 1.0 Enabled 1×H200 (147 GB) or H100 42

are not directly usable for training a SEC-bench student, so we pass them through a cleansing pipeline before fine-tuning. (i) We retain only oracle-verified successful trajectories. (ii) We align the teacher environment to the SEC-bench evaluation harness (Lee et al. 2025): repro/build invocations are normalized to secb repro/secb build, exploit-artifact paths are remapped to /testcase, and ripgrep calls are rewritten to grep (the evaluation container lacks the ripgrep package). (iii) Each trajectory is linearized to one command per assistant turn. (iv) The teacher’s reasoning is retained, after removing its boilerplate bold-header summary. (v) Tool outputs are re-rendered through the evaluation observation template (a 10 k-character head/tail cap) and long observation histories are compressed with a sliding window (recent observations kept in full, older ones reduced to short stubs) so each trajectory fits the training context without ever truncating the assistant turn that writes the patch. In the main paper we show that our fine-tuned models maintain some gains even in out-of-distribution setting with different evaluation environment (keeping the mini-swe-agent

scaffold)

E

Example of Injected Vulnerability

Listing 1: Example of vulnerability injected by CyberForge in the Guetzli repository. The line in red is the one the injection deletes; nothing else changes. bool ProcessAPP(const uint8_t* data, const size_t len, size_t* pos, JPEGData* jpg) { VERIFY_LEN(2); size_t marker_len = ReadUint16(data, pos); VERIFY_INPUT(marker_len, 2, 65535, MARKER_LEN); - VERIFY_LEN(marker_len - 2); // Save the marker type with the app data. std::string app_str( reinterpret_cast<const char*>( &data[*pos - 3]), marker_len + 1); *pos += marker_len - 2; jpg->app_data.push_back(app_str); return true; }

This section presents one instance of the generated corpus, guetzli/vulnerability_FZ_24: the weakness CyberForge introduced, the input that triggers it and explanations about this vulnerability. Guetzli is Google’s JPEG compressor, used by image hosts, CDNs, and web developers to reduce image file sizes before delivery.

E.1

The Vulnerability

A JPEG file consists of a series of segments containing either compressed image data or metadata (e.g. color profiles and camera settings). Each segment begins with a two-byte length field that tells the decoder how many bytes belong to it. In ProcessAPP (Listing 1), the original code validates this field in two steps. VERIFY_INPUT checks that the declared length is valid under the JPEG format, between 2 and 65535. VERIFY_LEN then checks that the input buffer actually contains that many bytes. CyberForge removed the buffer-length check. As a result, a JPEG may declare a segment length of up to 65535 bytes while providing much less data. The std::string constructor uses the declared length when copying from the segment, causing it to read past the end of the input buffer. This is an out-of-bounds read, CWE-125, because the attacker controls the copy length without having to supply the corresponding number of bytes.

Ordinary unit tests are unlikely to catch the problem. JPEGs produced by conforming encoders contain segment lengths that match the available data, so the removed check has no visible effect on valid files. Triggering the bug requires a deliberately malformed JPEG with a valid length value but insufficient segment data.

E.2

E.4

Triggering the Vulnerability

The trigger is a 504-byte file that opens with the bytes: FF D8 FF E0 FF FF 4A 46 49 46

The file starts normally: FF D8 is the JPEG start marker, and FF E0 begins an APP0 metadata segment. The next two bytes, FF FF, declare a segment length of 65 535 bytes. This is the largest value accepted by VERIFY_INPUT. Only 504 bytes are present, so the removed VERIFY_LEN check would have rejected the file. Without it, the code proceeds using the declared length. The std::string constructor then attempts to copy 65 536 bytes from an offset three bytes into the buffer. Since only 501 bytes remain, the read extends 65 035 bytes beyond the end of the file.

E.3

Why the Defect Is Realistic

This bug follows the same basic pattern as Heartbleed (CVE2014-0160): an attacker supplies a length larger than the accompanying data, and the program reads beyond that data into adjacent memory. File formats with embedded length fields are especially prone to this class of error, including image metadata segments. The defect is also easy to miss. The attacker-controlled value is still checked against the JPEG format’s permitted range shortly before it is used, which can make the code appear adequately validated during review. The missing check concerns whether the declared length fits within the actual input buffer.

Impact

The out-of-bounds read could disclose server memory. In an unsanitized production build, the copied bytes become part of app_data and are written into the re-encoded JPEG returned to the uploader. Because the segment length is 16 bits, a single request can expose nearly 64,KB beyond the input buffer. The leaked region may contain data from other work handled by the same process, including image buffers or metadata belonging to other users. Depending on the heap layout, it could also contain session tokens, API keys, or other secrets. Repeated uploads may reveal different regions as allocations change. The request need not look like a failure. The service can accept the upload, return a valid JPEG, and record the operation as successful while unintentionally including process memory in the response.

E.5

Directory Structure and File Contents

Every instance ships as a self-contained directory with the following layout. The files that define this instance are reproduced below.

guetzli / | - - project . json # language , upstream URL , secure base commit | - - setup / # OSS - Fuzz build | | - - Dockerfile | | - - build . sh | `- - project . yaml | - - unit_tests / # non - regression gate | | - - test . sh # standardized entrypoint | `- - parse_results . py # - > {" passed ": N , " failed ": M} `- - vulnerabilities / | - - vulnerability_FZ_0 / # one directory per instance | ... `- - vulnerability_FZ_24 / # the instance detailed below |-- inject_vulnerability . diff # apply - > introduces the vulnerability |-- vulnerability_metadata . json # id , cwe_id , secure base commit |-- sanitizer_report . txt # sanitizer crash proving it triggers `-- exploit_files / |-- exploit . sh # proof - of - vulnerability entrypoint |-- fuzz_poc . py # PoV driver `-- generated_inputs / # seed corpus

project.json {

}

" project ": " guetzli " , " main_repo_url ": " https :// github . com / google / guetzli " , " target_dir ": " guetzli " , " secure_base_commit ": " 214 f2bb42abf5a577c079d00add5d6cc470620d3 " , " unit_tests ": {" enabled ": true , " expected_passing_count ": 10} , " language ": "c ++ "

inject_vulnerability.diff diff - - git a/ guetzli / jpeg_data_reader . cc b/ guetzli / jpeg_data_reader . cc @@ - 398 ,7 +398 ,7 @@ bool ProcessAPP ( const uint8_t * data , size_t * pos , ...) VERIFY_LEN (2) ; size_t marker_len = ReadUint16 ( data , pos ); VERIFY_INPUT ( marker_len , 2, 65535 , MARKER_LEN ); - VERIFY_LEN ( marker_len - 2) ; + // Save the marker type together with the app data . std :: string app_str ( reinterpret_cast < const char * >( & data [ * pos - 3]) , marker_len + 1) ;

vulnerability_metadata.json {

}

" id " : " vulnerability_FZ_24 " , " project ": " guetzli " , " producer ": " fuzz_poc_guided " , " cwe_id ": " CWE - 125 " , " cwe_group ": " Post buffer operation " , " secure_base_commit ": " 214 f2bb42abf5a577c079d00add5d6cc470620d3 "

exploit_files/exploit.sh #!/ bin / bash set - euo pipefail cd / src / guetzli python3 exploit_files / fuzz_poc . py

exploit_files/fuzz_poc.py (excerpt) fuzzer = CFG [" selected_fuzzer " ][ " fuzzer "] binary = Path ("/ out ") / fuzzer # the built OSS - Fuzz target ... def run_and_capture ( args , log_name ): proc = subprocess . run ( args , stdout = subprocess . PIPE , stderr = subprocess . STDOUT , text = True ) output = proc . stdout crash = (" AddressSanitizer " in output or " UndefinedBehaviorSanitizer " in output or " runtime error :" in output ) return proc , crash , ... ... # time - boxed libFuzzer campaign over the seed corpus args = [ str ( binary ) , f"- max_total_time ={ CFG . get (' max_total_time ', 60) }" , f"- max_len ={ max_len }" , f"- dict ={ dict_path }" , str ( CORPUS_DIR )] proc = subprocess . run ( args , stdout = subprocess . PIPE , stderr = subprocess . STDOUT , text = True ) ... asan_like = (" AddressSanitizer " in proc . stdout or " runtime error :" in proc . stdout ) crash = bool ( crash_artifacts ) or ( asan_like and not oom and not leak ) print ( " TRIGGERED " if crash else " NOT_TRIGGERED ")

exploit_files/generated_inputs/ - triggering input (504 bytes, hexdump) 00000000 ff d8 ff e0 ff ff 4a 46 49 46 00 01 01 02 00 1c ...... JFIF ...... 00000010 00 1c 00 00 ff db 00 43 00 28 1c 1e 23 1e 19 28 ....... C .(..#..( 00000020 23 21 23 2d 2b 28 30 3c 64 41 3c 37 37 3c 7b 58 #!# - +(0 < dA <77 <{ X ... # 504 bytes total . Bytes 0-1 = SOI ( ff d8 ); bytes 2-3 begin an APP0 # segment whose length field ( bytes 4- 5) is ff ff = 65535 , far more # than the 504 bytes present - > ProcessAPP reads past the input buffer .

sanitizer_report.txt (excerpt) ==432== ERROR : AddressSanitizer : heap - buffer - overflow READ of size 65531 at 0 x6fc93620b1f8 thread T0 #0 ProcessAPP jpeg_data_reader . cc :403:15 SUMMARY : AddressSanitizer : heap - buffer - overflow jpeg_data_reader . cc :403:15 in guetzli :: ProcessAPP

Related documents

Record · ID 440321 · SHA-256 23c56d499aadfc6f
Retrieved via Conceptio: every document is proof-bundled with source, license, and retrieval metadata.
Bring this data into your agent: Connect via MCP or API · 20 free credits to start · no card required
Read the Docs → · View CLI source on GitHub · Conceptio Open Knowledge Archive