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
zipHardhatorzipFoundrythat 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/wizardto0.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.mdwhen 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.
Related recipes
- Source-code injection sink audit
- Source-code supply chain build integrity audit
- Smart contract upgrade diff risk review
References
- GitHub Advisory: https://github.com/advisories/GHSA-4x76-22x2-rx8v
- Vendor advisory: https://github.com/OpenZeppelin/contracts-wizard/security/advisories/GHSA-4x76-22x2-rx8v
- Fixed release: https://github.com/OpenZeppelin/contracts-wizard/releases/tag/%40openzeppelin%2Fwizard%400.10.9
- Fix commit: https://github.com/OpenZeppelin/contracts-wizard/commit/ec12c44f8d9e0491eba31037f95b36e98ec58b5f