Wednesday, December 11, 2013

Apache mod_ssl misconfiguration

I was doing some cleaning on my Apache server, and I disabled a old website in a VirtualHost that was using an SSL connexion on port 443.

After doing so, I was about to finally load my SSL certificate for and I tried to access the IP directly in order to do some test.

I got an SSL error, and said to myself "it's OK I haven't configured the SSL certificate yet".. but then I looked at my screen and saw the famous

Index of /

of shame as seen on Google.

I was shocked to see the whole content of /var/www listed underneath. All of it. As many people, I use that directory to put my web sites and sometime leave backup files hanging around.

I rapidly understood what was going on, and I was trying to find where in the config this is done.

In /etc/apache2/ports.conf I saw a normal Listen directive on ports when mod_ssl is enabled :

<IfModule mod_ssl.c>
    # SSL name based virtual hosts are not yet supported, therefore no
    # NameVirtualHost statement here

But I couldn't find a "DocumentRoot /var/www" that would cause the insecure behavior I have seen. After all, if you lend on an index page, that index must be pointed on somewhere.

The only place I found /var/www was in some default config that wasn't even loaded.

I fetched the source code of Apache 2 en then did a quick search for it and it turned out that the DocumentRoot is set per distribution or port of Apache and made somewhat default in the package. In my Debian version, considering all the configurations it is /var/www in the end.

If you listen to a port, Apache will respond to it with this default configuration.

How to avoid this in the future? Here's some possible solutions.

Solution #1 

One solution could be to leave the default-ssl VirtualHost enabled and change the DocumentRoot, because by default it is /var/www :

<IfModule mod_ssl.c>
<VirtualHost _default_:443>
        ServerAdmin webmaster@localhost

        DocumentRoot /var/www
        <Directory />
                Options FollowSymLinks
                AllowOverride None
        <Directory /var/www/>
                Options Indexes FollowSymLinks MultiViews
                AllowOverride None
                Order allow,deny
                allow from all

        ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
        <Directory "/usr/lib/cgi-bin">
                AllowOverride None
                Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
                Order allow,deny
                Allow from all

On my server I have a /var/www/default/ web site that contains only a blank index.html file, and I use that as DocumentRoot.

That way, if a SSL port is open (by the same thing apply to _default_:80), you can serve a page. By default the config uses a snakeoil certificate to handle SSL. It gives a self-signed warning but it works.

Solution #2

There's a file named /etc/apache2/conf.d/security that is suppose to force you to be secure with serving directory.. but on Debian it is disabled by default...

# Disable access to the entire file system except for the directories that
# are explicitly allowed later.
# This currently breaks the configurations that come with some web application
# Debian packages.
#<Directory />
#       AllowOverride None
#       Order Deny,Allow
#       Deny from all

If you do that, you need to have an Allow directive in each vhost that are serving. This will prevent any misconfiguration of unwanted exposition of folders.

Solution #3

Add a DocumentRoot at the top of your config. It could be in a conf.d/ file, or in httpd.conf/ports.conf. apache2.conf will probably be overridden in a future update and if ports.conf is, server will stop listening to the right ports and you will notice the change.

# /var/www leak paranoia
DocumentRoot /var/www/default

With that solution, any 443 ports listening but not SSL configured will be answering in plain HTTP with the default site. It is ugly, but if you disable the default site in solution #1 it will still protect yours /var/www.

Scanning for problems

If you want to check if your server is affected by this misconfiguration, first, review all Listen configuration lines. They are suppose to be in /etc/apache2/ports.conf but can be elsewhere :

grep -ri Listen /etc/apache2/
/etc/apache2/ports.conf:    Listen

And then just copy paste the IP:port it in your browser.

If you see :

Bad Request

Your browser sent a request that this server could not understand.
Reason: You're speaking plain HTTP to an SSL-enabled server port.
Instead use the HTTPS scheme to access this URL, please.

Apache/2.2 Server

you are connecting to a SSL port in plain HTTP, so try https:// before and see what respond.

But if you see :

Index of /

[ICO]NameLast modifiedSizeDescription

[DIR]mywebsite/16-May-2013 17:11-

Apache/2.2 Server

You are in trouble, especially if you there's a tar.gz backup of your site in here, or a mysql dump. Also, maybe your Apache will serve the source code of your applications instead of running them, that depends on your configuration.

No comments:

Post a Comment