# Insertion of Sensitive Information Into Sent Data (CWE-201) The product sends data to another actor, but this data contains sensitive information that should not be accessible to that actor. **Stack:** Python - Prevalence: 보통 3개 언어 지원 - Impact: 치명적 3개의 치명적 심각도 규칙 - Prevention: 문서화됨 3개의 수정 예시 **OWASP:** Broken Access Control (A01:2021-Broken Access Control) - #1 ## Description An attacker may be able to intercept or receive data that contains sensitive information, such as credentials, tokens, or internal system details, that were not intended for them. ## Prevention 1개의 Shoulder 탐지 규칙을 기반으로 한 Insertion of Sensitive Information 예방 전략. ### Python Validate webhook URLs against a domain allowlist and never send internal API keys ## Warning Signs - [CRITICAL] when internal credentials (API keys, secrets, tokens) are sent in HTTP requests to user-controlled e ## Consequences - 애플리케이션 데이터 읽기 - 권한 획득 ## Mitigations - 외부로 전송되는 모든 데이터에 민감한 정보가 포함되어 있는지 검토하세요 - 데이터 분류 체계를 구현하고 민감한 데이터가 적절히 보호되도록 하세요 - 민감한 정보를 전송할 때는 안전한 채널을 사용하세요 ## Detection - Total rules: 3 - Critical: 3 - Languages: go, javascript, typescript, python ## Rules by Language ### Python (1 rules) - **Credential Exfiltration via User-Controlled Endpoint** [CRITICAL]: Detects when internal credentials (API keys, secrets, tokens) are sent in HTTP requests to user-controlled endpoints. This allows attackers to exfiltrate server credentials by providing a malicious webhook URL that captures the sensitive headers or body data. Example vulnerable pattern: ```python # User controls 'endpoint' from request endpoint = request.form.get('webhook_url') # Server sends its internal API key to attacker-controlled URL requests.post(endpoint, headers={'X-API-Key': os.envir - Remediation: 1. Never send internal credentials to user-controlled endpoints 2. Validate webhook URLs against a strict allowlist of trusted domains 3. Use webhook secrets for authentication instead of sending API keys ```python from urllib.parse import urlparse ALLOWED_WEBHOOK_DOMAINS = {'api.slack.com', 'hooks.stripe.com'} def send_webhook(webhook_url, data): parsed = urlparse(webhook_url) if parsed.hostname not in ALLOWED_WEBHOOK_DOMAINS: raise ValueError('Untrusted webhook domain') # Use webhook-specific secret, not internal API key requests.post(webhook_url, json=data, headers={'X-Webhook-Secret': user_webhook_secret}) ``` Learn more: https://shoulder.dev/learn/python/cwe-201/credential-exfiltration