This vulnerability makes it possible that an encrypted communication is intercepted.
Why is this an issue?
Transport Layer Security (TLS) provides secure communication between systems over the internet by encrypting the data sent between them. The role
of certificate validation in this process is to ensure that a system is indeed the one it claims to be, adding an extra layer of trust and
security.
When certificate validation is disabled, the client skips this critical check. This creates an opportunity for attackers to pose as a trusted
entity and intercept, manipulate, or steal the data being transmitted.
What is the potential impact?
Establishing trust in a secure way is a non-trivial task. When you disable certificate validation, you are removing a key mechanism designed to
build this trust in internet communication, opening your system up to a number of potential threats.
Identity spoofing
If a system does not validate certificates, it cannot confirm the identity of the other party involved in the communication. An attacker can
exploit this by creating a fake server and masquerading it as a legitimate one. For example, they might set up a server that looks like your bank’s
server, tricking your system into thinking it is communicating with the bank. This scenario, called identity spoofing, allows the attacker to collect
any data your system sends to them, potentially leading to significant data breaches.
Loss of data integrity
When TLS certificate validation is disabled, the integrity of the data you send and receive cannot be guaranteed. An attacker could modify the data
in transit, and you would have no way of knowing. This could range from subtle manipulations of the data you receive to the injection of malicious
code or malware into your system. The consequences of such breaches of data integrity can be severe, depending on the nature of the data and the
system.
How to fix it in Botan
Code examples
The following code contains examples of disabled certificate validation.
The certificate validation gets disabled by overriding tls_verify_cert_chain
with an empty implementation. It is highly recommended to
use the original implementation.
Noncompliant code example
#include <botan/tls_client.h>
#include <botan/tls_callbacks.h>
#include <botan/tls_session_manager.h>
#include <botan/tls_policy.h>
#include <botan/auto_rng.h>
#include <botan/certstor.h>
#include <botan/certstor_system.h>
class Callbacks : public Botan::TLS::Callbacks
{
virtual void tls_verify_cert_chain(
const std::vector<Botan::X509_Certificate> &cert_chain,
const std::vector<std::shared_ptr<const Botan::OCSP::Response>> &ocsp_responses,
const std::vector<Botan::Certificate_Store *> &trusted_roots,
Botan::Usage_Type usage,
const std::string &hostname,
const Botan::TLS::Policy &policy)
override { }
};
class Client_Credentials : public Botan::Credentials_Manager { };
void connect() {
Callbacks callbacks;
Botan::AutoSeeded_RNG rng;
Botan::TLS::Session_Manager_In_Memory session_mgr(rng);
Client_Credentials creds;
Botan::TLS::Strict_Policy policy;
Botan::TLS::Client client(callbacks, session_mgr, creds, policy, rng,
Botan::TLS::Server_Information("example.com", 443),
Botan::TLS::Protocol_Version::TLS_V12); // Noncompliant
}
Compliant solution
#include <botan/tls_client.h>
#include <botan/tls_callbacks.h>
#include <botan/tls_session_manager.h>
#include <botan/tls_policy.h>
#include <botan/auto_rng.h>
#include <botan/certstor.h>
#include <botan/certstor_system.h>
class Callbacks : public Botan::TLS::Callbacks { };
class Client_Credentials : public Botan::Credentials_Manager { };
void connect() {
Callbacks callbacks;
Botan::AutoSeeded_RNG rng;
Botan::TLS::Session_Manager_In_Memory session_mgr(rng);
Client_Credentials creds;
Botan::TLS::Strict_Policy policy;
Botan::TLS::Client client(callbacks, session_mgr, creds, policy, rng,
Botan::TLS::Server_Information("example.com", 443),
Botan::TLS::Protocol_Version::TLS_V12);
}
How does this work?
Addressing the vulnerability of disabled TLS certificate validation primarily involves re-enabling the default validation.
To avoid running into problems with invalid certificates, consider the following sections.
Using trusted certificates
If possible, always use a certificate issued by a well-known, trusted CA for your server. Most programming environments come with a predefined list
of trusted root CAs, and certificates issued by these authorities are validated automatically. This is the best practice, and it requires no
additional code or configuration.
Working with self-signed certificates or non-standard CAs
In some cases, you might need to work with a server using a self-signed certificate, or a certificate issued by a CA not included in your trusted
roots. Rather than disabling certificate validation in your code, you can add the necessary certificates to your trust store.
How to fix it in cURL
Code examples
The following code contains examples of disabled certificate validation.
The certificate validation gets disabled by setting CURLOPT_SSL_VERIFYPEER
to 0L
. To enable validation set the value to
1L
or do not set CURLOPT_SSL_VERIFYPEER
at all to use the secure default value.
Noncompliant code example
#include <curl/curl.h>
void connect() {
CURL *curl;
curl_global_init(CURL_GLOBAL_DEFAULT);
curl = curl_easy_init();
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); // Noncompliant
curl_easy_perform(curl);
}
Compliant solution
#include <curl/curl.h>
void connect() {
CURL *curl;
curl_global_init(CURL_GLOBAL_DEFAULT);
curl = curl_easy_init();
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L);
curl_easy_perform(curl);
}
How does this work?
Addressing the vulnerability of disabled TLS certificate validation primarily involves re-enabling the default validation.
To avoid running into problems with invalid certificates, consider the following sections.
Using trusted certificates
If possible, always use a certificate issued by a well-known, trusted CA for your server. Most programming environments come with a predefined list
of trusted root CAs, and certificates issued by these authorities are validated automatically. This is the best practice, and it requires no
additional code or configuration.
Working with self-signed certificates or non-standard CAs
In some cases, you might need to work with a server using a self-signed certificate, or a certificate issued by a CA not included in your trusted
roots. Rather than disabling certificate validation in your code, you can add the necessary certificates to your trust store.
How to fix it in OpenSSL
Code examples
The following code contains examples of disabled certificate validation.
The certificate validation gets disabled by overriding verify_callback
with an empty implementation. It is highly recommended to use
the original implementation.
Noncompliant code example
#include <openssl/ssl.h>
static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx) { return 1; }
void connect() {
const SSL_METHOD *method = TLS_method();
SSL_CTX *ctx = SSL_CTX_new(method);
SSL_CTX_set_verify(ctx, CURLOPT_SSL_VERIFYPEER, verify_callback); // Noncompliant
SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL); // Noncompliant
SSL *ssl = SSL_new(ctx);
SSL_connect(ssl);
}
Compliant solution
#include <openssl/ssl.h>
void connect() {
const SSL_METHOD *method = TLS_method();
SSL_CTX *ctx = SSL_CTX_new(method);
SSL *ssl = SSL_new(ctx);
SSL_connect(ssl);
}
How does this work?
Addressing the vulnerability of disabled TLS certificate validation primarily involves re-enabling the default validation.
To avoid running into problems with invalid certificates, consider the following sections.
Using trusted certificates
If possible, always use a certificate issued by a well-known, trusted CA for your server. Most programming environments come with a predefined list
of trusted root CAs, and certificates issued by these authorities are validated automatically. This is the best practice, and it requires no
additional code or configuration.
Working with self-signed certificates or non-standard CAs
In some cases, you might need to work with a server using a self-signed certificate, or a certificate issued by a CA not included in your trusted
roots. Rather than disabling certificate validation in your code, you can add the necessary certificates to your trust store.
Resources
Documentation
Standards