The Problem:
I find a lot of surprising security problems as I work on client’s sites. Even large, reputable companies often have gross security issues. I know more than anyone how difficult it can be to get a cgi script installed and working. It’s tempting to walk away without double-checking the security. One of the most common things that I see is poor security of the cgi-bin. Depending on the setup of your server, someone can take total control of your account easily through a poorly secured cgi-bin.
The particular problem i’m writing about involves writable files/directories within your cgi-bin, or scripts that make calls to external programs (like sendmail). These are both very common types of scripts that you would find in just about any cgi-bin.
The writable file issue is that most cgi scripts rely on a datafile to store their information. In some cases, they need an entire writable directory to store data (file uploads, etc). The tricky part is that you have to allow the script write access to the file/directory. If your server is running as “nobody” then you need to allow world write access to the file. This is dangerous because other users on the server also have the ability to run under the “nobody” user - which means they can also write to those files. Some servers are configured so that scripts execute under your own userid. Otherwise sensible people are fooled into thinking that they are protected by this. Although it does protect you from the “nobody” exploits, it actually make the potential damage much worse if you have poor security settings.
The issue with scripts that make calls to external programs (like Formail for sending email via sendmail, etc) is that if they are not coded properly, someone can input malicious text that causes an arbitrary shell command to run in addition to the sendmail command. This command will run under whatever userid that the original script has.
One dangerous situation is a script that allows file uploads and it’s writable directory is in the cgi-bin. Any script like this should have serious security checks in place to prevent malicious files from being uploaded. If the script doesn’t check file types as they upload, any anonymous user can upload a script or executable file right to your cgi-bin.
Another situation is on a virtual host where you share your account with lots of other users. This exploit is only available to people who have an account on your machine, however it is no less a problem. All users on your server can install cgi scripts in their account which run under the “nobody” permissions. If they install a simple command processing script, they can manipulate any file in your account that allows world write access.
So, take a look at your cgi-bin and look for any writable files or directories. Imagine what would happen if someone could edit or add any file there in your cgi-bin. A writable directory is particularly bad because the other person on your server can actually write a new script file there and then browse to the url to execute it.
Normally if someone can totally compromise your site in this way, they are limited to running as the user “nobody.” However, there is still quite a bit of damage that can be done. Formmail scripts can be installed to send spam. Scripts to snoop into your datafiles can be installed. Large files can be uploaded and shared (using your bandwith). I once had a client who incurred a $10,000 bandwidth bill after their server was compromised by hackers sharing video game software. Nothing more than “nobody” access is needed to do this.
If cgi-wrap is enabled, the situation is compounded because the scripts in your cgi-bin can be executed through cgi-wrap to run under your own userid. At that point, they own your account.
How To Secure cgi-bin:
There’s a few simple things that can help lock down your cgi-bin.
1. Never, ever have a file with both world-execute and world-write permissions. This can be overwritten with any arbritrary code by any user on your server. Once they overwrite, they can execute it through the browser. Scripts themselves should never require write permission. Read/Execute is fine (chmod 505 is nice and secure).
2. If possible, never have any writable directories or files in the cgi-bin. Not even writable by your own user id. there is no reason that a file needs to be writable within the cgi-bin. Depending on what scripts you have installed, this can be challenging. The solution is to move all datafiles to an area that is not accessible through the web browser. If this is not possible, see # 3
3. If you must have writable files or folders in the cgi-bin because of the functionality of a script, keep them in a subdirectory and put an .htaccess file in there that has the contents “deny from all” in it. Your scripts can still read/write files there, but nothing can be executed through the browser. if you are not able to put them in a separate directory, you can deny access to specific files using .htaccess.
4. Never give any permissions to the “group.” In UNIX you have three permissions to grant - owner, group, world. for example, chmod 644 grants 6 (rw) to owner, 4 (r) to group and 4 (r) to the world. The group is almost always other accounts on your server. You generally do not know these other users and there is no reason to give them any permissions for any file in your account. The middle value should always be zero. for example: chmod 604 gives the group 0 (no access) which is fine.
5. be very careful when cgi-wrap is enabled or your cgi-bin executes using your own account’s userid. in this case you have to make sure that nothing can be written arbitrarily into your cgi-bin even using your own account permissions. Keep in mind that you do not need permission to write to a script. You can remove the write permission even for yourself. If you need to change it later, you first change the permission to allow write, then change it back. It doesn’t need to sit there with write permissions. You have to be very cautious about what scripts are installed, because any script with an exploit can be dangerous. if someone can write or upload to your cgi-bin, they can create their own script and run it under you userid. If you use cgi-wrap, there is no reason for the group or the world to have any permissions on your files. so, you should change permissions something like this: chmod 400 (only you have read permission). scripts can be chmod 500. writable datafiles can be chmod 600, but should not be stored in a public area. remember that if someone can run arbitrary code as your userid, they own your account!
6. Try to break into your own account. Go through your scripts and try to upload a file that shouldn’t be allowed. Look at scripst that send email and see if you can enter data in such a way that code gets executed.
Summary:
The moral of the story is to be cautious with your cgi-bin. Especially look for writable files and directories. Never trust other users on your server. It may not seem important to take security seriously for your homepage with a bulletin board and formmail script. But there are malicious people out there always scanning for easy targets. Your data can be compromised or your bandwidth stolen - leaving you with the bill. A little bit of extra time can save you a lot of grief later.
Share This