Weakness reference
CWE-940

Improper Verification of Source of a Communication Channel

This weakness occurs when software accepts incoming requests or communications without properly verifying who or what initiated them. An attacker can…

01Summary

This weakness occurs when software accepts incoming requests or communications without properly verifying who or what initiated them. An attacker can impersonate a legitimate user, system, or service by spoofing the source of a communication, leading to unauthorized actions, data theft, or system compromise. Proper source verification is essential to ensure that only trusted actors can trigger sensitive operations.

02How It Happens

Communication channels—whether HTTP requests, API calls, inter-process messages, or network packets—can be forged or intercepted if the receiving software doesn't authenticate the sender. Common scenarios include:

- Missing authentication headers:
A system accepts requests without checking cryptographic signatures, tokens, or credentials. - Trusting client-supplied identifiers:
Code assumes that a user ID, IP address, or hostname provided by the client is genuine without independent verification. - Accepting unauthenticated callbacks:
Webhooks or callback URLs are invoked without confirming the caller's identity. - Relying on network position alone:
Assuming that because a request came from an internal IP or local socket, it must be trustworthy.

The root cause is a gap between the assumption ("this request must be from a trusted source") and the reality ("I never checked").

03Real-World Impact

Improper source verification can lead to account takeover, privilege escalation, unauthorized data access, or malicious actions performed on behalf of legitimate users. For example, an attacker could trigger administrative functions by forging a request that appears to come from an authorized admin, or manipulate inter-service communication in a microservices architecture to exfiltrate data or corrupt state. In supply-chain scenarios, an attacker could impersonate a trusted partner's webhook to inject malicious data into a system.

04Vulnerable & Fixed Patterns

Vulnerable pattern
from flask import Flask, request

app = Flask(__name__)

@app.route('/admin/delete-user', methods=['POST'])
def delete_user():
    user_id = request.form.get('user_id')
    # No verification of who initiated this request
    database.delete_user(user_id)
    return "User deleted"

Why it's vulnerable:
The endpoint accepts a deletion request without verifying the caller's identity or authorization. Any attacker who can reach this endpoint can delete any user.

Fixed pattern
from flask import Flask, request
from functools import wraps
import jwt

app = Flask(__name__)
SECRET_KEY = "your-secret-key"

def require_auth(f):
    @wraps(f)
    def decorated(*args, **kwargs):
        token = request.headers.get('Authorization', '').replace('Bearer ', '')
        try:
            payload = jwt.decode(token, SECRET_KEY, algorithms=['HS256'])
            if payload.get('role') != 'admin':
                return "Forbidden", 403
        except jwt.InvalidTokenError:
            return "Unauthorized", 401
        return f(*args, **kwargs)
    return decorated

@app.route('/admin/delete-user', methods=['POST'])
@require_auth
def delete_user():
    user_id = request.form.get('user_id')
    database.delete_user(user_id)
    return "User deleted"
Vulnerable pattern
<?php
// Webhook endpoint
if ($_POST['action'] === 'sync-data') {
    $data = json_decode($_POST['payload'], true);
    // No verification of the caller's identity
    update_database($data);
    echo "Synced";
}
?>

Why it's vulnerable:
The webhook accepts and processes data without verifying that the request came from the expected source. An attacker can send a forged POST request to trigger the sync.

Fixed pattern
<?php
// Webhook endpoint with signature verification
$expected_secret = 'shared-webhook-secret';
$signature = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? '';
$payload = file_get_contents('php://input');

$computed_signature = hash_hmac('sha256', $payload, $expected_secret);
if (!hash_equals($computed_signature, $signature)) {
    http_response_code(401);
    echo "Unauthorized";
    exit;
}

$data = json_decode($payload, true);
update_database($data);
echo "Synced";
?>

05Prevention Checklist

Require authentication on all sensitive endpoints:
Use tokens (JWT, OAuth), session cookies, or API keys; never skip authentication for "internal" or "trusted" requests.
Verify cryptographic signatures on callbacks and webhooks:
Use HMAC or asymmetric signatures to confirm the caller's identity before processing the payload.
Implement authorization checks:
Verify not only *who* the caller is, but also *what they are allowed to do* (role-based or attribute-based access control).
Use mutual TLS (mTLS) for service-to-service communication:
Authenticate both client and server in inter-service calls to prevent impersonation.
Never trust client-supplied identifiers alone:
Do not assume a user ID, IP address, or hostname provided by the client is genuine; cross-check against server-side session or token state.
Log and monitor authentication failures:
Track failed authentication attempts to detect impersonation attempts or reconnaissance.

06Signs You May Already Be Affected

- Unexpected administrative actions (user deletions, permission changes, data exports) with no corresponding audit trail or logged-in admin session. - Webhook or callback processing that has resulted in data corruption or unauthorized state changes, especially if the timing correlates with external events. - Unusual inter-service communication patterns in logs, or services performing actions they should not have permission to perform.

07Related Recent Vulnerabilities