-
Notifications
You must be signed in to change notification settings - Fork 29
Closed
Labels
Description
Vulnerability Summary
Severity: MEDIUM (CVSS 5.3)
CWE: CWE-200 (Information Exposure), CWE-526 (Exposure of Sensitive Information Through Environmental Variables)
Location: src/agentready/learners/llm_enricher.py
Impact: API keys leaked through process listings and error messages
Description
The Anthropic API client may expose API keys through environment variables that are visible to:
- Process monitoring tools (
ps aux,top) - Error messages and stack traces
- Log files
- Child processes
Vulnerability Analysis
# llm_enricher.py - API client initialization
from anthropic import Anthropic
# If ANTHROPIC_API_KEY is set in environment, it's visible to all processes
client = Anthropic() # Reads from os.environ['ANTHROPIC_API_KEY']Information Leakage Vectors
- Process listings: Environment variables visible in
/proc/PID/environ - Error messages: API errors may include partial keys
- Log files: Logger may capture API responses with keys
- Child processes: Subprocess inherits environment
Example Attack
# Attacker on same system
ps aux | grep agentready
cat /proc/$(pgrep -f agentready)/environ | tr '\0' '\n' | grep ANTHROPICSecurity Impact
- API key theft: Attackers gain access to Claude API
- Cost fraud: Unauthorized API usage charged to victim
- Data exfiltration: Use API to process sensitive data
- Quota exhaustion: Denial of service via rate limit depletion
Remediation
Immediate Fix (P1)
- Clear API key from environment after reading:
# SECURITY: API Key Handling - Clear from environment after use
# Why: Environment variables are visible in process listings
# Prevents: Information Exposure (CWE-200)
# Alternative considered: Keyring storage rejected due to complexity
import os
from anthropic import Anthropic
class LLMEnricher:
def __init__(self, client: Anthropic | None = None, ...):
if client is None:
# Read and immediately clear from environment
api_key = os.environ.get('ANTHROPIC_API_KEY')
if api_key:
# Clear from environment to prevent leakage
del os.environ['ANTHROPIC_API_KEY']
client = Anthropic(api_key=api_key)
# Don't store raw key, only client
else:
raise ValueError("ANTHROPIC_API_KEY environment variable not set")
self.client = client- Sanitize error messages:
try:
response = self.client.messages.create(...)
except APIError as e:
# SECURITY: Strip potential API key from error message
error_msg = str(e)
if 'sk-ant-' in error_msg:
error_msg = re.sub(r'sk-ant-[a-zA-Z0-9-]+', 'sk-ant-***REDACTED***', error_msg)
logger.error(f"API error enriching {skill.skill_id}: {error_msg}")
return skill- Secure logging configuration:
# SECURITY: Configure logging to exclude sensitive data
import logging
class SensitiveDataFilter(logging.Filter):
"""Filter to redact API keys and secrets from logs."""
PATTERNS = [
(re.compile(r'sk-ant-[a-zA-Z0-9-]+'), 'sk-ant-***'),
(re.compile(r'ANTHROPIC_API_KEY[=:]\\s*\\S+'), 'ANTHROPIC_API_KEY=***'),
]
def filter(self, record):
record.msg = self._redact(str(record.msg))
if record.args:
record.args = tuple(self._redact(str(arg)) for arg in record.args)
return True
def _redact(self, text: str) -> str:
for pattern, replacement in self.PATTERNS:
text = pattern.sub(replacement, text)
return text
# Apply filter to all loggers
for handler in logging.root.handlers:
handler.addFilter(SensitiveDataFilter())Additional Protections
-
Use keyring for secure storage:
import keyring # Store API key securely keyring.set_password("agentready", "anthropic_api_key", api_key) # Retrieve when needed api_key = keyring.get_password("agentready", "anthropic_api_key")
-
Document secure usage:
# Security Best Practices **API Key Management**: - Never commit API keys to git - Use `.env` files (excluded from git) - Clear `ANTHROPIC_API_KEY` after use - Rotate keys regularly - Use separate keys for development/production
-
Add security checks:
# Warn if API key is set globally if 'ANTHROPIC_API_KEY' in os.environ: warnings.warn( "ANTHROPIC_API_KEY is set in environment. " "Consider using .env file instead for security.", SecurityWarning )
References
- OWASP Secrets Management Cheat Sheet
- CWE-200: Information Exposure
- CWE-526: Exposure Through Environmental Variables
Related Issues
- Subprocess calls may leak environment to child processes
- Error messages may contain sensitive repository paths
Reactions are currently unavailable