Serious security flaw in WHM/cPanel – symlinks and .htaccess can be evil

From lxadm | Linux administration tips, tutorials, HOWTOs and articles
Jump to: navigation, search

WHM/cPanel is one of the most successful web hosting control panel. Especially popular among shared hostings, it came to me as a surprise that it lets you read files which belong to other users, including those containing database credentials (like, the whole contents wp-config.php belonging to other user’s WordPress installation, or configuration.php, being yet another user’s Joomla config file).


To do it, create a directory in your public_html directory – let’s name it symlinked. Then, add a .htaccess file with the following content:

Options all DirectoryIndex blah.html AddType text/plain .php AddHandler server-parsed .php AddType text/plain .html AddHandler txt .html Require None Satisfy Any As you can see, it disabled parsing of PHP files of in any directory below.

Our next step will be creating a symbolic link to / – so, /home/youraccount/public_html/symlinked/rootdir should be a symbolic link pointing to /.

Voila! Now navigate to http://your-website/symlinked/rootdir/home/otheraccount/public_html/wp-config.php and you will see the whole file belonging to other user, in plain text.

The flaw in WHM is possible with PHP 5 handler being set to suphp and Apache suEXEC set to on. Both settings are default for WHM. Because AddType/AddHandler directives in the .htaccess file disable executing of PHP code, we’re able to view the content of PHP files, instead of executing them. And because executing of PHP code is disabled, Apache no longer errors when reading PHP files owned by other users.

I was not able to reproduce this issue with apache2-mpm-itk (unfortunately WHM does not support it).

The fix? If you have a website on shared hosting, you can protect yourself by adding similar directives to your .htaccess file:

RewriteEngine On
RewriteCond %{HTTP_HOST} !^www.example.com
RewriteRule (.*) http://www.example.com%{REQUEST_URI} [R=permanent,L]
If you’re shared hosting owner, you’re in trouble, as there is no simple fix for that.

Quick fix can be that:

#!/bin/bash
 
# changes the permissions to user-readable only
ACCOUNTS=$(ls /home/*/public_html -d | awk -F/ '{print $3}')
 
for ACCOUNT in $ACCOUNTS; do
    find /home/$ACCOUNT/public_html -name \*\.php | xargs -I file chmod 600 file
    find /home/$ACCOUNT/public_html -type d | xargs -I file chmod 755 file
    chmod 750 /home/$ACCOUNT/public_html
done

This makes PHP files user-readable only, so this hack no longer works for viewing the source of the files. The way WHM configures Apache, other files must be world-readable – a flaw which wouldn’t exist if WHM used Apache MPM-ITK.

Other options are discussed here:

https://forums.cpanel.net/f185/solutions-handling-symlink-attacks-202242-p23.html#post1397221 – recompiling Apache and enabling mod_ruid2 is recommended.