Skip to content

Conversation

@padak
Copy link

@padak padak commented Nov 11, 2025

Summary

Fixes two HIGH priority security vulnerabilities that could lead to supply chain attacks and data exfiltration.

1. Presigned URL Leak - Supply Chain Attack Vector (HIGH)

Problem:
The upload script logged sensitive presigned URLs to CI logs through multiple mechanisms:

  • curl -v flag printed full HTTP headers including the URL
  • 2>&1 captured verbose stderr output
  • set -x shell tracing echoed the entire curl command with $SIGNED_URL

The presigned URL contains HMAC-SHA256 signatures that grant upload rights for ~1 hour. Anyone with CI log access could:

  • Replay the URL before expiration
  • Overwrite Python wheels in the artifact storage
  • Execute supply chain attacks by injecting malicious code

Fix:

  • Removed -x flag from set -exuo pipefailset -euo pipefail
  • Replaced curl -v with curl -s -w '%{http_code}' -o /dev/null
  • Changed success detection from parsing verbose output to checking HTTP status code
  • URL never appears in logs (happy path or error path)

2. Exception Data Exfiltration to API (HIGH)

Problem:
Tool runner caught all exceptions and automatically sent repr(exc) to Anthropic API in tool_result content. Exception messages routinely contain:

  • Database credentials: postgres://user:password@host:5432/db
  • API keys: sk-proj-..., sk_live_...
  • File paths: /home/user/.ssh/id_rsa, /var/www/secret-api/
  • Environment variables: AWS_SECRET_ACCESS_KEY=...
  • Connection strings and other secrets

This behavior silently exfiltrated sensitive host information to the LLM with:

  • No sanitization
  • No user control
  • No visibility (users unaware of the leak)
  • Permanent storage (data in Anthropic API logs indefinitely)

Fix:

  • Replaced repr(exc) with generic error message: "Error: Tool '{tool_name}' execution failed. Check logs for details."
  • Full exception stack traces still logged locally via log.exception() for debugging
  • Prevents all sensitive data exfiltration while maintaining debuggability

Implementation Details

Curl Fix

Before:

set -exuo pipefail
UPLOAD_RESPONSE=$(curl -v -X PUT ... "$SIGNED_URL" 2>&1)
if echo "$UPLOAD_RESPONSE" | grep -q "HTTP/[0-9.]* 200"; then

After:

set -euo pipefail
HTTP_CODE=$(curl -w '%{http_code}' -o /dev/null -s -X PUT ... "$SIGNED_URL")
if [[ "$HTTP_CODE" == "200" ]]; then

Exception Fix

Before:

except Exception as exc:
    log.exception(f"Error occurred while calling tool: {tool.name}", exc_info=exc)
    results.append({
        "content": repr(exc),  # ← Leaks credentials!
        "is_error": True,
    })

After:

except Exception as exc:
    log.exception(f"Error occurred while calling tool: {tool.name}", exc_info=exc)
    results.append({
        "content": f"Error: Tool '{tool_use.name}' execution failed. Check logs for details.",
        "is_error": True,
    })

Security Impact

Presigned URL Leak

  • Before: Supply chain attack possible via CI log access
  • After: URL never logged, attack vector eliminated
  • Risk Eliminated: Unauthorized artifact uploads

Exception Exfiltration

  • Before: Automatic credential leakage to API
  • After: Generic errors only, no sensitive data sent
  • Risk Eliminated: Information disclosure, credential theft

Changes

  • scripts/utils/upload-artifact.sh:2
    • Removed -x from set -exuo pipefail
  • scripts/utils/upload-artifact.sh:17-21
    • Replaced curl -v ... 2>&1 with curl -s -w '%{http_code}' -o /dev/null
    • Changed HTTP success detection to use status code
  • src/anthropic/lib/tools/_beta_runner.py:195 (sync)
    • Changed repr(exc) to generic error message
  • src/anthropic/lib/tools/_beta_runner.py:362 (async)
    • Changed repr(exc) to generic error message

Testing

Both fixes validated with comprehensive security review to ensure:

  • ✅ Presigned URLs no longer appear in any logs
  • ✅ HTTP status detection remains reliable
  • ✅ Exception details no longer sent to API
  • ✅ Local logging preserved for debugging
  • ✅ No new vulnerabilities introduced

…tion

Fixes two HIGH priority security vulnerabilities:

1. Presigned URL Leak in Upload Script (HIGH):
   - upload-artifact.sh used "curl -v" with "2>&1", logging the full
     presigned URL (including HMAC-SHA256 signature) to CI logs
   - "set -x" flag additionally echoed the entire curl command with URL
   - Anyone with log access could replay URL within expiration window
     to overwrite Python wheels (supply chain attack)
   - Fix: Remove -x flag, replace curl -v with -s -w '%{http_code}'
     to get HTTP status without verbose logging

2. Exception Data Exfiltration to API (HIGH):
   - Tool runner caught all exceptions and sent repr(exc) directly to
     Anthropic API in tool_result content
   - Exception messages often contain credentials, file paths, env vars,
     connection strings - silently exfiltrating sensitive host info
   - No sanitization or user control over what gets sent
   - Fix: Replace repr(exc) with generic error message that contains no
     host context. Full exception still logged locally via log.exception()

Changed:
- scripts/utils/upload-artifact.sh:2
  Changed "set -exuo pipefail" to "set -euo pipefail" (removed -x)
- scripts/utils/upload-artifact.sh:17-21
  Replaced curl -v with curl -w '%{http_code}' -s -o /dev/null
  Changed success detection from parsing verbose output to checking HTTP code
- src/anthropic/lib/tools/_beta_runner.py:195
  Changed "content": repr(exc) to generic error message (sync)
- src/anthropic/lib/tools/_beta_runner.py:362
  Changed "content": repr(exc) to generic error message (async)
@padak padak requested a review from a team as a code owner November 11, 2025 06:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant