Validating SSL Certificates in Non-Browser Software
Validating SSL Certificates in Non-Browser Software
Martin Georgiev
The University of Texas at Austin
Subodh Iyengar
Stanford University
Suman Jana
The University of Texas at Austin
Rishita Anubhai
Stanford University
Dan Boneh
Stanford University
Vitaly Shmatikov
The University of Texas at Austin
ABSTRACT
SSL (Secure Sockets Layer) is the de facto standard for secure Internet communications. Security of SSL connections against an active network attacker depends on correctly validating public-key certicates presented when the connection is established. We demonstrate that SSL certicate validation is completely broken in many security-critical applications and libraries. Vulnerable software includes Amazons EC2 Java library and all cloud clients based on it; Amazons and PayPals merchant SDKs responsible for transmitting payment details from e-commerce sites to payment gateways; integrated shopping carts such as osCommerce, ZenCart, Ubercart, and PrestaShop; AdMob code used by mobile websites; Chase mobile banking and several other Android apps and libraries; Java Web-services middlewareincluding Apache Axis, Axis 2, Codehaus XFire, and Pusher library for Androidand all applications employing this middleware. Any SSL connection from any of these programs is insecure against a man-in-the-middle attack. The root causes of these vulnerabilities are badly designed APIs of SSL implementations (such as JSSE, OpenSSL, and GnuTLS) and data-transport libraries (such as cURL) which present developers with a confusing array of settings and options. We analyze perils and pitfalls of SSL certicate validation in software based on these APIs and present our recommendations.
Keywords
SSL, TLS, HTTPS, public-key infrastructure, public-key certicates, security vulnerabilities
cations. The main purpose of SSL is to provide end-to-end security against an active, man-in-the-middle attacker. Even if the network is completely compromisedDNS is poisoned, access points and routers are controlled by the adversary, etc.SSL is intended to guarantee condentiality, authenticity, and integrity for communications between the client and the server. Authenticating the server is a critical part of SSL connection establishment.1 This authentication takes place during the SSL handshake, when the server presents its public-key certicate. In order for the SSL connection to be secure, the client must carefully verify that the certicate has been issued by a valid certicate authority, has not expired (or been revoked), the name(s) listed in the certicate match(es) the name of the domain that the client is connecting to, and perform several other checks [14, 15]. SSL implementations in Web browsers are constantly evolving through penetrate-and-patch testing, and many SSL-related vulnerabilities in browsers have been repaired over the years. SSL, however, is also widely used in non-browser software whenever secure Internet connections are needed. For example, SSL is used for (1) remotely administering cloud-based virtual infrastructure and sending local data to cloud-based storage, (2) transmitting customers payment details from e-commerce servers to payment processors such as PayPal and Amazon, (3) logging instant messenger clients into online services, and (4) authenticating servers to mobile applications on Android and iOS. These programs usually do not implement SSL themselves. Instead, they rely on SSL libraries such as OpenSSL, GnuTLS, JSSE, CryptoAPI, etc., as well as higher-level data-transport libraries, such as cURL, Apache HttpClient, and urllib, that act as wrappers around SSL libraries. In software based on Web services, there is an additional layer of abstraction introduced by Web-services middleware such as Apache Axis, Axis 2, or Codehaus XFire. Our contributions. We present an in-depth study of SSL connection authentication in non-browser software, focusing on how diverse applications and libraries on Linux, Windows, Android, and iOS validate SSL server certicates. We use both white- and blackbox techniques to discover vulnerabilities in validation logic. Our main conclusion is that SSL certicate validation is completely broken in many critical software applications and libraries. When presented with self-signed and third-party certicatesincluding a certicate issued by a legitimate authority to a domain called AllYourSSLAreBelongTo.us they establish SSL connections and send their secrets to a man-in-the-middle attacker.
1.
INTRODUCTION
Originally deployed in Web browsers, SSL (Secure Sockets Layer) has become the de facto standard for secure Internet communi-
Permission to make digital or hard copies of all or part of this work for personal or classroom use is granted without fee provided that copies are not made or distributed for prot or commercial advantage and that copies bear this notice and the full citation on the rst page. To copy otherwise, to republish, to post on servers or to redistribute to lists, requires prior specic permission and/or a fee. CCS12, October 1618, 2012, Raleigh, North Carolina, USA. Copyright 2012 ACM 978-1-4503-1651-4/12/10 ...$15.00.
1 SSL also supports client authentication, but we do not analyze it in this paper.
This is exactly the attack that SSL is intended to protect against. It does not involve compromised or malicious certicate authorities, nor forged certicates, nor compromised private keys of legitimate servers. The only class of vulnerabilities we exploit are logic errors in client-side SSL certicate validation. The root cause of most of these vulnerabilities is the terrible design of the APIs to the underlying SSL libraries. Instead of expressing high-level security properties of network tunnels such as condentiality and authentication, these APIs expose low-level details of the SSL protocol to application developers. As a consequence, developers often use SSL APIs incorrectly, misinterpreting and misunderstanding their manifold parameters, options, side effects, and return values. In several cases, we observed developers introducing new vulnerabilities when attempting to x certicate validation bugs. Furthermore, deveopers often do not understand which security properties are or are not provided by a given SSL implementation: for example, they use SSL libraries that do not validate certicates even when security is essential (e.g., connecting to a payment processor). More prosaic, yet deadly causes include intermediate layers of the software stack silently disabling certicate validation and developers turning off certicate validation accidentally (e.g., for testing) or intentionally.
In summary, SSL connections established by any of the above programs are insecure against a man-in-the-middle attack. All vulnerabilities have been empirically conrmed. Causes. For the most part, the actual SSL libraries used in these programs are correct. Yet, regardless of which well-known library the software relies onwhether JSSE, OpenSSL, GnuTLS, or CryptoAPI, used directly or wrapped into a data-transport library such as Apache HttpClient or cURLit often nds a way to end up with broken or disabled SSL certicate validation. The primary cause of these vulnerabilities is the developers misunderstanding of the numerous options, parameters, and return values of SSL libraries. For example, Amazons Flexible Payments Service PHP library attempts to enable hostname verication by setting cURLs CURLOPT_SSL_VERIFYHOST parameter to true. Unfortunately, the correct, default value of this parameter is 2; setting it to true silently changes it to 1 and disables certicate validation. PayPal Payments Standard PHP library introduced the same bug when updating a previous, broken implementation. Another example is Lynx, a text-based browser which is often used programmatically and thus included in our study. It checks for self-signed certicatesbut only if GnuTLSs certicate validation function returns a negative value. Unfortunately, this function returns 0 for certain errors, including certicates signed by an untrusted authority. Chain-of-trust verication in Lynx is thus broken. Developers often misunderstand security guarantees provided by SSL libraries. For example, JSSE (Java Secure Socket Extension) has multiple interfaces for managing SSL connections. The advanced SSLSocketFactory API silently skips hostname verication if the algorithm eld in the SSL client is NULL or an empty string rather than HTTPS. This is mentioned in passing in the JSSE reference guide, yet many Java implementations of SSL-based protocols use SSLSocketFactory without performing their own hostname verication. Vulnerable libraries include Apache HttpClient version 3.* and the Weberknecht implementation of WebSockets. Any Java program based on these libraries is generically insecure against a man-in-the-middle attack. Vulnerable programs include SOAP Web-services middleware such as Apache Axis and Codehaus XFire, as well as any software built on top of it (for example, Amazons EC2 client library), any Android app that uses Pusher API to manage real-time messaging (for example, GitHubs Gaug.es), clients of Apache ActiveMQ servers, etc. Other bugs include using incorrect regular expressions for hostname matching, not checking the results of certicate validation correctly, accidentally or deliberately disabling validation, etc. Lessons. First, the state of adversarial testing appears to be exceptionally poor even for critical software such as mobile banking apps and merchant SDKs responsible for managing secure connections to payment processors. Most of the vulnerabilities we found should have been discovered during development with proper unit testing. Second, many SSL libraries are unsafe by default, requiring higher-level software to correctly set their options, provide hostname verication functions, and interpret return values. As we show, software that relies on these libraries is often not up to the task. Third, even safe-by-default libraries, such as cURLs wrapper around OpenSSL, are misused by developers that misinterpret the meaning of various options. This calls for better documentation and more rigorous formalization of API semantics. In particular, APIs should present high-level abstractions to developers, such as condential and authenticated tunnel, as opposed to requiring them to explicitly deal with low-level details such as hostname verication. Fourth, SSL bugs are often hidden deep inside layers of middleware, above the actual SSL implementation but below the applica-
2.
Our study uncovered a wide variety of SSL certicate validation bugs. Affected programs include those responsible for managing cloud-based storage and computation, such as Amazons EC2 Java client library and Elastic Load Balancing API Tools, Apache Libcloud, Rackspace iOS client, and Windows-based cloud storage clients such as ElephantDrive and FilesAnywhere. Java-based Web-services middleware, such as Apache Axis, Axis 2, and Codehaus XFire, is broken, too. So is the Android library for Pusher notication API and Apache ActiveMQ implementation of Java Message Service. All programs employing this middleware are generically insecure. Certicate validation bugs are pervasive in merchant SDKs, which typically run on e-commerce servers (e.g., online stores) and are responsible for transmitting customers nancial details to payment processing gateways. Broken libraries include Amazon Flexible Payments Service (both Java and PHP), as well as PayPal Payments Standard and PayPal Invoicing (both in PHP), PayPal Payments Pro, Mass Pay, and Transactional Information SOAP (all in Java). Most payment modules for integrated shopping carts, such as ZenCart, Ubercart, PrestaShop, and osCommerce, do not validate certicates, either. A man-in-the-middle attack enables the attacker to harvest credit card numbers, names, addresses, etc. of the customers of any merchant who uses one of these programs for payment processing. Mobile app providers who use AdMobs sample code to link app instances to their AdMob accounts are vulnerable, too, enabling the attacker to capture the developers account credentials and gain access to all of her Google services. Instant messenger clients such as Trillian and AIM do not validate certicates correctly, either. A man-in-the-middle attack on Trillian yields login credentials for all Google (including Gmail), Yahoo!, and Windows Live services (including SkyDrive). Not the most interesting technically, but perhaps the most devastating (because of the ease of exploitation) bug is the broken certicate validation in the Chase mobile banking app on Android. Even a primitive network attackerfor example, someone in control of a malicious Wi-Fi access pointcan exploit this vulnerability to harvest the login credentials of Chase mobile banking customers. Other insecure Android software includes Breezy, a secure printing app, and the ACRA library for application crash reporting.
tion, making the problem hard to locate and repair, and effectively taking it out of application developers hands. Fifth, least interesting technically but still critically important, we observed many cases of developers deliberately disabling certicate validation, while assuring both users and higher-level programs that SSL is being supported but not informing them that protection against active attacks has been turned off.
cates have not expired and that the certicates of the intermediate CAs have the CA bit set in the Basic Constraints eld. Hostname verication. After the chain of trust is established, the client must verify the servers identity. RFC 2818 advises the implementors to use SubjectAltNames as the main source of server identiers and support Common Name for backward compatibility only, but most of the software we tested does it the other way around and checks Common Name rst. After building the list of server identiers, the client attempts to match the fully qualied DNS name of the requested server to one of the identiers. If the client nds an exact match in the list of server identiers, verication is done by straightforward string comparison. The client may also nd a wildcard name in the list of identiers. The rules for wildcard matching are fairly complex [14, 17], especially concerning international character sets. Certicate revocation and X.509 extensions. This paper focuses on verifying the servers identity, but full certicate validation involves many more checks. These checks are essential for security, yet are handled poorly or not at all by non-browser software. For example, some SSL libraries such as OpenSSL implement certicate revocation, but require the application to provide the certicate revocation list (CRL). The applications we analyzed do not avail themselves of this facility. Furthermore, libraries such as JSSE require the application to check validity of the CRL on its own. Most applications dont bother. Other SSL libraries, such as Pythons ssl, do not expose a method for CRL checking. Some X.509 certicate extensions contain security-critical information such as key usage (e.g., is the CA allowed to use this key for signing certicates?), name constraints (restricting the names that a sub-CA can certify), and certicate policies, described in RFC 2527 [13]. For instance, a CA may assign different levels of trust to different sub-CAs, but the application must provide a policy that takes advantage of this information. In practice, these extensions are largely neglected. For example, until recently OpenSSL did not validate name constraints correctly, while cURL does not even have an interface for specifying the applications certicate policy. Attacks exploiting improper treatment of certicate revocation and X.509 extensions are somewhat different from the pure manin-the-middle model considered in this paper. We leave their detailed analysis to future work.
3.
OVERVIEW OF SSL
4. SSL ABSTRACTIONS
Depending on its needs, an application can plug into SSL at different levels of abstraction. At the lowest level, there are many popular SSL implementations with different features, licenses, and hardware requirements: OpenSSL, JSSE, CryptoAPI, NSS, yaSSL, GnuTLS, BouncyCastle, and others. These libraries are mostly oblivious to protocols transported over SSL. Therefore, to avoid having to parse HTTP messages on their own, applications that involve HTTP over SSL (HTTPS) typically do not use them directly. Instead, they employ one of the many HTTPS libraries (see Section 4.2), which in turn use SSL libraries internally. Applications that use SOAP- or REST-based Web services require additional middleware on top of HTTPS or WebSockets (see Figure 2).
SSL_CTX_set_verify_depth
Applications SOAP Axis ... CXF HTTP HttpsClient ... SSL TCP JSSE Applications Applications REST Pusher ... Web Socket cURL ... Weberknecht ... GnuTLS OS NetworkingStack ... ... IM OpenSSL userland libraries kernel
SSL_CTX_set_verify
SSL_new
fd
verication must be managed either by the application itself, or by a data-transport wrapper such as cURL. Proper hostname verication for OpenSSL and CryptoAPI is discussed in [21, Chap. 10.8], assuming the chain of trust has been veried correctly. As discussed in [21, Chap. 10.5], the latter is error-prone due to the complexity of the underlying API. OpenSSL allows applications to customize chain-of-trust verication by providing a callback function or modifying conguration variables such as verify depth and verify mode as shown in Figure 3. A program using OpenSSL can perform the SSL handshake by invoking the SSL_connect function. A high-level overview of the handling of different congurations and callbacks is shown in Algorithm 1. They can have complex interactions. Some certicate validation errors are signaled through the return values of SSL_connect, while for other errors SSL_connect returns OK but sets internal verify result ags. Applications must call SSL_get_ verify_result function to check if any such errors occurred. This approach is error-prone (see Section 7.6). Algorithm 1 Outline of SSL_connect control ow. while chain of trust contains no trusted CA do if chain length <verify_depth then Try to extend chain of trust by 1 level Set ERROR appropriately if any error else Set ERROR to incomplete chain end if if ERROR then verify_result = error if verify_callback == NULL then if verify_mode != 0 then Print error and terminate connection. end if else ret = verify_callback(preverify_ok = 0, . . . ) if (verify_mode != 0) and (ret == 0) then Print error and terminate connection. end if end if if ERROR is not related to incorrect parsing then return 1 else return ERROR end if else ret = verify_callback(preverify_ok = 1, . . . ) if (verify_mode != 0) and (ret == 0) then Print error and terminate connection. end if end if end while return 1
Figure 3: OpenSSL API for setting up SSL connections with the default chain-of-trust verication.
The certicate validation function in GnuTLS, gnutls_certifhas similarly atrocious error reporting. It takes a reference to tls_status as an argument and sets it to an appropriate error code if validation fails. For some errors (e.g., insufcient credentials or no certicate found), it returns a negative value; for others (e.g., self-signed certicate), it sets the error code but returns zero. In Section 7.4 we show that application developers misunderstand this complex relationship between the error status and the return value, resulting in broken certicate validation.
icate_verify_peers2,
JSSE. Java Secure Socket Extension (JSSE) provides numerous interfaces through which Java applicationsincluding Android mobile appscan establish SSL connections. The low-level API is SSLSocketFactory. Depending on how the SSL client is created, this API may or may not perform hostname verication. The following code sample is taken from X509Trust ManagerImpl.checkIdentity in Java 6 update 31:
private void checkIdentity(String hostname, X509Certificate cert, String algorithm) throws CertificateException { if (algorithm != null && algorithm.length() != 0) { .... if (algorithm.equalsIgnoreCase("HTTPS")) { HostnameChecker.getInstance(HostnameChecker.TYPE _TLS).match(hostname, cert); } else if (algorithm.equalsIgnoreCase("LDAP")) { HostnameChecker.getInstance(HostnameChecker.TYPE _LDAP).match(hostname, cert); } else { throw new CertificateException( "Unknown identification algorithm: " + algorithm); } } }
The checkIdentity method throws an exception if the algorithm eld is set to anything other than HTTPS or LDAP. This is different from, for example, OpenSSL, which returns a value even if verication fails and expects the application to check this value. JSSE APIs such as HttpsClient and HttpsURLConnection call try SetHostnameVerification when creating SSL clients. This method sets the algorithm eld to HTTPS. The above code thus invokes HostnameChecker and veries the name in the certicate. If the algorithm eld in the client data structure is NULL or an empty string, checkIdentity silently skips hostname verication without throwing an exception. We conjecture that this behavior is designed to accommodate implementors of certicate-based protocols other than HTTPS or LDAP who may want to re-use
JSSEs default trust manager for chain-of-trust verication but provide their own, protocol-specic hostname verication. On February 14, 2012, Java 7 update 3 was released. The code for certicate validation is different from Java 6, but its behavior is similar: if the algorithm eld is NULL or an empty string, checkIdentity is never invoked.
private void checkTrusted(X509Certificate[] chain, String authType, Socket socket, boolean isClient) throws CertificateException { ... / / check endpoint i d e n t i t y String identityAlg = sslSocket.getSSLParameters(). getEndpointIdentificationAlgorithm(); if (identityAlg != null && identityAlg.length != 0) { String hostname = session.getPeerHost(); checkIdentity(hostname, chain[0], identityAlg); } }
nal consistency checks: for example, it allows connections to port 443 to have HTTP as the scheme. In Section 7.8, we show how this leads to errors even in code implemented by SSL experts. Weberknecht. Weberknecht4 is a Java implementation of the WebSockets protocol. It uses SSLSocketFactory but does not perform its own hostname verication. Any Java program that employs Weberknecht is vulnerable to a man-in-the-middle attack. cURL. cURL5 is a popular tool and library (libcurl) for fetching data from remote servers. Since version 7.10, cURL validates SSL certicates by default. Internally, it uses OpenSSL to verify the chain of trust and veries the hostname itself. This functionality is controlled by parameters CURLOPT_SSL_VERIFYPEER (default value: true) and CURLOPT_SSL_VERIFYHOST (default value: 2). This interface is almost perversely bad. The VERIFYPEER parameter is a boolean, while a similar-looking VERIFYHOST parameter is an integer. The following quote from the cURL manual explains the meaning of CURLOPT_SSL_VERIFYHOST: 1 to check the existence of a common name in the SSL peer certicate. 2 to check the existence of a common name and also verify that it matches the hostname provided. In production environments the value of this option should be kept at 2 (default value). Well-intentioned developers not only routinely misunderstand these parameters, but often set CURLOPT_SSL_VERIFY HOST to TRUE, thereby changing it to 1 and thus accidentally disabling hostname verication with disastrous consequences (see Section 7.1). PHP. PHP provides several methods for establishing SSL connections. For example, fsockopen, which opens a raw socket to the remote server, can be used to connect to SSL servers by putting ssl:// in the URL. Even though fsockopen does not perform any certicate checks whatsoever, PHP application developers routinely use it for SSL connection establishment (see Section 9). PHP also provides a cURL binding, which uses cURLs default settings to establish SSL connections with proper certicate validation. As we show in Sections 7.1, 7.2, and 7.3, application developers often set cURL options incorrectly, overriding the defaults and breaking certicate validation. Python. Several Python modules can be used for SSL connection establishment. urllib, urllib2, and httplib connect to SSL servers but do not check certicates. This is clearly documented in a bright pink box on the urllib front page:6 Warning: When opening HTTPS URLs, it does not attempt to validate the server certicate. Use at your own risk! Nevertheless, even high-security applications routinely use these modules for SSL connection establishment (see Section 9). Python also has an ssl module. This module veries the certicates chain of trust, but not the hostname. The application must do its own hostname verication. In Python version 3, the ssl module introduced the match_hostname method for hostname verication, but it must be explicitly called by the application.
In SSL clients created using raw SSLSocketFactory (as opposed to HttpsClient or HttpsURLConnection wrappers), the algorithm eld is NULL, thus JSSE does not perform hostname verication. The responsibility for hostname verication is delegated to the software running on top of JSSE. This feature is not explained in the API documentation. Instead, the following warning can be found deep inside the JSSE reference guide:2 When using raw SSLSockets/SSLEngines you should always check the peers credentials before sending any data. The SSLSocket and SSLEngine classes do not automatically verify that the hostname in a URL matches the hostname in the peers credentials. An application could be exploited with URL spoong if the hostname is not veried. The prevalence of Java software that uses SSLSocketFactory to create SSL clients yet does not perform hostname verication (see Section 4.2) suggests that developers are not aware of this feature. The existence of alternative JSSE interfaces that do perform hostname verication only increases the confusion.
4 5
5.
Merchants Website
Payment Gateway
We analyze a representative sample of non-browser software applications and libraries that use SSL for secure Internet connections. Some programs, such as instant messenger clients and simple mobile banking apps, are fairly straightforward in their use of SSL. Others, especially middleware libraries, use SSL as part of a multi-layer software stack. Many of the programs we analyze transmit extremely sensitive dataprivate les of individual users in the case of cloud clients, nancial information of customers in the case of merchant SDKs, developer account credentials in the case of mobile advertising softwareover potentially insecure public networks, thus it is absolutely critical that they use SSL correctly. Cloud client APIs. As cloud-computing platforms such as Amazon EC2 grow in popularity, their operators supply client SDKs through which third-party software can transmit user data to cloudbased storage, manage cloud-based computation (e.g., start and terminate virtual instances), and access other cloud services. For example, Amazon provides EC2 API tools in Java, PHP, Python, and Perl. Apache Libcloud is an example of an independent library for accessing multiple cloud providers. Merchant payment SDKs. Operators of e-commerce websites often rely on third parties such as PayPal and Amazon Flexible Payments Service (FPS) to process their customers payments. Payment processors provide merchant SDKs (software development kits) in a variety of languages. These libraries are designed to be integrated into the back end of e-commerce websites. Merchant software uses them to transmit customers payment details and/or receive notications when payments are made by customers. An online store typically has two options for payment processing. The rst option is to have the customer enter payment details directly into the payment processors website. When the customer checks out, the merchants website redirects her browser to PayPal or Amazon, where the customer enters her name, credit or debit card number, etc. The merchant never sees these details. Once the payment is complete, the payment processor redirects the customer back to the merchants website and noties the merchant. The merchants site runs a daemon listening for IPN (Instant Payment Notication) calls from the payment processor. Upon receiving a notication, the merchant is advised to verify that the call indeed originated from the processor (some merchants skip this step, opening the door to shop-for-free attacks [23]). The merchant then completes the transaction with the customer. The second option is preferred by larger, more established stores. It does not require the customer to leave the merchants website and allows the merchant to collect payment details directly from the customer. The back-end software on the merchants website then transmits these details to the payment processors gateway over an SSL connection and receives the conrmation that the payment succeeded (often over the same SSL connection). Fig. 4 shows schematically the interaction between the merchants server and the payment gateway. The SSL client is the merchants back-end software (running on the merchants server), while the payment gateway acts as the SSL server. We analyzed SSL connection establishment in popular merchant SDKs, including Java and PHP SDKs for Amazon Flexible Payments Service and multiple interfaces to PayPal: Payments Pro, Transactional Information, and Mass Pay (all in Java), as well as Payments Standard and Invoicing (PHP). We also analyzed both Amazons and PayPals utilities that merchants can use to verify the origin of IPN (Instant Payment Notication) calls. We also analyzed several open-source shopping carts written in PHP: osCommerce, ZenCart, Ubercart, and PrestaShop. Shopping
Customer
1 SDK
2
SSL tunnel
carts are an important component of e-commerce websites. They keep track of customers shipping and billing information and allow them to purchase multiple items in one transaction. When the customer checks out, the shopping cart generates a summary of the purchases and the total price and sends it to the payment gateway. Shopping carts include modules for many payment processors. Web-services middleware. Many modern programs rely on Web services. A Web service is a software system designed to support interoperable machine-to-machine interaction over a network.7 A service has an interface described in a machine-readable XML format. Different providers may provide different concrete implementations of this interface. Other systems interact with the service by sending and receiving messages. Messages to and from Web services are sent using XML-based Simple Object Access Protocol (SOAP) or REpresentational State Transfer (REST). From the viewpoint of the client software, a Web service can be thought of as providing a remote procedure call (RPC) interface, while SOAP or REST middleware marshals and unmarshals arguments of RPC calls. To interact with such a Web servicefor example, if a cloud client implemented in Java wants to interact with Amazon EC2 existing Java software often uses SOAP middleware such as Apache Axis, Axis 2, or Codehaus XFire (see Section 8). Similarly, if an Android app needs real-time push notications, it may use a client-side library to connect to the REST-based Pusher service.8 These middleware frameworks are responsible for transmitting Web-service messages over the network. If the connection must be secure, the middleware typically uses SSL but delegates actual SSL connection management to a data-transport library such as Apache HttpClient or Weberknecht (see Section 4.2). Mobile advertising. Mobile advertising services such as AdMob supply software that providers of mobile apps install on their sites. When a new app instance is initialized on a customers phone, it connects to the providers site, which in turn noties the AdMob server so that all ads shown to this app instance will be associated with the providers account (to enable ad revenue sharing, etc.). The connection from the app providers site to the AdMob server contains the providers credentials and must be protected by SSL.
6. EXPERIMENTAL TESTBED
Our primary methodology for the initial discovery of SSL certicate validation bugs is black-box fuzzing. We test applications and libraries implementing SSL client functionality on two Dell laptops running Microsoft Windows 7 Professional Service Pack
7 8
http://www.w3.org/TR/ws-arch/ http://pusher.com
1 and Ubuntu Linux 10.04, respectively. Mobile applications are tested on a Nexus One smartphone running Android 2.3.6 and an iPad 2 running iOS 4.2.1. We use local DNS cache poisoning to divert clients connections to a simulated attack server executing on an old Dell laptop with Ubuntu Linux 10.04. To simulate a man-in-the-middle attacker, we built two prototypes: one in Java, using JKS keystore to manage the attackers certicates and keys, the other in C, using OpenSSL for certicate and key management. We also used Fiddler, a Web debugging proxy [9]. If Fiddler encounters a connection request to a server it has not seen before, it creates a new certicate with the common name matching the requested name and stores it in its repository; otherwise, it retrieves an existing certicate from its repository. Fiddler then presents the certicate to the client, allowing us to simulate a man-in-the-middle attacker who presents self-signed certicates with correct common names. In addition, we enabled Fiddler to capture and decrypt HTTPS connections. Our simulated man-in-the-middle server presents the client with several certicates: (1) a self-signed certicate with the same common name as the host the client is attempting to connect to, (2) a self-signed certicate with an incorrect common name, and (3) a valid certicate issued by a trusted certicate authority to a domain called AllYourSSLAreBelongTo.us. If the client establishes an SSL connection, the attack server decrypts trafc sent by the client. It can then establish its own SSL connection to any legitimate server specied by the attacker and forward the clients trafc. The attack server also listens for the legitimate servers response, decrypts and logs it, re-encrypts it with the symmetric key the attacker shares with the client and forwards it to the client. If we observed a particular client successfully establishing an SSL connection when presented with any of the attack certicates, we analyzed the source code of the client or, in the case of closedsource applications, the results of reverse-engineering, decompilation, and runtime traces (focusing in particular on calls to SSL libraries) in order to nd the root cause of the vulnerability. In Sections 7 through 10, we describe the vulnerabilities in specic programs, arranged by error type.
The URL verication utilityfound in src\Amazon\IpnReturnUrlValidation\SignatureUtilsForOutbound. phpis broken in a very similar way. This utility is critically important because it is used by merchants to verify the origin of the calls informing them that a customers payment has been successfully processed (see Section 5). Because Amazons PHP SDK does not correctly verify the origin of the IPN call, e-commerce sites using it may be vulnerable to shop-for-free attacks [23].
CURLOPT_SSL_VERIFYHOST and
As in Section 7.1, this code overrides the correct default value of breaks hostname verication. PayPal Invoicing contains similarly broken code:
Any PHP code using these PayPal-provided SDKs to establish an SSL connection to PayPals payment processing gateway is insecure against a man-in-the-middle attack.
7.
7.4 Lynx
Lynx is a text-based browser, included in our study because it is often used programmatically by other software. It relies on GnuTLS to validate SSL certicates:
ret = gnutls_certificate_verify_peers2(handle->gnutls_ state, &tls_status); if (ret < 0) { int flag_continue = 1; char *msg2; if (tls_status & GNUTLS_CERT_SIGNER_NOT_FOUND) { msg2 = gettext("no issuer was found"); } else if (tls_status & GNUTLS_CERT_SIGNER_NOT_CA) { msg2 = gettext("issuer is not a CA"); } else if (tls_status & GNUTLS_CERT_SIGNER_NOT_FOUND) { msg2 = gettext("the certificate has no known issuer" ); } else if (tls_status & GNUTLS_CERT_REVOKED) { msg2 = gettext("the certificate has been revoked"); } else {
This well-intentioned code contains a fatal mistake. cURLs default value of CURLOPT_SSL_VERIFYHOST is correctly set to 2. In the curl_setopt($curlHandle,CURLOPT_SSL_VERIFYHOST, true) call, true silently turns into 1, overriding the default and instructing cURL to check the existence of any common name in the certicate (Section 4.2), which may or may not match the name requested. Any PHP code using this Amazon-provided SDK to establish an SSL connection to the Amazon Flexible Payments Service gateway is insecure against a man-in-the-middle attack.
gnutls_certificate_
verify_peers2. As explained in Section 4.1, this function indeed sets the tls_status code if certicate validation fails, but for cer-
tain errorsincluding self-signed certicates!it returns 0. Even though the above code includes two identical checks for GNUTLS_ CERT_SIGNER_NOT_FOUND, neither check is ever executed when GNUTLS_CERT_SIGNER_NOT_FOUND is actually true! In this case hostname verication is correct, but chain-of-trust verication is broken.
example, it will reject mail.<a>.<b>.com if the name in the certicate is m*.<a>.<b>.com. Furthermore, the original patch, as well as its derivatives, has a minor bug in the regular expression for parsing IPv4 addresses, causing it to accept IP addresses starting with zero (this does not immediately result in a security vulnerability):
private static final Pattern IPV4_PATTERN = Pattern.compile("^(25[0-5]|2[0-4]\\d|[0-1]?\\d ?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)) {3}\$");
7.6 Trillian
Trillian, a popular instant messenger client, relies on OpenSSL for SSL connection establishment. By default, OpenSSL does not throw a run-time exception if the certicate is self-signed or has an invalid chain of trust. Instead, it sets ags. Furthermore, OpenSSL does not provide any hostname verication. If the application has called SSL_CTX_set to set the SSL_VERIFY _PEER ag (see Section 4.1), then SSL_connect exits and prints an error message when certicate validation fails. Trillian does not set the SSL_VERIFY_PEER ag. When this ag is not set, SSL_connect returns 1. The application is then expected to check the status of certicate validation by calling SSL_get_verify_result. Trillian does not call this function. Trillian thus accepts any SSL certicate and is insecure against a man-in-the-middle attack. Depending on the specic module chosen by the Trillian user, this reveals usernames, passwords, security tokens, etc. for Google Talk (typically compromising all of the users Google services), AIM, ICQ, Windows Live (including SkyDrive), and Yahoo! Messenger (and thus all Yahoo! services). Interestingly, it was reported back in 2009 that older versions of Trillian do not correctly validate MSN certicates [20]. This bug was ostensibly xed in Trillian 4.2. Our analysis shows, however, that SSL certicate validation is still completely broken for all services, not just for MSN (Windows Live), in Trillian 5.1.0.19.
7.7 Rackspace
The Rackspace app for iOS (version 2.1.5) is an open-source application for administering Rackspace cloud services. It uses the OpenStack iOS cloud client framework, which in turn relies on the ASIHTTPRequest library to set up HTTPS connections. ASIHTTPRequest provides a conguration variable Validates SecureCertificate, set to 1 by default. If reset to 0, it turns off both chain-of-trust and hostname verication. OpenStack supports multiple accounts on remote servers and lets users customize SSL certicate validation on per-account basis using the ignoreSSL Validation variable. The value of this variable depends on the GUI switch validateSSLSwitch, which should be shown to the user. The Rackspace app (version 2.1.5) does not present the user with this option.9 The GUI switch validateSSLSwitch is thus never displayed or explicitly assigned. Instead, it is simply initialized to 0 by the Objective-C allocator. This turns on ignoreSSLValidation in ASIHTTPRequest, which in turn sets ValidatesSecureCertificate to 0 and disables certicate validation. As a consequence, SSL connections established by the Rackspace app on iOS are insecure against a man-in-the-middle attack.
7.8 TextSecure
TextSecure is an Android application for encrypting SMS and MMS messages. It was written by Moxie Marlinspike who had
9 We are informed by Mike Mayo that this was an accidental oversight and will be xed in subsequent releases of the app.
This code computes the length of the prex by subtracting 2 from the number of parts (determined by the number of dots in the name). This logic is incorrect: validity of the rst part of a domain name should have nothing to do with the total number of parts. For
previously discovered several SSL certicate validation vulnerabilities [11, 12]. This following code can be found in the application (however, it does not appear to be reachable from the user interface and may not currently lead to an exploitable vulnerability):
schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); schemeRegistry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443)); ... HttpHost target = new HttpHost(hostUrl.getHost(), hostUrl.getPort(), HttpHost.DEFAULT_SCHEME_NAME); ... HttpResponse response = client.execute(target, request);
In summary, any software using any of the above Web-services frameworks is insecure against a man-in-the-middle attack. Apache CXF. Apache CXF is a continuation of XFire. It supports SOAP, along with REST and CORBA; the latest release is 2.6.1. It does not rely on Apache HttpClient. Instead, SSL connections are established using OpenJDKs HttpsClient. Therefore, properly congured instances of CXF do verify hostnames. Apache CXF provides an application-controlled option to turn off certicate validation. Certicate validation is enabled by default, but was disabled in the sample wsdl_first_https code supplied with CXF until we notied the developers.
Even if the port number is 443, DEFAULT_SCHEME_NAME is http and the connection is over HTTP, not HTTPS.
8.
As explained in Section 5, software based on Web services usually relies on middleware libraries to manage network connections. SSL functionality inside these libraries is opaque to the applications. If the middleware employs a broken HTTPS implementation that does not correctly validate SSL certicates, all applications based on it typically inherit the vulnerability.
This code is replicated in PayPal payment modules for ZenCart and PrestaShop shopping carts. PrestaShop uses fsockopen in its CanadaPost payment module, too. Other similarly vulnerable software includes Open Source Classieds, Pythons URL libraries do not validate certicates (Section 4.2), yet developers still use them for SSL connections. Examples include Tweepy, a library for accessing Twitter API that uses httplib, and Mozillas Zamboni project, which accepts contributions for extension developers and uses urllib2 to connect to PayPal.
Tutorial: Disabling Certicate Validation in an HTTPS Connection. . . Reply: Thank you very much. You solved my biggest problem in the project. 12 I have always turned off CURLOPT_SSL_VERIFYPEER in curl.13 I am using axis on java to consume a webservice. The web service is in https, and I want to avoid the the check for certicate.14
11
8.2 Pusher
Pusher is a WebSocket-based API that provides real-time messaging functionality to mobile and Web applications. Pushers Android libraries10 are based on Weberknecht (see Section 4.2). Any application using these libraries (e.g., GitHubs Gaug.es) is thus insecure. It is also worth noting that Gaug.es is using an updated version of Weberknecht, which, in addition to incorrectly using raw SSLSocketFactory (see Section 4.1), disables the trust manager.
10
https://github.com/EmoryM/Android_Pusher
However, by default, SSL support in NSStream is a little paranoid. It wont, for example, use a self-signed certicate or an expired certicate to establish a secure connection. NSStream does a number of validity checks when establishing the secure connection, and if they dont all pass, the streams appear to be valid, but no data gets sent or received. This is somewhat frustrating, and it could be theres a way to nd out when the secure connection failed, but I havent been able to nd it in the documentation, or using Google. There is an error domain declared for these errors (NSStreamSocketSSLErrorDomain), but in my experimentation, no errors gets generated, the streams even accept bytes for transfer, but nothing happens. 15 Unfortunately, these bad development practices nd their way even into critical software responsible for transmitting nancial information and sensitive data, where security against man-in-themiddle attacks is absolutely essential and SSL certicate validation should be mandatory. For example, a comment in the Authorize.Net eCheck module of ZenCart says that certicate validation is disabled for compatibility for SSL communications on some Windows servers (IIS 5.0+)note the fallacious reasoning!
def # # # #
_verify_hostname(self, hostname, cert): V e r i f y hostname a g a i n s t peer c e r t Check b o t h commonName and e n t r i e s i n s u b j e c t A l t N a m e , u s i n g a r u d i m e n t a r y glob t o dns r e g e x check to f i n d matches
common_name = self._get_common_name(cert) alt_names = self._get_subject_alt_names(cert) # r e p l a c e w i t h a l p h a n u m e r i c and d a s h # replace . with l i t e r a l . valid_patterns = [re.compile(pattern.replace(r".", r" \.").replace(r"*", r"[0-9A-Za-z]+")) for pattern in (set(common_name) | set(alt_names)) ] return any( pattern.search(hostname) for pattern in valid_patterns )
This bug has been xed in Libcloud version 0.11.1 after we notied the developers.
Note the unreachable invocation of checkServerTrusted. We conjecture that this was a temporary plug during development that somehow found its way into the production version of the app.
10.5 AdMob
Googles AdMob provides sample code to mobile site owners that they can use on their servers to associate instances of their mobile apps with their developer accounts (see Section 5). This code uses cURL to establish an SSL connection to AdMobs server, but turns off certicate validation. A man-in-the-middle attacker can thus gain access to all of the developers Google services.
ager. Similarly, Breezy, an app for secure document printing, disables hostname verication and overrides the default trust manager. ACRA, an Android library for posting application crash reports to a Google Doc, overrides the default trust manager. Any app using this library is insecure against a man-in-the-middle attack.
10.7 AIM
AIM client version 1.0.1.2 on Windows uses Microsofts CryptoAPI. Runtime analysis shows that it calls CryptoAPIs certicate validation function CertVerifyCertificateChainPolicy. To disable certicate validation, it passes a CERT_CHAIN_POLICY_PARA variable with CERT_CHAIN_POLICY_ALLOW_UNKNOWN_CA_FLAG set, instructing CryptoAPI to accept certicates signed by untrusted authorities. AIM does not perform any hostname verication, either.
10.8 FilesAnywhere
FilesAnywhere is an application for managing cloud storage. It uses CryptoAPI for SSL connections and accepts both self-signed and third-party certicates. FilesAnywhere has an interesting peculiarity. If presented with a Google certicate when it attempts to connect to a non-Google server, it shows a warning message The WebDav server has a new address. Please specify http://google.com in the prole. If presented with any other third-party certicate, it silently accepts it and sends users data to a wrong, potentially malicious server.
example, the PHP libraries for Amazon Flexible Payments Services and PayPal Payments Standard attempt to enable hostname verication in cURL, but instead accidentally override the correct default value and end up disabling it (Sections 7.1 and 7.2). This shows that even safe defaults may be insufcient. Lynx attempts to check for self-signed certicates, but misinterprets the meaning of return values of GnuTLSs certicate validation function and the check is never executed (Section 7.4). Formalizing the precise semantics of SSL library API and rigorously verifying the contracts between the application and the library is an interesting topic for future research and may call for programming language support. DONT delegate the responsibility for managing SSL connections to the applications. Existing SSL libraries expose many options to higher-level software. This is fraught with peril. Application developers may not realize that they must explicitly choose certain options in order to enable certicate validation. Therefore, libraries should use safe defaults as much as possible. Furthermore, they should not silently skip important functionality such as hostname verication as JSSE does when the algorithm eld is NULL or an empty string (see Section 4.1). Instead, they should raise a runtime exception or inform the application in some other way. DO design a clean and consistent error reporting interface. Libraries such as OpenSSL and GnuTLS report some errors via return values of functions, while other errors from the same function are reported through a ag passed as an argument. Inconsistent interfaces confuse developers who then mistakenly omit some error checks in their applications. These recommendations provide short-term xes. A principled solution to the problem must involve a complete redesign of the SSL libraries API. Instead of asking application developers to manage incomprehensible options such as CURLOPT_SSL_VERIFYPEER or SSL_get_verify_result, they should present high-level abstractions that explicitly express security properties of network connections in terms that are close to application semantics: for example, a condential and authenticated tunnel. The library should also be explicit about the security consequences of any applicationcontrolled option: for example, instead of verify hostname?, it could ask Anyone can impersonate the server. Ok or not?
http://www.unrest.ca/peerjacking
Several certicate authorities such as Comodo [5] and DigiNotar [6] were recently compromised and used by attackers to issue fake certicates for popular websites. By contrast, our attacks do not involve CA compromise. To mitigate the risks of rogue certicates, Evans et al. proposed certicate pinning, i.e., pre-established bindings in the browser between well-known websites and their certicates [8]. Certicate pinning is not supported by any of the software we analyzed. Several large-scale studies analyzed HTTPS deployment [7, 22] and found many errors in SSL certicates. One of the most common errors is a mismatch between the servers fully qualied domain name and certicates identiers. This misconguration alone does not enable a man-in-the-middle attack. Chen et al. showed how a malicious proxy can exploit browser bugs for man-in-the-middle attacks on HTTPS [3]. By contrast, our attacks do not depend on browser bugs. Side-channel attacks can extract information from encrypted trafc even when SSL is correctly deployed [4, 19]. By contrast, we found vulnerabilities that enable a man-in-the-middle attacker to decrypt SSL trafc, obviating the need for side-channel analysis. Other side-channel attacks include a timing attack that extracts the private key from OpenSSL implementations [2].
13. CONCLUSION
The main lesson of this paper is that using SSL in non-browser software is a surprisingly challenging task. We demonstrated that even applications that rely on standard SSL libraries such as JSSE, OpenSSL, GnuTLS, etc. often perform SSL certicate validation incorrectly or not at all. These vulnerabilities are pervasive in critical software, such as Amazon FPS and PayPal libraries for transmitting customers payment details from merchants to payment gateways; integrated shopping carts; Amazon EC2, Rackspace, and other clients for remote administration of cloud storage and virtual cloud infrastructure; Chase mobile banking on Android; and many other popular programs. Their SSL connections are completely insecure against a man-in-the-middle attack. We also presented our recommendations for safer use of SSL in non-browser software. Future research directions include (1) development of better black-box testing and code analysis tools for discovering errors in SSL connection establishment logic, (2) design of formal verication techniques and programming language support for automatically checking whether applications use SSL libraries correctly and not misinterpret the meaning of critical options and parameters, and (3) design of better APIs for SSL and other secure networking protocols. Acknowledgments. This research was partially supported by the NSF grants CNS-0331640, CNS-0746888, and CNS-0905602, two Google research awards, Samsung, and the MURI program under AFOSR Grant No. FA9550-08-1-0352. Boneh also thanks iSEC partners for helpful conversations about this work. We acknowledge Amazon, Apache, Chase, GitHub, Lynx, PayPal, and Rackspace developers for recognizing and promising to repair the vulnerabilities after they were brought to their attention. We thank Colm O hEigeartaigh for explaining the intended behavior of certicate validation in Apache CXF.
References
[1] https should check CN of x509 cert. https://issues. apache.org/jira/browse/HTTPCLIENT-613. [2] D. Brumley and D. Boneh. Remote timing attacks are practical. In USENIX Security, 2003.
[3] S. Chen, Z. Mao, Y.-M. Wang, and M. Zhang. Pretty-Bad-Proxy: An overlooked adversary in browsers HTTPS deployments. In S&P, 2009. [4] S. Chen, R. Wang, X. Wang, and K. Zhang. Side-channel leaks in Web applications: A reality today, a challenge tomorrow. In S&P, 2010. [5] Comodo report of incident. http://www.comodo.com/Comodo-FraudIncident-2011-03-23.html, 2011. [6] Diginotar issues dodgy SSL certicates for Google services after break-in. http://www.theinquirer.net/inquirer/ news/2105321/diginotar-issues-dodgy-sslcertificates-google-services-break, 2011. [7] P. Eckersley and J. Burns. An observatory for the SSLiverse. In DEFCON, 2010. [8] C. Evans and C. Palmer. Certicate pinning extension for HSTS. http://www.ietf.org/mail-archive/ web/websec/current/pdfnSTRd9kYcY.pdf, 2011. [9] Fiddler - Web debugging proxy. http://fiddler2.com/fiddler2/. [10] D. Kaminsky, M. Patterson, and L. Sassaman. PKI layer cake: new collision attacks against the global X.509 infrastructure. In FC, 2010. [11] Moxie Marlinspike. IE SSL vulnerability. http: //www.thoughtcrime.org/ie-ssl-chain.txt, 2002. [12] Moxie Marlinspike. Null prex attacks against SSL/TLS certicates. http://www.thoughtcrime.org/papers/nullprefix-attacks.pdf, 2009. [13] Internet X.509 public key infrastructure certicate policy and certication practices framework. http://www.ietf.org/rfc/rfc2527.txt, 1999. [14] HTTP over TLS. http://www.ietf.org/rfc/rfc2818.txt, 2000. [15] Internet X.509 public key infrastructure certicate and certicate revocation list (CRL) prole. http://tools.ietf.org/html/rfc5280, 2008. [16] The Secure Sockets Layer (SSL) protocol version 3.0. http://tools.ietf.org/html/rfc6101, 2011. [17] Representation and verication of domain-based application service identity within Internet public key infrastructure using X.509 (PKIX) certicates in the context of Transport Layer Security (TLS). http://tools.ietf.org/html/rfc6125, 2011. [18] M. Stevens, A. Sotirov, J. Appelbaum, A. Lenstra, D. Molnar, D. Osvik, and B. Weger. Short chosen-prex collisions for MD5 and the creation of a rogue CA certicate. In CRYPTO, 2009. [19] Q. Sun, D. Simon, Y.-M. Wang, W. Russell, V. Padmanabhan, and L. Qiu. Statistical identication of encrypted Web browsing trafc. In S&P, 2002. [20] CVE-2009-4831. http://cve.mitre.org/cgibin/cvename.cgi?name=CVE-2009-4831, 2009. [21] J. Viega and M. Messier. Secure Programming Cookbook for C and C++. OReilly Media, 2007. [22] N. Vratonjic, J. Freudiger, V. Bindschaedler, and J.-P. Hubaux. The inconvenient truth about Web certicates. In WEIS, 2011. [23] R. Wang, S. Chen, X. Wang, and S. Qadeer. How to shop for free online Security analysis of cashier-as-a-service based Web stores. In S&P, 2011.