CVE-2026-48054 - OpenZeppelin Wizard generated test code injection

@openzeppelin/wizard before 0.10.9 could generate Hardhat or Foundry test files that interpolated untrusted opts.name or opts.uri values into source code without escaping. If a caller passed attacker-controlled strings into zipHardhat or zipFoundry, the downloaded project could contain test code that executed when a developer later ran npm test or forge test.

The hosted Wizard site was already redeployed by the vendor, but repositories that embed the package or call those generator functions directly still need a code-level remediation path.

When to use it

Use this recipe when a repository embeds @openzeppelin/wizard, wraps OpenZeppelin Contracts Wizard APIs, or exposes Hardhat/Foundry project generation through a web app, API, CLI, template service, agent tool, or saved contract metadata. It is for generated-code injection where untrusted contract names or URIs can become source text in generated tests.

Use it to upgrade the generator, constrain inputs, and add inert-source regression tests. Do not use it to generate or execute malicious test projects.

Inputs

  • npm manifests, lockfiles, workspaces, SBOMs, generated dependency reports, package builds, docs, and local forks/wrappers that reference @openzeppelin/wizard.
  • Calls to zipHardhat, zipFoundry, or equivalent local generation paths, including API, CLI, UI, agent, and template-service entry points.
  • Data-flow evidence for generator options such as contract names, token names, URIs, saved templates, request fields, CLI args, workspace files, or agent-generated configuration.
  • Generated project fixtures, archive packaging, CI/download flows, and any automation that runs generated tests after creation.
  • Validation commands for dependency install, generator tests, package build, lint/typecheck, SBOM refresh, and security scans.

Affected versions

  • Vulnerable: @openzeppelin/wizard <0.10.9
  • Fixed: @openzeppelin/wizard 0.10.9+
  • Affected surface: direct callers of zipHardhat or zipFoundry that forward externally controlled strings into generator options

Indicator-of-exposure

  • The repository depends on @openzeppelin/wizard <0.10.9.
  • Code calls zipHardhat, zipFoundry, or local wrappers around those APIs.
  • Untrusted user input, request fields, CLI arguments, or saved templates feed contract names, token names, or URIs into generated test output.

Quick checks:

rg -n "@openzeppelin/wizard|zipHardhat|zipFoundry|opts\\.name|opts\\.uri|wizard" .
npm ls @openzeppelin/wizard
pnpm why @openzeppelin/wizard

Windows:

rg -n "@openzeppelin/wizard|zipHardhat|zipFoundry|opts\\.name|opts\\.uri|wizard" .
npm ls @openzeppelin/wizard
pnpm why @openzeppelin/wizard

Remediation strategy

  • Upgrade to @openzeppelin/wizard 0.10.9+.
  • Sanitize or strictly validate any externally controlled values before they reach code-generation functions.
  • Treat generated projects as build artifacts that can become execution paths once tests or scripts run.
  • Add regression tests that verify generated Hardhat and Foundry test files keep attacker-controlled strings inside literals.

The prompt

Model context: this prompt was generated by GPT 5.5 Extra High reasoning.

You are remediating CVE-2026-48054 / GHSA-4x76-22x2-rx8v in
`@openzeppelin/wizard`. The issue lets unescaped generator inputs break out of
test-file literals and execute when generated tests run. Produce exactly one
output:

- A reviewer-ready PR/change request that upgrades the package, constrains input
  handling, adds generator regression tests, and documents affected workflows,
  or
- TRIAGE.md if this repository does not control an affected generator path.

## Rules

- Scope only CVE-2026-48054 and directly related code generation paths.
- Treat generated archives, templates, secrets, and CI tokens as sensitive.
- Do not generate a malicious project or execute injected test code.
- Do not remove Hardhat or Foundry generation features outright unless product
  owners already approved that change.
- Do not auto-merge.

## Steps

1. Inventory every `@openzeppelin/wizard` dependency, wrapper, service,
   archive-generation path, and documentation workflow in this repository.
2. Determine whether the code directly calls `zipHardhat` or `zipFoundry`, or
   exposes equivalent local generation paths.
3. Trace whether untrusted values can reach generator options such as contract
   names or URIs.
4. If the repository does not control an affected generator path, stop with
   `TRIAGE.md` listing files checked and the external owner.
5. Upgrade to `0.10.9+` and refresh lockfiles, generated artifacts, and SBOMs.
6. Add or tighten validation for user-controlled generator inputs so dangerous
   characters cannot break source literals.
7. Add regression tests that generate sample projects with hostile-looking
   names/URIs and verify the generated test files remain inert source text.
8. Review any CI, download, or packaging path that automatically runs generated
   tests after project creation.
9. Add a PR body section named `CVE-2026-48054 operator actions` covering:
   - versions before and after;
   - which generator functions were in scope;
   - whether untrusted input could reach them;
   - any downstream projects that need regeneration;
   - validation that passed.
10. Run available validation: dependency install, unit tests, generator tests,
    linting, package build, and security scans.
11. Use PR title:
    `fix(sec): remediate CVE-2026-48054 in OpenZeppelin Wizard`.

## Stop conditions

- The repository only consumes the hosted Wizard site and does not own the
  vulnerable generator code.
- Verification would require producing and running an injected test artifact.
- Product requirements intentionally allow arbitrary source fragments in
  generator input; document the risk and stop for review.
- Validation fails for unrelated pre-existing reasons; document those failures.

Verification - what the reviewer looks for

  • No controlled dependency resolves @openzeppelin/wizard <0.10.9.
  • Untrusted generator input is escaped, rejected, or otherwise constrained before test-file emission.
  • Regression tests prove hostile names/URIs remain data, not executable code.

Watch for

  • Upgrading the package while a local wrapper or fork still reproduces the old string interpolation behavior.
  • Validating UI fields but leaving API or CLI entry points unsanitized.
  • Generated project fixtures committed to the repo that still contain unsafe payload shapes.

Output contract

Return one of:

  • A reviewer-ready PR/change request that upgrades @openzeppelin/wizard to 0.10.9+, constrains untrusted generator inputs, proves generated Hardhat and Foundry test files keep hostile-looking values inside inert literals, refreshes generated artifacts, and documents affected workflows.
  • TRIAGE.md when the repository does not control an affected generator path, wrapper, service, archive-generation flow, or dependency artifact.

The output must list versions before/after, generator functions in scope, untrusted input sources, wrappers or forks changed, downstream projects that need regeneration, validation commands, and any remaining owner decisions. It must not generate a malicious project, execute injected tests, expose secrets from generated archives, or remove generation features without an explicit product decision.

References