For anyone running an e-commerce web site, the term PCI compliance is unlikely to escape the owner’s or developers attention. In essence, if a web site is handling credit card data, regardless of whether they store that data, the web site must be PCI compliant.
For a web site to be compliant, it must pass a rolling three month test by an authorised PCI scanning vendor. There are many out there and from my experience they are not all equal. Some vary with the features they offer but the interesting one is that not all of them return the same vulnerabilities. As a developer, the vulnerability report is key to helping identify and resolve any issues, so I find it surprising when a scanning vendor provides the solution but not the steps to help reproduce the issue or a link on how to resolve. Anyways, to help out here I’ve found that Apache vulnerabilities pop up more than most and so I will address some of these raised issues and present the resolutions.
To help you get a head start; or if you already have a PCI vulnerability report to resolve with some identified Apache vulnerabilities then hopefully the following tests and fixes will help.
Please note that the ‘openssl s-client’ command is part of the openssl package.
Verify your site doesn’t accept connections using SSLv2
SSLv2 has a number of security vulnerabilities which is why SSLv3 was developed. In fact most modern browsers have dropped support for it. If this vulnerability is raised after a PCI scan it may appear along the lines of:
SSL Version 2 (v2) Protocol Detection https (443/tcp)
To test your site to see if SSLv2 connections are accepted, at the terminal run:
$ ~> openssl s_client -port 443 -host example.com -ssl2 CONNECTED(00000003) 677:error:1407F0E5:SSL routines:SSL2_WRITE:ssl handshake failure:/SourceCache/OpenSSL098/OpenSSL098-35/src/ssl/s2_pkt.c:428:
The result above shows that a connection was made, but SSLv2 encryption could not be established. Any kind of failure message here is a positive result. What you don’t want to see is a screen’s worth of connection information that includes the display of your server certificate.
If an SSLv2 connection was successfully established then in the Apache config file add the following setting and restart the server:
SSLProtocol all -SSLv2
This will then tell Apache to accept all SSL protocols except SSLv2. SSLv1 was never publicly released.
Verify your site doesn’t accept SSL connections using weak cyphers
A vulnerability report may raise an issue along the lines of:
SSL Weak Cipher Suites Supported https (443/tcp)
To test if a site accepts these weak SSL cyphers, at the terminal run:
$ ~> openssl s_client -connect example.com:443 -cipher LOW:EXP CONNECTED(00000003) 731:error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure:/SourceCache/OpenSSL098/OpenSSL098-35/src/ssl/s23_clnt.c:596:
Again, any kind of failure message like the command output above would be regarded as a success. Seeing lots of connection detail that includes the server certificate would indicate that the server does accept these weak SSL cyphers and needs to be disabled.
In the Apache config file add the following and restart the server:
Verify your site doesn’t accept trace requests
Trace requests allow for the debugging of connections to the server and are required to be disabled. A vulnerability report may raise an issue along the lines of:
HTTP TRACE / TRACK Methods Allowed http (80/tcp)
CVE-2003-1567, CVE-2004-2320, CVE-2010-0386
An example of a successful trace request is as follows:
telnet example.com 80 Trying 172.16.0.1... Connected to example.com. Escape character is '^]'. TRACE / HTTP/1.1 Host: example.com HTTP/1.1 200 OK Date: Mon, 06 Jun 2011 13:45:03 GMT Server: Apache Transfer-Encoding: chunked Content-Type: message/http 38 TRACE / HTTP/1.1 Host: example.com 0
On the flip side, a failed trace request looks as follows:
telnet example.com 80 Trying 172.16.0.1... Connected to example.com. Escape character is '^]'. TRACE / HTTP/1.1 Host: example.com HTTP/1.1 405 Method Not Allowed Date: Mon, 06 Jun 2011 13:50:36 GMT Server: Apache Allow: Vary: Accept-Encoding Content-Length: 223 Content-Type: text/html; charset=iso-8859-1 405 Method Not Allowed <h1>Method Not Allowed</h1> The requested method TRACE is not allowed for the URL /.
Within the Apache config file add the following line and restart the server:
Putting it all together
Taking all the tests above, these can be knitted together and packaged into it’s own config file and included by Apache. This approach will ensure that these settings are applied to every site the Apache server is hosting. To do so simply create a file called pci-compliance.conf and ensure Apache loads this. On Ubuntu, simply drop this into the /etc/apache2/conf.d/ directory. Or, you can add these to an individual site’s vhost configuration.
<IfModule mod_ssl.c> # Disable acceptance of weak SSL ciphers SSLCipherSuite HIGH:MEDIUM:!ADH # Disable any connection attempts using SSLv2 SSLProtocol all -SSLv2 </IfModule> # This directive controls whether the server response header field, which is # sent back to clients, includes a description of the generic OS-type of # the server as well as information about compiled-in modules. # See http://httpd.apache.org/docs/current/mod/core.html#servertokens ServerTokens Prod # Disables the footer on server-generated documents, hiding the version of # Apache being used. # See http://httpd.apache.org/docs/current/mod/core.html#serversignature ServerSignature Off # Disable the trace method so attackers cannot intercept the session ID TraceEnable off
Associated image “Padlock & Chain” by Tim Haynes, available under an Attribution-NonCommercial-NoDerivs 2.0 Generic licence.