A generated abstract illustration on a pale grey-blue field with a faint blueprint grid: a large square drawn in thin dark-slate outline sits centre-right, enclosing a vertical stack of five pale grey file-shaped sheets. A single amber line leaves the stack, runs left, and passes cleanly through the square's left wall, ending in a small solid amber square in the left third of the frame among a few scattered, unaligned grey rectangles. The boundary line stays unbroken where the amber line crosses it. No text, numbers, people, brand marks or organisation logos appear. The OrcaRouter logo is composited in the bottom-right corner.
AI Safety Incidents

CVE-2026-18953: AWS's Transform MCP Server Had No Write Boundary

Author

Alistair Wren

Date Published

Latest models · 20View all models →
Benchmarks: Artificial Analysis · updated daily
Back to all posts

Amazon published security bulletin 2026-075-AWS on 5 August 2026 for CVE-2026-18953, a path traversal in the get_resource tool of awslabs.aws-transform-mcp-server, the open-source Model Context Protocol server that runs on a developer's own machine so an AI assistant can drive AWS Transform jobs and retrieve their artifacts. Versions 0.1.0 through 0.1.4 did not adequately restrict pathnames, and the savePath parameter could write files outside the intended working directory — which the GitHub advisory in Amazon's repository says "could lead to local code execution." Amazon scored it 8.6, High. The fix is version 0.1.5, and there is no server-side or configuration-only workaround, because the vulnerable code path is present in the default configuration. No public source has recorded anyone exploiting it. The full record, with its severity and confidence grades, sits in the Orca AI Incident Archive alongside the MCP and agent-runtime incidents filed under the same month.

An MCP server that writes where the developer works

Model Context Protocol servers are the layer that gives an assistant callable tools, and this one is deliberately local. Amazon's bulletin describes it as "an open-source MCP server that runs locally on a developer's machine and lets AI-powered assistants interact with AWS Transform to run code-transformation jobs and retrieve their artifacts." Its package description on the Python Package Index says it exposes the Transform lifecycle through 19 tools, managing transformation workspaces, jobs, connectors, human-in-the-loop tasks, artifacts and chat, and covers mainframe modernization, VMware migration, .NET modernization and custom code transformations.

That placement is what makes the flaw matter. A server on a vendor's own infrastructure that mishandles a filename corrupts the vendor's storage. This one ran as the developer, in the developer's home directory, beside their shell configuration and SSH keys, and the impact Amazon describes is not a corrupt download but "local code execution." Every score attached to the CVE agrees on one point: the attack vector is local, not network.

The tool named in the advisory is the one that brings a job artifact down to disk. get_resource takes a savePath naming where the file should land. The bug is that nothing stopped that path from naming somewhere else.

How bad, and by whose arithmetic

Three scores are attached to this CVE and they do not match. Amazon, which assigned the CVE as the numbering authority, scores it 8.6 High on CVSS v3.1 with the vector CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:H — local, low complexity, no privileges required, user interaction required, scope changed, high impact on confidentiality, integrity and availability. NIST's entry in the National Vulnerability Database carries its own primary v3.1 score of 8.8 on a different vector, CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H: low privileges required, no user interaction. Both land in the High band. The disagreement is about preconditions — whether the actor already needs a foothold, and whether a human has to be persuaded — not about how bad the outcome is.

Amazon's CVSS v4.0 score for the same CVE is 6.3, Medium, on CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:P/VC:N/VI:N/VA:N/SC:H/SI:H/SA:H. Read the impact metrics: nothing on the vulnerable system itself, everything high on the subsequent system. That is the shape of a traversal that breaks out of a tool's own boundary — the damage is done to whatever the tool can reach, so it lands in the sub-system column and the vulnerable system scores zero.

A self-built HTML card titled 'One CVE, three scores', badged 'CVE-2026-18953 · CWE-22', subtitled 'Who scored it, on which scale, and what the vectors disagree about'. A table of four rows: Amazon as CVE numbering authority, CVSS v3.1, 8.6 High, vector AV:L/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:H, noted as no privileges required and user interaction required; NIST as NVD primary, CVSS v3.1, 8.8 High, vector AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H, noted as low privileges required and no user interaction; Amazon again, CVSS v4.0, 6.3 Medium, vector AV:L/AC:L/AT:N/PR:N/UI:P/VC:N/VI:N/VA:N/SC:H/SI:H/SA:H, noted as impact recorded on the subsequent system only; CISA SSVC dated 6 August 2026 with no numeric score, listing exploitation none, automatable no, technical impact total. Three boxes below read 'Where the two v3.1 vectors diverge', 'Where they agree' and 'What the record does not carry'. A footer reads 'Sources: AWS security bulletin 2026-075-AWS; GHSA-66mr-jr63-2jgw; NVD record for CVE-2026-18953, last modified 23 October 2026; CISA Vulnrichment SSVC dated 6 August 2026. The two v3.1 vectors are separate assessments of the same CVE, not a correction of one by the other.' The OrcaRouter logo is composited in the bottom-right corner.

