Preventing an attacker who has compromised my CGI scripts badly enough to execute arbitrary code from copying the database is exactly the point of a security-in-depth strategy.
Here's the design I'm working with: Apache will run in a chroot jail, with a Unix socket to the SQL server inside the chroot. The SQL server stores its binaries and all of its data outside Apache's chroot. The username and password to log in to the SQL database are sent by the user, and only allow access to this user's own data (implemented using PostgreSQL views).
In this configuration, I don't think that compromising the CGI script will allow the user to copy or delete the entire database (unless it's in conjunction with a kernel bug or an SQL server bug); he will be able to send arbitrary SQL commands to the database, but only with the permissions of the SQL user he's logged in as, which will prevent access to or destruction of data other than his own.
Do you see flaws in this design that I'm missing?
| [reply] |
Do you see flaws in this design that I'm missing?
You're assuming that any compromise of the CGI script only applies to a single user and a single invocation of the script.
If the Evil Hacker can run arbitrary code then this may not be true. For example the compromised script could spin off another process that sits their doing a dictionary attack on your database, badly set permissions could allow the script to rewrite itself, etc.
In some ways a mod_perl server would be more secure. Set it up to only service a single request per-process. You still save on startup time, forks are cheap (definately cheaper than starting up a separate CGI process and loading all the modules needed), and a compromised service would have to restart Apache to affect future requests.
That said, it seems odd to me to be worrying about the database access in this way.
If it were me, and my requirements had me worrying about the possibility of a buggy CGI/mod_perl being compromised, then there is no way in heck I would have direct access to the database on the same box as the W3 server.
You don't need all the database functionality, the Evil Hacker can use it to gain information that you don't need/want to reveal, and you open yourself up to possible security holes in the database layer.
I'd have my W3 server talking to a separate applications server on another box using a very thin application specific protocol that only supplied just enough functionality for the W3 application to do what it needs to do. You hide most database-specific exploits away on the other box, and have something that you can apply fine grained security controls too.
| [reply] |
Thanks for your thoughts, adrianh! Some responses...
For example the compromised script could spin off another process that sits their doing a dictionary attack on your database
That's true, although they could just as well do a dictionary attack on the main site.
badly set permissions could allow the script to rewrite itself, etc.
Which is why I don't intend to set the permissions badly. :)
In some ways a mod_perl server would be more secure. Set it up to only service a single request per-process. You still save on startup time, forks are cheap (definately cheaper than starting up a separate CGI process and loading all the modules needed), and a compromised service would have to restart Apache to affect future requests.
I already have Apache configured to process only one request in each child. As far as speed, it's not an issue; the site will be getting at most dozens of hits a day and will run on modern hardware.
Attacks are possible with a mod_perl script that aren't possible with CGI, since it has access to the listening socket, the scoreboard, and other internal Apache data structures. For example, this bit of mod_perl will intercept some future requests, but isn't possible under CGI:
These are the sorts of attacks I think CGI will protect against.
I'd have my W3 server talking to a separate applications server on another box using a very thin application specific protocol that only supplied just enough functionality for the W3 application to do what it needs to do. You hide most database-specific exploits away on the other box, and have something that you can apply fine grained security controls too.
Ah, that's a great idea! Thanks!
| [reply] [d/l] |
That sounds fairly reasonable if you are very careful about database permissions. Keep in mind that you can run CGI scripts or mod_perl as a specific user with essentially no privileges on the local box. I also like adrianh's firewalling idea.
| [reply] |