Improper Validation of Certificate with Host Mismatch
This weakness occurs when software connects to a remote host over HTTPS or another certificate-based protocol but fails to verify that the certificate's…
This weakness occurs when software connects to a remote host over HTTPS or another certificate-based protocol but fails to verify that the certificate's hostname matches the actual host being connected to. An attacker positioned to intercept network traffic (or control DNS) can present a valid certificate for a different domain, and the application will accept it, enabling man-in-the-middle attacks. This is a critical flaw in any application that handles sensitive data over encrypted channels.
02How It Happens
When establishing a secure connection, the client receives a certificate from the server and must verify two things: that the certificate is signed by a trusted Certificate Authority, and that the certificate's Common Name (CN) or Subject Alternative Name (SAN) field matches the hostname being connected to. Many developers verify the first check (certificate validity) but skip or disable the second (hostname matching). This often happens when developers disable certificate verification entirely during testing and forget to re-enable it, or when they use libraries with insecure defaults. The result is that any valid certificate—even one issued for a completely different domain—will be accepted.
03Real-World Impact
An attacker on the same network, controlling a router, or able to manipulate DNS can intercept HTTPS connections and present their own valid certificate. The application will accept it and transmit sensitive data (credentials, API keys, personal information) over the attacker's connection, believing it is secure. This enables credential theft, session hijacking, API key compromise, and data exfiltration. The vulnerability is particularly dangerous because the connection *appears* encrypted to the user, but the attacker has full visibility into the traffic.
Why it's vulnerable: The verify=False parameter disables all certificate validation, including hostname matching. An attacker can present any valid certificate and the request will succeed.
Fixed pattern
import requests
# Use default behavior: verify certificate and hostname
response = requests.get(
'https://api.example.com/data'
# verify=True is the default; omit it or set explicitly
)
# Or explicitly specify a CA bundle if needed
response = requests.get(
'https://api.example.com/data',
verify='/path/to/ca-bundle.crt'
)
Why it's vulnerable: Setting CURLOPT_SSL_VERIFYPEER to false disables certificate validation, and CURLOPT_SSL_VERIFYHOST to false disables hostname matching. Any certificate will be accepted.
Never disable certificate verification in production code. If you disable it during development, use a separate configuration file or environment variable and ensure it defaults to true in production.
Verify hostname matching is enabled. In Python, use requests with verify=True (default). In PHP/cURL, set CURLOPT_SSL_VERIFYHOST to 2. In Node.js, do not set rejectUnauthorized: false.
Use up-to-date CA certificate bundles. Ensure your application uses a current set of trusted root certificates; outdated bundles may not recognize legitimate certificates.
Test certificate validation in your test suite. Include tests that verify your application rejects connections to mismatched hostnames or untrusted CAs.
Audit third-party libraries and dependencies. Check that HTTP client libraries you depend on have certificate verification enabled by default.
Use certificate pinning for high-security scenarios. If connecting to a specific API, consider pinning the expected certificate or public key to prevent acceptance of any other valid certificate.
06Signs You May Already Be Affected
Review your codebase for calls to HTTP client libraries with verification disabled: search for verify=False, CURLOPT_SSL_VERIFYPEER set to false, or rejectUnauthorized: false. Check your application logs for any warnings or errors related to certificate validation that may have been silenced. If your application connects to external APIs or services over HTTPS, verify that your configuration files do not contain settings that disable certificate checks.