# 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:** Go - 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 の予防策。 ### Go Validate webhook URLs against an allowlist and never send internal credentials to user-controlled endpoints ## 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 ### Go (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: ```go // User controls 'endpoint' from request endpoint := r.FormValue("webhook_url") // Server sends its internal API key to attacker-controlled URL req, _ := http.NewRequest("POST", endpoint, nil) req.Header. - 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 ```go allowedDomains := map[string]bool{ "api.slack.com": true, "hooks.stripe.com": true, } parsed, err := url.Parse(webhookURL) if err != nil || !allowedDomains[parsed.Host] { return errors.New("untrusted webhook domain") } // Use webhook-specific secret, not internal API key req, _ := http.NewRequest("POST", webhookURL, body) req.Header.Set("X-Webhook-Secret", userWebhookSecret) client.Do(req) ``` Learn more: https://shoulder.dev/learn/go/cwe-201/credential-exfiltration