Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2026-18953 — PoC for CVE-2026-18953 — arbitrary file write (CWE-22) in awslabs.aws-transform-mcp-server's get_resource tool via the savePath parameter | Kitploit
Tools/GitHubGitHub/ronamosa/cve-2026-18953
Vulnerability AnalysisExploitationPenetration TestingAPI Security
GitHubronamosa/cve-2026-18953

CVE-2026-18953

PoC for CVE-2026-18953 — arbitrary file write (CWE-22) in awslabs.aws-transform-mcp-server's get_resource tool via the savePath parameter

View Repository
31 month agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

CVE-2026-18953 — PoC

Arbitrary file write in awslabs.aws-transform-mcp-server (AWS Transform MCP server) via the savePath parameter of the get_resource tool.

CVECVE-2026-18953
CWECWE-22 — Improper Limitation of a Pathname to a Restricted Directory
Affectedawslabs.aws-transform-mcp-server 0.1.0 – 0.1.4
Fixed in0.1.5
CVSS v3.18.6 HIGH — AV:L/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:H
CVSS v4.06.3 MEDIUM — AV:L/AC:L/AT:N/PR:N/UI:P/VC:N/VI:N/VA:N/SC:H/SI:H/SA:H
AdvisoryGHSA-66mr-jr63-2jgw
BulletinAWS Security Bulletin 2026-075
ReporterDrew Raines (coordinated disclosure)
Published2026-08-05

Summary

get_resource(resource="artifact" | "asset", ...) downloads a file from a pre-signed S3 URL and, when the caller passes savePath / fileName, saves it to local disk through:

root@kitploit:~
tools/get_resource.py  ->  tool_utils.download_s3_content()
                        ->  file_validation.validate_write_path()

In <= 0.1.4, validate_write_path() only:

  1. Resolves save_path with os.path.realpath(os.path.expanduser(...)).
  2. Rejects a short deny-list of directories (~/.aws, ~/.ssh, ~/.gnupg, ~/.docker, ~/.aws-transform-mcp, /etc/shadow, /etc/passwd).
  3. Strips directory components from file_name via os.path.basename().

It never confines the resolved directory to any base/working directory, and BLOCKED_FILENAMES (.bashrc, .zshrc, authorized_keys, id_rsa, …) is only enforced on reads, not writes. So any MCP client of this server — including an agent that has been indirectly prompt-injected via untrusted job/task/message content it fetches through this same tool — can set savePath to an absolute path, a ../.. traversal, or a sensitive dotfile name, and the server writes attacker-influenced bytes there. That's a file-write primitive outside the directory the operator believes downloads are confined to; the advisory notes it "could lead to local code execution" (e.g. clobbering a shell startup file).

0.1.5 fixes this by adding an explicit allow-listed base directory (_ALLOWED_WRITE_BASE, taken from $AWS_TRANSFORM_MCP_WRITE_DIR or the server's CWD at startup) that every resolved write path must fall under, and by also enforcing BLOCKED_FILENAMES on the final resolved write path.

Full root-cause diff: vendor/0.1.4-vulnerable/file_validation.py vs. vendor/0.1.5-fixed/file_validation.py (both pulled verbatim from PyPI / GitHub, Apache-2.0).

What a real attack looks like

An MCP client (Q Developer, Kiro, Claude, etc. wired up to this server) issues a tool call such as:

root@kitploit:~
{
  "name": "get_resource",
  "arguments": {
    "resource": "artifact",
    "workspaceId": "ws-...",
    "jobId": "job-...",
    "artifactId": "art-...",
    "savePath": "/Users/victim/Library/LaunchAgents",
    "fileName": "com.evil.persist.plist"
  }
}

or, from a relative sandbox dir:

root@kitploit:~
{ "savePath": "../../../../../../Users/victim/.bashrc", "fileName": "x" }

Because the tool describes resource="task" responses as things the agent should read and act on, and resource="messages" content originates from chat/job data, a workspace collaborator (or a compromised upstream job/message source) doesn't need to convince a human to type this — steering an already-connected agent into calling get_resource with a hostile savePath is enough. No real AWS credentials are required to demonstrate the flaw itself, since the bug is entirely in local path handling, before/after the S3 fetch.

Running the PoC

root@kitploit:~
python3 poc.py

No third-party dependencies, no AWS account, no network access to AWS. The script:

  1. Vendors the real, unmodified file_validation.py from both 0.1.4 and 0.1.5+ (see vendor/).
  2. Starts a throwaway local HTTP server standing in for the pre-signed S3 URL.
  3. Re-implements download_s3_content() with the exact control flow from upstream tool_utils.py (httpx swapped for stdlib urllib only —zero dependencies, same logic), and drives it exactly as get_resource would.
  4. Fires three malicious savePath/fileName pairs — absolute-path escape, relative ../.. traversal, and a blocked-on-read-only dotfile name — against the vulnerable validator, then the fixed one.

Everything happens inside a disposable mkdtemp() scratch directory; your real $HOME is never touched. Sample output:

root@kitploit:~
=== Target: file_validation.py from 0.1.4-vulnerable ===
  -> Absolute path escape (no traversal needed at all)
     RESULT: VULNERABLE: wrote OUTSIDE sandbox -> .../outside_sandbox/dropped_by_absolute_path.sh
  -> Relative "../../.." traversal out of the sandbox dir
     RESULT: VULNERABLE: wrote OUTSIDE sandbox -> .../outside_sandbox/dropped_by_traversal.sh
  -> Sensitive dotfile name, written inside a decoy $HOME
     RESULT: VULNERABLE: wrote OUTSIDE sandbox -> .../outside_sandbox/decoy_home/.bashrc

=== Target: file_validation.py from 0.1.5-fixed ===
  -> Absolute path escape (no traversal needed at all)
     RESULT: BLOCKED (raised ValueError): Write path must be within the working directory (...)
  -> Relative "../../.." traversal out of the sandbox dir
     RESULT: BLOCKED (raised ValueError): ...
  -> Sensitive dotfile name, written inside a decoy $HOME
     RESULT: BLOCKED (raised ValueError): ...

Remediation

Upgrade to awslabs.aws-transform-mcp-server >= 0.1.5. There is no server-side workaround for older versions; the advisory recommends upgrading. Operators who cannot upgrade immediately should run the server with its CWD set to a dedicated, empty directory and treat any file it can write to as compromised.

Repo layout

root@kitploit:~
README.md                              — this file
poc.py                                 — self-contained PoC driver
vendor/_loguru_shim.py                 — tiny stand-in for the `loguru` dep (test scaffolding only)
vendor/0.1.4-vulnerable/file_validation.py  — real vulnerable source, from PyPI sdist
vendor/0.1.5-fixed/file_validation.py       — real patched source, from github.com/awslabs/mcp@main
Download Tool