CISA's enrichment of the CVE, dated 6 August 2026, records an SSVC decision of Exploitation: none, Automatable: no, Technical Impact: total. NVD's record was last modified on 23 October 2026 and still carries both the 8.6 and the 8.8 side by side. Neither document treats the other as wrong.

What the vulnerable code did, and what 0.1.5 changed

Amazon's description of the mechanism is one sentence and it is careful: the tool "did not adequately restrict pathnames," which might allow "a context-dependent actor" to "write arbitrary files outside the intended working directory via the savePath parameter." The advisory does not define the actor, does not say what triggers the write, and does not describe what a successful exploit looks like. It says only that the result "could lead to local code execution."

The most detailed public account of the mechanism is not Amazon's. It is a small proof-of-concept repository, ronamosa/CVE-2026-18953, published on GitHub on 8 August 2026 under Apache-2.0 — two commits, no stars and no forks at the time of writing — which vendors verbatim copies of the vulnerable and patched file_validation.py and drives both through the same inputs.

Its reading of 0.1.4 is this: validate_write_path() resolved savePath with realpath and expanduser, rejected a short deny-list of locations (~/.aws, ~/.ssh, ~/.gnupg, ~/.docker, ~/.aws-transform-mcp, /etc/shadow, /etc/passwd), and stripped directory components from the supplied filename. It never confined the resolved path to any base or working directory. A blocklist of sensitive filenames — .bashrc, .zshrc, authorized_keys, id_rsa — was enforced on reads but not on writes.

The repository demonstrates three writes this permits: an absolute path that needs no traversal at all, a relative ../../ escape, and a dotfile name the read path would have refused. All three land inside a temporary directory the script creates, and its sample output shows dropped_by_absolute_path.sh, dropped_by_traversal.sh and a .bashrc under a decoy home directory; the real home directory is never touched. Version 0.1.5 adds the missing boundary: a base directory taken from $AWS_TRANSFORM_MCP_WRITE_DIR or the server's startup working directory, which every resolved write must fall beneath, plus the filename blocklist applied to the final resolved write path. The fixed validator raises "Write path must be within the working directory" against all three.

A generated abstract illustration on a pale grey-blue field with a faint blueprint grid: two nested rectangles drawn in thin dark-slate outline, one inside the other with a gap between them, sit slightly left of centre. A dotted cyan line runs from the centre of the inner rectangle outward, crossing the gap, and stops at the outer rectangle before resuming on the far side. Three small solid amber squares sit at staggered positions along that line, the outermost well beyond the larger rectangle. No text, numbers, people, brand marks or organisation logos appear. The OrcaRouter logo is composited in the bottom-right corner.

None of that detail appears in the advisory, and the repository does not claim it came from there. Treat the deny-list, the read-only filename check and the base-directory fix as a reconstruction from source code, not as a second official finding. What the repository does add beyond the advisory is an account of who can supply the path: because the server's job is to pull job and task content into an assistant's context, the party choosing savePath need not be the person at the keyboard. An assistant steered by untrusted content it fetched through the same tool can make the call. That is the repository's argument from the code and the tool's design, not a claim Amazon makes; Amazon's undefined "context-dependent actor" is consistent with it and stops there.

Seven weeks between the patch and the bulletin

The fix did not arrive with the announcement. The Python Package Index's release history — first-party metadata from the registry the package ships through — dates 0.1.4 to 20 May 2026 and 0.1.5 to 17 June 2026, seven weeks before bulletin 2026-075 was published on 5 August. There is no 0.1.0 file on the index at all; the earliest published artifact inside the affected range is 0.1.1, uploaded 9 May 2026. A developer installing from the index could therefore only have received a vulnerable build between 9 May and 17 June, and anyone tracking releases was already on patched code by the middle of June.

