Amazon CodeCatalyst blueprints ran a project's own ownership field through a shell with no validation (CVE-2026-85012)
A .ownership-file's owner field is only ever an identity string, matched by wildcard against a package name, for every merge strategy identifier except the reserved word local. This entry confirmed directly, by cloning aws/codecatalyst-blueprints and reading the affected source, that for the local identifier the same field position was instead handed whole to Node's execSync with no character validation at all, in every version through 0.3.155. Formally assigned CVE-2026-85012 on 3 September 2026; this entry separately confirmed, from the current default branch and a direct ancestry check against the release history, that both an argument array construction removing the shell entirely and a character allow list rejecting a non conforming value were shipped in version 0.3.156 and remain unchanged in version 0.3.159.
Affected
- Organisation
- Amazon Web Services
- Product
- Amazon CodeCatalyst blueprints SDK
- Component
- The local merge strategy's owner field, parsed in packages/blueprints/blueprint/src/resynthesis/merge-strategies/deserialize-strategies.ts and executed in constructLocalStrategy and runLocalCommand in merge-strategies/local.ts, within the npm package @amazon-codecatalyst/blueprints.blueprint
- Versions
- This entry independently confirmed the unvalidated execSync call was introduced by the local merge strategy's own commit, at package version 0.2.15, and remained unchanged through version 0.3.155, the exact upper bound GHSA-c7rj-fr2j-64w7 itself states. Confirmed the fix, an argument array passed to execFileSync and a new character allow list, shipped in version 0.3.156 and remains unchanged in the current default branch, version 0.3.159
- Configurations
- Any direct consumer of the @amazon-codecatalyst/blueprints.blueprint npm package running resynthesis outside the managed Amazon CodeCatalyst service, against a project whose .ownership-file a committer with ordinary repository write access can edit
Execution authority facts
Fields the evidence does not establish are shown as unknown rather than guessed.
- Intended task
- Resynthesize an existing project by consulting its .ownership-file to decide, per path, which blueprint may modify it and which merge strategy resolves a conflict between the blueprint's proposed content and the project's existing content
- Agent
- The process performing resynthesis against the affected package version
- Delegating actor
- unknown
- Action
- A local merge strategy owner value containing shell metacharacters, substituted into a command string by formatLocalCommand and passed whole to child_process.execSync with no character validation, confirmed directly by this entry's own reading of the pre fix local.ts
- Target resource
- The shell of the process performing resynthesis, and whatever files, network access or credentials that process could reach from within it
- Environment
- unknown
- Credentials used
- unknown
- Privileges available
- Whatever privileges and credentials the resynthesis environment itself held, per the advisory's own stated consequence
- Authority presented
- Ordinary permission to commit to the project repository whose .ownership-file resynthesis reads, sufficient to edit the file at all
- Authority required
- Authority over the resynthesis environment's own shell, which no repository commit permission separately grants and which this entry's own reading of the source confirms was never independently checked
- Applicable policy
- unknown
- Approval mechanism
- unknown
- Required approver
- unknown
- Independent approval
- unknown
- Action binding
- unknown
- Sequence context
- unknown
Impact
- Consequence
- Arbitrary operating system command execution in the resynthesis environment, with whatever privileges and credentials that environment held, per GHSA-c7rj-fr2j-64w7's own stated consequence and this entry's own confirmation of the unvalidated execSync call it describes
- Reach
- single
- Reversibility
- unknown
- Detectability
- unknown
- Propagation
- A concrete propagation path exists, whatever the resynthesis environment's own credentials could reach beyond the local shell itself, but this entry did not observe the effect actually spreading to a further system
- Recovery
- Fixed in version 0.3.156, confirmed directly by this entry's own reading of the current source: local.ts calls execFileSync with a pre split argument array and no shell, and deserialize-strategies.ts rejects a local owner value outside a narrow allow list before that call is reached. The managed Amazon CodeCatalyst service separately applies its own server side validation, per AWS's own stated remediation, independent of blueprint version.
Evidence
Primary sources
- OS command injection in the Amazon CodeCatalyst blueprints SDK (CVE-2026-85012) (aws/codecatalyst-blueprints (GitHub Security Advisory GHSA-c7rj-fr2j-64w7))
- Commit e448811a: feat, blueprint, add local merge strategy (#364) (aws/codecatalyst-blueprints (GitHub, commit))
- Commit 7d120709: fix, harden command execution in synthesis (aws/codecatalyst-blueprints (GitHub, commit))
Supporting sources
- Commit 53f6ff19: chore(release), package version 0.3.156 (aws/codecatalyst-blueprints (GitHub, commit))
- local.ts, deserialize-strategies.ts and package.json on the current default branch (aws/codecatalyst-blueprints (GitHub, source))
- CVE-2026-85012, OS command injection in the Amazon CodeCatalyst blueprints SDK (AWS Security Bulletin 2026-095-AWS)
- Reproduction status
- Independently confirmed by Moona Intelligence cloning aws/codecatalyst-blueprints directly and reading the real, affected and fixed source, rather than by executing a resynthesis run against a live project. This entry read local.ts and deserialize-strategies.ts at the commit before the fix, confirmed the owner value reached execSync with no validation, then read the identical files after the fix and on the current default branch and confirmed both the shell free execution path and the character allow list.
- Evidence state
- Confirmed
Known unknowns
- Whether this has been exploited against a real project or a real resynthesis environment.
- The exact wording of AWS's own bulletin, 2026-095-AWS, since aws.amazon.com was blocked to direct fetch in this session on every attempt.
- Which body served as the assigning CVE Numbering Authority; cve.org and nvd.nist.gov were not independently checked in this session.
- The specific privileges and credentials any particular resynthesis environment holds, which this entry's sources describe only in general terms.
Limitations
- This session's direct fetch of aws.amazon.com was blocked by this session's network egress policy on every attempt; the bulletin's stated content is corroborated through the GitHub Security Advisory, read directly, and through independently phrased web searches converging on consistent wording, rather than read from the bulletin's own text.
- This entry verifies the mechanism by reading and comparing the affected and fixed source directly rather than by running a resynthesis process against a live project, since the exact validator and execution call already establish the outcome and the fix is already shipped.
Claim provenance
- verified
GitHub's Security Advisory Database, fetched directly in this session, assigns CVE-2026-85012, published 3 September 2026, rates it CVSS 3.1 base score 8.0, High, vector CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:U/C:H/I:H/A:H, and classifies it CWE-78, against @amazon-codecatalyst/blueprints.blueprint through version 0.3.155, fixed in 0.3.156.
The Ownership File Named Who Owned a Path. One Line Named a Command Instead. - verified
This session cloned aws/codecatalyst-blueprints directly and confirmed this commit introduces the local merge strategy, the formatLocalCommand string substitution and the unvalidated execSync call, with the package's own package.json reading version 0.2.15 at this commit, and confirmed, through git log against local.ts, that no later commit touched it before the fix.
The Ownership File Named Who Owned a Path. One Line Named a Command Instead. - verified
This session read this commit's complete diff directly and confirmed it rewrites local.ts to build an argument array and call execFileSync with no shell, and adds ALLOWED_LOCAL_CMD in deserialize-strategies.ts, a regular expression rejecting a local owner value outside a narrow character set before constructLocalStrategy is called.
The Ownership File Named Who Owned a Path. One Line Named a Command Instead. - verified
This session confirmed, through a direct ancestry check in the cloned repository, that commit 7d120709 is an ancestor of this commit, which changes the package's own package.json from version 0.3.155 to version 0.3.156, establishing that the fix reached the exact version the advisory names as fixed. This session separately read the current default branch, package.json reading version 0.3.159, and confirmed the fix remains unchanged.
The Ownership File Named Who Owned a Path. One Line Named a Command Instead.
