Channel Accessible by Non-Endpoint
Description
Channel Accessible by Non-Endpoint is a vulnerability that occurs when a product does not adequately verify the identities of the entities at both ends of a communications channel, or does not adequately ensure the integrity of the channel. This enables attackers to position themselves between legitimate endpoints and intercept or modify communications. The fundamental problem is that a communication channel is accessible to parties other than the intended endpoints without proper verification or protection. Without sufficient identity verification at both endpoints, attackers can eavesdrop on communications, impersonate legitimate parties, or modify data in transit - the classic man-in-the-middle attack scenario.
Risk
Failure to secure communication channel endpoints represents a critical security weakness that enables devastating man-in-the-middle attacks. When endpoints are not properly verified, attackers can intercept sensitive data including credentials, personal information, financial data, and proprietary communications. The risk extends beyond passive eavesdropping to active manipulation where attackers modify data in transit, potentially altering transaction details, injecting malicious content, or corrupting data integrity. High-profile incidents like Apple's "goto fail" bug (CVE-2014-1266) demonstrate how endpoint verification failures can affect millions of users. The impact is amplified in environments handling sensitive data such as financial services, healthcare, and government communications.
Solution
Always verify the identities of both endpoints in any communications channel using strong cryptographic mechanisms. Implement mutual TLS (mTLS) where both client and server present certificates for validation. Use X.509 certificates that bind identities to cryptographic keys, verified through a trusted certificate authority. Apply the principle of complete mediation - never assume a channel is secure without verification. Implement certificate pinning in client applications to prevent certificate substitution attacks. Use authenticated encryption modes that provide both confidentiality and integrity protection. Validate certificates fully including chain of trust, expiration, revocation status, and hostname matching. Consider implementing additional channel binding mechanisms to tie the authentication to the specific channel.
Common Consequences
| Impact | Details |
|---|---|
| Confidentiality | Scope: Confidentiality Attackers positioned in the communication channel can read all transmitted data, exposing credentials, session tokens, personal information, and sensitive business data. |
| Integrity, Access Control | Scope: Integrity, Access Control Attackers can modify communications in transit, impersonate either endpoint, inject malicious content, and gain unauthorized access by assuming the identity of a legitimate party. |
Example Code
Vulnerable Code (Java)
The following examples demonstrate unprotected communication channels:
// Vulnerable: Plain socket communication without encryption or authentication
import java.net.*;
import java.io.*;
public class VulnerableClient {
public void sendSensitiveData(String data) throws Exception {
// Vulnerable: No encryption, no endpoint verification
Socket socket = new Socket("server.example.com", 8080);
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
// Vulnerable: Data sent in cleartext
out.println("username:admin");
out.println("password:secretpassword");
out.println(data);
// Attacker can read everything on the network
String response = in.readLine();
socket.close();
}
}
# Vulnerable: HTTP without TLS or endpoint verification
import http.client
import json
def vulnerable_api_call(endpoint, data):
# Vulnerable: Plain HTTP, no encryption
conn = http.client.HTTPConnection("api.example.com", 80)
# Vulnerable: Credentials sent without encryption
headers = {
"Authorization": "Bearer secret_token_12345",
"Content-Type": "application/json"
}
# Attacker can intercept all of this
conn.request("POST", endpoint, json.dumps(data), headers)
response = conn.getresponse()
return response.read()
# Vulnerable: SSL without proper verification
import ssl
import socket
def vulnerable_ssl_connect(hostname, port):
context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
# Vulnerable: Disabling certificate verification
context.check_hostname = False
context.verify_mode = ssl.CERT_NONE
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ssl_sock = context.wrap_socket(sock)
ssl_sock.connect((hostname, port))
# Attacker with any certificate can intercept
return ssl_sock
// Vulnerable: C code without SSL verification callback
#include <openssl/ssl.h>
#include <openssl/err.h>
int vulnerable_connect(const char *host, int port) {
SSL_CTX *ctx = SSL_CTX_new(TLS_client_method());
// Vulnerable: No certificate verification configured
// SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);
SSL *ssl = SSL_new(ctx);
// Connect without verifying server identity
int sock = create_socket(host, port);
SSL_set_fd(ssl, sock);
if (SSL_connect(ssl) <= 0) {
ERR_print_errors_fp(stderr);
return -1;
}
// Vulnerable: Not checking certificate at all
// Any endpoint can pretend to be the server
return sock;
}
Fixed Code (Java)
// Fixed: Mutual TLS with proper endpoint verification
import javax.net.ssl.*;
import java.security.*;
import java.io.*;
public class SecureClient {
public void sendSensitiveData(String data) throws Exception {
// Load client certificate for mutual authentication
KeyStore clientKeyStore = KeyStore.getInstance("PKCS12");
clientKeyStore.load(
new FileInputStream("/path/to/client.p12"),
"keystorepassword".toCharArray()
);
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(clientKeyStore, "keypassword".toCharArray());
// Load trusted server certificates
KeyStore trustStore = KeyStore.getInstance("JKS");
trustStore.load(
new FileInputStream("/path/to/truststore.jks"),
"truststorepassword".toCharArray()
);
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
tmf.init(trustStore);
// Fixed: Configure SSL context with both key and trust managers
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
SSLSocketFactory factory = sslContext.getSocketFactory();
SSLSocket socket = (SSLSocket) factory.createSocket("server.example.com", 8443);
// Fixed: Enable hostname verification
SSLParameters params = socket.getSSLParameters();
params.setEndpointIdentificationAlgorithm("HTTPS");
socket.setSSLParameters(params);
// Fixed: Verify handshake completes (both endpoints verified)
socket.startHandshake();
// Now communication is encrypted and both endpoints verified
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
out.println(data);
String response = in.readLine();
socket.close();
}
}
# Fixed: Proper TLS with endpoint verification
import ssl
import socket
import certifi
def secure_connect(hostname, port):
# Fixed: Create context with proper verification
context = ssl.create_default_context(cafile=certifi.where())
# Fixed: Enable hostname verification
context.check_hostname = True
context.verify_mode = ssl.CERT_REQUIRED
# Fixed: Require minimum TLS version
context.minimum_version = ssl.TLSVersion.TLSv1_2
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Fixed: Provide hostname for SNI and verification
ssl_sock = context.wrap_socket(sock, server_hostname=hostname)
ssl_sock.connect((hostname, port))
# Fixed: Verify certificate after connection
cert = ssl_sock.getpeercert()
if not cert:
raise ssl.SSLError("No certificate received")
return ssl_sock
# Fixed: Mutual TLS client
def secure_mtls_connect(hostname, port, client_cert, client_key, ca_bundle):
context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
# Load client certificate for mutual authentication
context.load_cert_chain(certfile=client_cert, keyfile=client_key)
# Load CA certificates for server verification
context.load_verify_locations(cafile=ca_bundle)
context.check_hostname = True
context.verify_mode = ssl.CERT_REQUIRED
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ssl_sock = context.wrap_socket(sock, server_hostname=hostname)
ssl_sock.connect((hostname, port))
return ssl_sock
The fix implements mutual TLS authentication ensuring both endpoints verify each other's identity using certificates.
Exploited in the Wild
Apple SSL "goto fail" Bug (iOS/macOS, 2014)
CVE-2014-1266 documented a critical vulnerability in Apple's SSL/TLS implementation where a coding error (duplicate "goto fail" statement) caused certificate validation to be bypassed, allowing man-in-the-middle attacks on all iOS and macOS communications.
Banking App MitM Attacks (Mobile Applications, 2016)
Security researchers discovered multiple banking applications vulnerable to man-in-the-middle attacks due to improper certificate validation, allowing attackers to intercept credentials and financial transactions.
Tools to Test/Exploit
-
mitmproxy — Interactive HTTPS proxy for testing man-in-the-middle attack scenarios.
-
Wireshark — Network protocol analyzer for examining unencrypted or improperly secured communications.
-
sslstrip — Tool demonstrating SSL stripping attacks against improperly configured endpoints.
CVE Examples
-
CVE-2014-1266 — Apple SSL "goto fail" bug bypassing certificate validation.
-
CVE-2012-5810 — Mobile banking app accepts arbitrary certificates.
-
CVE-2014-0224 — OpenSSL CCS injection allowing MitM attacks.
References
-
MITRE Corporation. "CWE-300: Channel Accessible by Non-Endpoint." Common Weakness Enumeration. https://cwe.mitre.org/data/definitions/300.html
-
OWASP Foundation. "Transport Layer Protection Cheat Sheet." https://cheatsheetseries.owasp.org/cheatsheets/Transport_Layer_Protection_Cheat_Sheet.html
-
RFC 5246. "The Transport Layer Security (TLS) Protocol Version 1.2." https://tools.ietf.org/html/rfc5246