Skip to content

fix: validate contract artifact schema in CLI deploy/call path (A-836)#23921

Merged
PhilWindle merged 1 commit into
merge-train/spartan-v5from
phil/a-836-audit-188-cli-deploy-command-doesnt-validate-contract
Jun 8, 2026
Merged

fix: validate contract artifact schema in CLI deploy/call path (A-836)#23921
PhilWindle merged 1 commit into
merge-train/spartan-v5from
phil/a-836-audit-188-cli-deploy-command-doesnt-validate-contract

Conversation

@PhilWindle

Copy link
Copy Markdown
Collaborator

Fixes A-836 (Audit #188).

Problem

The CLI loaded contract artifacts via loadContractArtifact (getContractArtifact in cli/src/utils/aztec.ts). For an already-processed artifact, loadContractArtifact only runs the shallow isContractArtifact heuristic — its own JSDoc notes "The check is not exhaustive". It checks name/functions/nonDispatchPublicFunctions shape but never validates parameter ABIs, types, storage layout, outputs, etc. (Raw nargo output is already fully validated, since it flows through generateContractArtifactContractArtifactSchema.parse.)

A malformed-but-superficially-shaped artifact therefore bypassed schema validation and surfaced as an opaque error later during deployment/arg-encoding rather than a clear validation failure.

Fix

Add loadContractArtifactWithValidation in stdlib: it runs the full ContractArtifactSchema over an already-processed artifact before returning, and otherwise defers to loadContractArtifact (raw nargo stays validated as before). The returned object is identical to loadContractArtifact's — the schema parse is used purely as a validation gate. The CLI's getContractArtifact now uses it.

Scoped deliberately to the CLI (the audit's concern). loadContractArtifact is called at 100+ module-load sites with wire-form JSON; adding a stricter schema gate to all of them would have a large blast radius and risk rejecting legacy artifacts, so the unguarded function is left unchanged.

Test

Added loadContractArtifactWithValidation tests in contract_artifact.test.ts: a valid already-processed artifact (wire form) loads, and one whose functionType is a non-enum string — which still passes the shallow isContractArtifact check — is rejected. The rejection test fails without the schema gate and passes with it.

Note

Severity is MEDIUM in the finding, but as the artifact is local input the deployer supplies (not an untrusted network boundary) and downstream code still throws on bad input, the practical impact is closer to LOW (a clearer error message, earlier).

The CLI loaded contract artifacts via loadContractArtifact, which only runs
the shallow isContractArtifact shape check on already-processed artifacts
(parameter ABIs, types, storage layout, etc. were never validated). A
malformed artifact passed to the CLI therefore surfaced as an opaque error
later during deployment instead of a clear schema-validation failure.

Add loadContractArtifactWithValidation, which runs the full
ContractArtifactSchema over an already-processed artifact before returning
it (raw nargo output is already validated via generateContractArtifact).
The returned object is unchanged from loadContractArtifact; the schema
parse is used purely for validation. Scoped to the CLI to avoid validating
at the many module-load call sites of loadContractArtifact.
@PhilWindle PhilWindle added the ci-draft Run CI on draft PRs. label Jun 6, 2026
@PhilWindle PhilWindle marked this pull request as ready for review June 7, 2026 18:49
@PhilWindle PhilWindle merged commit a742e68 into merge-train/spartan-v5 Jun 8, 2026
31 checks passed
@PhilWindle PhilWindle deleted the phil/a-836-audit-188-cli-deploy-command-doesnt-validate-contract branch June 8, 2026 08:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci-draft Run CI on draft PRs.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants