Weakness reference
CWE-941

Incorrectly Specified Destination in a Communication Channel

This weakness occurs when software sends data to the wrong destination—a misconfigured server, an unintended recipient, or an attacker-controlled…

01Summary

This weakness occurs when software sends data to the wrong destination—a misconfigured server, an unintended recipient, or an attacker-controlled endpoint—because the destination address is hardcoded incorrectly, derived from untrusted input, or resolved through a compromised lookup. The result is unintended disclosure of sensitive information or loss of control over where requests are routed.

02How It Happens

The vulnerability typically arises in one of three ways: a developer hardcodes the wrong hostname or IP address in a request; the destination is read from user input or configuration without validation; or the destination is resolved through a mechanism (DNS, service discovery, environment variables) that an attacker can influence. When the application constructs an outgoing connection—to a payment processor, logging service, API endpoint, or database—it may send the request to an attacker's server instead of the intended legitimate one. This is especially dangerous when the request contains authentication tokens, API keys, personal data, or other sensitive payloads.

03Real-World Impact

An attacker who can redirect traffic to their own server gains access to all data in transit: API credentials, session tokens, customer records, or financial information. In supply-chain scenarios, a compromised configuration or DNS poisoning could cause an application to send data to a malicious endpoint instead of a trusted partner. Even without active exploitation, misconfiguration can cause data to leak to the wrong internal service, violating data segregation and compliance requirements.

04Vulnerable & Fixed Patterns

Vulnerable pattern
import requests

# Destination read from untrusted environment variable
api_endpoint = os.getenv("API_ENDPOINT")

response = requests.post(
    api_endpoint,
    json={"user_id": user_id, "api_key": secret_key}
)

Why it's vulnerable:
The destination URL is taken directly from an environment variable without validation. If the variable is misconfigured or poisoned, the request—including the API key—is sent to an attacker's server.

Fixed pattern
import requests
from urllib.parse import urlparse

# Whitelist of allowed destinations
ALLOWED_ENDPOINTS = {
    "production": "https://api.example.com",
    "staging": "https://staging-api.example.com"
}

environment = os.getenv("ENVIRONMENT", "production")
api_endpoint = ALLOWED_ENDPOINTS.get(environment)

if not api_endpoint:
    raise ValueError(f"Unknown environment: {environment}")

response = requests.post(
    api_endpoint,
    json={"user_id": user_id, "api_key": secret_key}
)
Vulnerable pattern
<?php
// Destination from user input or config without validation
$webhook_url = $_POST['webhook_url'] ?? getenv('WEBHOOK_ENDPOINT');

$ch = curl_init($webhook_url);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
    'user_id' => $user_id,
    'api_token' => $api_token
]));
curl_exec($ch);
?>

Why it's vulnerable:
The webhook URL is accepted from user input or an unvalidated environment variable. An attacker can supply their own URL and receive the API token and user data.

Fixed pattern
<?php
// Whitelist of trusted destinations
$allowed_webhooks = [
    'production' => 'https://webhook.example.com/notify',
    'staging' => 'https://staging-webhook.example.com/notify'
];

$environment = getenv('ENVIRONMENT') ?: 'production';
$webhook_url = $allowed_webhooks[$environment] ?? null;

if (!$webhook_url) {
    throw new Exception("Invalid or missing webhook configuration");
}

$ch = curl_init($webhook_url);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
    'user_id' => $user_id,
    'api_token' => $api_token
]));
curl_exec($ch);
?>

05Prevention Checklist

Hardcode trusted destinations
or load them from a read-only configuration file, never from user input or untrusted environment variables.
Use allowlists
for all outgoing endpoints; reject any destination not explicitly approved.
Validate destination URLs
before use: check the scheme (https only), hostname against a whitelist, and reject localhost or private IP ranges unless explicitly intended.
Separate configuration by environment
(production, staging, development) and ensure each environment points to the correct, isolated service.
Monitor outgoing connections
in logs and alerts; flag requests to unexpected destinations.
Use mutual TLS (mTLS)
or certificate pinning for critical outbound connections to prevent man-in-the-middle redirection.

06Signs You May Already Be Affected

Review your application logs for outgoing requests to unexpected hostnames or IP addresses. Check configuration files and environment variables for hardcoded or user-supplied destination URLs that lack validation. If you find requests being sent to unfamiliar servers, or if configuration management tools show recent changes to endpoint URLs, investigate whether data may have been exposed in transit.