A self-built HTML card titled 'The patch came seven weeks early', subtitled 'Release dates from the Python Package Index, laid against the advisory', with a side note that Amazon publishes no report date and no discovery date. A vertical timeline of nine dated milestones reads: 23 April 2026, first package file 0.0.0 on the index; 9 May 2026, 0.1.1, earliest artifact inside the affected range; 20 May 2026, 0.1.4, last vulnerable release; 17 June 2026, tagged PATCHED, 0.1.5, first fixed release, seven weeks before the bulletin; 5 August 2026 at 12:30 PDT, tagged ADVISORY, bulletin 2026-075-AWS published with the CVE published at 19:33 UTC the same day; 6 August 2026, CISA SSVC recording exploitation none, automatable no, technical impact total; 8 August 2026, independent proof-of-concept repository published; 23 October 2026, NVD last modified, carrying NIST's 8.8 beside Amazon's 8.6; 27 October 2026, 0.2.4, latest release at the time of writing. A highlight box reads '49 days' from the first fixed release to the bulletin. A footer reads 'Sources: PyPI release metadata for awslabs.aws-transform-mcp-server; AWS security bulletin 2026-075-AWS; CVE record for CVE-2026-18953; CISA Vulnrichment; github.com/ronamosa/CVE-2026-18953; NVD.' The OrcaRouter logo is composited in the bottom-right corner.

Amazon does not say when it learned of the issue, when the report arrived, or why the release that closed it went out. The only person named in the record is Drew Raines, thanked in both the bulletin and the GitHub advisory "for collaborating on this issue through the coordinated issue disclosure process." GHSA-66mr-jr63-2jgw was published in Amazon's awslabs/mcp repository on 5 August 2026, the same day as the bulletin; the CVE record was reserved at 13:44 UTC and published at 19:33 UTC that day.

So the date of the fix is established and the reason for it is not. A patched version sitting on the registry seven weeks ahead of the advisory is consistent with a quiet fix followed by a coordinated disclosure — but that is an inference from two timestamps, and neither document states it.

What the record establishes, and what it does not

The archive grades this entry A — well documented, primary sources agree — and does not mark it disputed. It files it as a research record, a vulnerability finding rather than a deployment incident, with no recorded real-world harm. The grade is about the quality of the documentation, and on the evidence reviewed it holds: the bulletin, the GitHub advisory and the CVE record are three Amazon-published documents that agree on the product, the versions, the fix and the credit.

• Established. Amazon published bulletin 2026-075-AWS on 5 August 2026 covering CVE-2026-18953, a CWE-22 path traversal in get_resource's savePath handling in awslabs.aws-transform-mcp-server 0.1.0 through 0.1.4, fixed in 0.1.5, with no server-side or configuration-only workaround because the vulnerable path is in the default configuration.

• Established. The scores and their divergence: 8.6 High from Amazon as the CVE numbering authority, 8.8 High from NIST as the NVD primary score, 6.3 Medium on CVSS v4.0, and CISA's 6 August SSVC decision that no exploitation and no automatable path had been observed.

• Established. The release dates on the Python Package Index, and the credit to Drew Raines for coordinated disclosure.

• Inferred from source code, by a third party. The deny-list, the read-only filename blocklist, the absent base directory and the _ALLOWED_WRITE_BASE fix all come from the ronamosa proof-of-concept repository, whose vendored copies of the two validator versions anyone can diff.

• Inferred from timestamps and design. That 0.1.5 was a deliberate security release, and that an assistant steered by untrusted content could supply the hostile path. Amazon states neither.

• Not established. Any exploitation in the wild. CISA's "Exploitation: none" is dated 6 August, two days before the public proof-of-concept appeared, so it speaks to that moment and not to anything after it. No affected-user count, customer notification or telemetry has been published.

• Not established. Independent reporting. No mainstream outlet appears to have covered this CVE. The public record is Amazon's three documents, NIST's and CISA's enrichments of them, tracker pages that restate the record, and the one small proof-of-concept repository described above.

What changed, and what to check

Amazon's remedy is a version bump and nothing else: upgrade to 0.1.5 or later, and "ensure any forked or derivative code is patched to incorporate the new fixes." The second clause is the one that travels. The server is open source, and a fork that vendored the 0.1.4 validator inherits the flaw without inheriting the advisory; the bulletin asks operators of derivative code to carry the change into it, which is to say the upstream release does not reach a copy someone else maintains.

The proof-of-concept repository suggests something the advisory refuses to. Operators who cannot upgrade immediately, it says, should run the server with its working directory set to a dedicated empty directory and treat any file it can write to as compromised. Amazon's position is stricter: there is no server-side or configuration-only workaround at all. On the repository's own account that suggestion is also thin, since the vulnerable code never confined writes to the working directory in the first place. Where the two disagree, the vendor's upgrade-only instruction stands.

The useful thing about this record is not its score. It is the shape of it: a local MCP server, an artifact download with a caller-supplied destination, and no boundary between the two. The check that matters is not the bulletin date but the pinned version — 0.1.5 or later, and the same change carried into any fork that copied the validator.