
|
View Full Version : CGI-BIN security - keeping your files private from other users on your server
Flying Fox 11-21-2000, 08:58 AM I plan on getting a dedicated RH server sometime soon, and I am wondering how you can prevent other users from writing scripts that, say, list the directory structure of a given location outside their "allowed" path or even attempt to copy/move/read files in locations that they really shouldn't have access to.
For example, suppose I have a customer with the home directory of:
/usr/home/customer
and he writes a script that performs a directory listing for /etc/mail and then tries to read in one of those files? How is this prevented, if the script is executed from his account space under /usr/home/customer/httpd/cgi-bin/hostilescript.pl ?
Is it prevented purely by the fact that these files in /etc/mail (or wherever) have a different user group to his ("root" or "admin" say, instead of "customer"), and thus Linux disallows access to them?
How does Apache/Perl know which user id to use to allow access to certain files and not others (both when run from the web and when run from the telnet command line, the former of which is bugging me)?
And what about the possibility of customer A trying to list and then read files from customer B's account space? How does Apache distinguish between users executing a cgi script such as this and prevent a script from customer A accessing files of customer B?
Chris
Félix C.Courtemanche 11-21-2000, 09:21 AM If you use mod_perl or the basic Perl as CGI st up, this is impossible. Since perl run as the Apache ID, it has the potential to read any files that apache has.
However, if you want to protectr your file, you can use a CGI Wrapper (notably suEXE and CGI-WRAP).
These programs basically look at every files that the scripts want to read / write / overwrite and if the owner of these file is different than the owner of the script, an error is displayed.
This is a sword with 2 edges, since it will slow down your CGI execution and will render some scrips useless.
The other solution invoplves giving a dedicated Apache config & process per user's cgi-bin.
you can guess that this is far from optimal as well.
brainbox 11-21-2000, 12:30 PM So this leads me to the question of, can a cgi script be written that would read the entire directory structure of our server, cobalt raq 4i if we turn off cgiwrap? Or must the vandals know a specific file to target? Can they seriously mess up a server? Or only the other virtual sites hosted on said server?
We really want to turn off cgiwrap since it causes quite a few of our customers serious problems since some of their scripts absolutely refuse to run under cgiwrap. Is there a way of turning it off for just a few clients that we know personally?
Thanks,
Bbox
Félix C.Courtemanche 11-21-2000, 12:42 PM It is effectively possible to read any 'public readable' file on your server. That mean that you can dum /etc/passwd but not /etc/shadow
you can write any world writable files, which mena that any files chmoded to 777 are a huge treat. You could ovewritte them, replace the content, then _execute_ it. Do your dirty laundry by someone else... Catch passwords, etc.
If you system is really poorly built, you could screw up everything, yes.
As for disabling only for certain people, you would have to go with cetain apache modules that block everything behind the home directory of a user. You could then use another module to create a 'hole' for certain users.
I don't remember the module names off hand, but I don't suggest using them anyway. I looked into it and they seem pretty hard to configure and you might even have to write certain modules yourself.
This is an area where no-one bothered writing anything, so you are quite on your own.
Travis 11-21-2000, 04:55 PM If you use suEXEC in combination with properly set up permissions, you won't have any problems at all.
We've used suEXEC for 2 1/2 years, and it works great. It's a part of Apache, it's just that a lot of people seem to not know about it. It works completely passively as far as the CGI is concerned, unlike CGIWrap. suEXEC is just called before the script, and most all of what it does is just drop itself to the user's privilege level on the system.
Once a script is running with the user's permissions, it can't do anything they couldn't do with FTP or telnet. If the rest of your system is set up okay, you'll be fine.
brainbox 11-21-2000, 05:15 PM Hmmm, seems a good way to go, I wonder what the cons are of setting up SuEXEC on a cobalt raq, and why cobalt chose cgiwrap instead of SuEXEC? Anyone know?
Think I'll head over to Apache and see the rundown on installing SuEXEC instead of cgiwrap. This would simplify those customers that are experiencing problems with cgiwrap maybe.
Thanks for the heads up
Bbox
Travis 11-21-2000, 05:36 PM I really can't see any good reason why Cobalt uses CGIWrap - matter of fact, I don't see any good reason to use anything besides suEXEC.
The only downside to suEXEC is that it can be a little difficult to get going. Let me know if you have any troubles, and I'll try to help.
Praxis 11-29-2000, 08:44 AM Just run httpd as it's own user!
Just create a user and group named www, and add the --user option to the daemon function invocation in the httpd init script.
Of course, then it can't listen on port 80. But you can set it to listen on, say, port 8000, and use ipmasqadm portfw to map port 80 to 8000 on the same host.
callisia 11-29-2000, 11:15 PM There is not much that can be done for a world readable
file. For most system files /usr/bin /bin etc it is no big deal. For /etc you really don't want to give your configurations away. A partial solution for Linux can be
had with LIDS (Linux Intrusion Detection System) http://www.lids.org. This kernel patch allows for finer grained
access control. So I can do things like allow only
certain process or users to access certain files,devices
or memory. You can effectively cripple root and make it
powerless in the event of a break in. I can make /etc/password readable by only the processes that need it so people can't give away my user list. Allow only processes x,y,x to see the log files so they cant be deleted in a breakin.Its tricky to set up and get right but it works.
I believe the reason for using CGIWRAP instead of suEXEC is simply it is more configurable and flexible. It can be
used transparently in a few ways. Easiest being adding:
ScriptAlias /home/username/public_html/cgi-bin/ /home/httpd/cgiwrap/cgiwrap/username/
to each virtual host.
A more serious problem I believe is how httpd is usually run under a shared uid for a shared system. While suEXEC/CGIWRAP work well for CGI's they don't for apache_modules like php or mod_perl. In non CGIWRAP enviroments people end up making world writable directories for their cgi's and other stupid things. So users in the same machine can write cgi's to mess with other peoples data. As well you can never make the html
tree fully private between users on the machine.
Best solution to this problem as already mentioned is make a httpd server for each user running under their uid. Its really not a pain at all. No more work than administering virtuals. A common base config file and script or two will start up all the servers just as easy as httpd start. Only downside is a bit more memory usage.
brainbox 11-30-2000, 12:38 AM When you say a bit more memory, how much are we talking about, each httpd that I see in the "top" command uses about 4% of the memory, so if you have 200 virtuals on a server that would be a lot of memory. Yes?
Bbox
callisia 11-30-2000, 02:10 AM On my systems its about 1%. For example one machine each process is about 3 MB. Code pages should be shared. This
is where you get your savings. A little more than half is shared and the rest is the extra memory per process (stack etc.). Which is about 1.3 meg. I think the percentage is the total of the paged and resident memory so the actual percentage is actually less. I put
alot of memory in the machines so I guess it doesn't bother me too much. In practice it has worked well so far.
I would image it is very bad for certain situations.
Apache 2.0 seems like it may be a better fit for this
model. Have one process per user and then use threads to
handle requests instead of pre-fork and hopefully save more
memory. What would be real good is if you could somehow
specify different uid's per virtual then have apache prefork one each and serve requests by threads all from the one root process and config.
Have a nice day.
|