The FastCGI Caveat: Web Server Secrets, Part 7

Many servers run their PHP and CGI scripts pre­cisely as I describe above. That is, you and your script are two entirely dif­fer­ent per­sons, so far as file own­er­ship is concerned.

But… what if your script pre­tended to be you? Wouldn’t that sim­plify things? Of course it would. Never again do you have to worry about those sub­tleties of file own­er­ship. What’s yours is yours, and what’s the script’s is yours too.

But… how does the script become you? That’s a very tricky thing to do in Unix or Linux. What’s impor­tant here, is for you to know when this is hap­pen­ing. Why is it impor­tant? Because it makes such a tremen­dous dif­fer­ence to how you set up your file permissions.

Okay, so you need to know if your scripts become you, or not. How do you find out? That’s easy — you ask your server admin. What’s dif­fi­cult, is know­ing what ques­tion to ask. There is no sin­gle cor­rect ques­tion to ask! Like I said, this is a tricky issue in Unix and Linux, and there­fore truly cool.

Ask Your Server Admin

Try ask­ing the ques­tion this way: If I upload a file a file for my PHP or CGI script to edit, does the file need to have 644 per­mis­sion, or 666 per­mis­sion? Unfor­tu­nately, your admin might miss the point of the ques­tion. So, at the same time, ask this sec­ond ques­tion: If my CGI script cre­ates a file, is that file owned by my ftp user id, or is it owned by the Apache server’s user id? If your admin has no idea what you’re ask­ing, con­sider that a clue.

This bit of trick­i­ness has a num­ber of dif­fer­ent names in Unix and Linux; the most com­mon are SuExec and CGI­Wrap­per. For PHP scripts, this is an option of FastCGI. All of these mean that your PHP or CGI script pre­tends to be you.

Remem­ber that if you change servers — such as upgrad­ing to a ded­i­cated server — the answer to your ques­tion will prob­a­bly change, and that means your file and direc­tory per­mis­sions must change too!

Surely I have con­vinced you that using this trick­i­ness would save a whole lot of has­sle? Why do many Unix and Linux server setups not use this trick­i­ness? It’s not a ques­tion of con­ve­nience, but one of security.

Server Secu­rity

It’s time to back up, and think like your server admin. Do you want your server hacked? Of course not! Nei­ther does your admin. Do you want some other idiot on your server bring­ing the thing to its knees, so that your domains become unavail­able? Of course not! Nei­ther does your admin.

There­fore, on a shared server, your admin will do var­i­ous things to pro­tect you from your col­leagues, and to pro­tect your col­leagues from you. This is Unix or Linux, and that means you’re all shar­ing a depart­men­tal computer.

There are two basic approaches to PHP and CGI script secu­rity, and you already know what those are. The first approach says the script is not you, and the sec­ond approach says the script is you. If you under­stand that, you under­stand PHP and CGI security!

Not You

The first approach means you need to have your files and direc­to­ries wide open. For your PHP or CGI script to cre­ate a file, that file’s direc­tory must have 777 per­mis­sion. You can’t get more open than that — there’s noth­ing wider. To edit a file, the file must have 666 (or 777) per­mis­sion. Again, that’s as unse­cure as it’s pos­si­ble to be in Unix and Linux.

Why is this a good thing? Because you only need to make cer­tain files and direc­to­ries vul­ner­a­ble. You can keep the rest of your files untouch­able. Your PHP or CGI script there­fore has very clear-cut bound­aries. It can­not cre­ate new files or edit other files even if it wanted to. It can only touch the places where you have explic­itly given it permission.

The pop­u­lar blog­ging and Con­tent Man­age­ment Sys­tem soft­ware Word­Press, for exam­ple, only requires that the wp-content direc­tory have wide-open permission.

Using this approach, some of your stuff is wide open, but the rest of your stuff is untouch­able. This is a stan­dard (and secure) approach. Of course, you could do some­thing really dumb like this:


find . -exec chmod ugo+rw {} \\;

What have you done? You’ve just made all of your files com­pletely vul­ner­a­ble. Your script can edit them, but so can any­one else who hap­pens to be on your server. On a shared server, this is a prob­lem. On a ded­i­cated server (or vir­tual ded­i­cated server), this is not a prob­lem — until some­one fig­ures out how to hack your script.

Is You

The other approach is for the script to pre­tend to be you. This is the more com­mon approach for a shared server. Do you see the pri­mary reasons?

I’m sure you see the first rea­son… if you’re on a shared server, you’re likely to be less expe­ri­enced. You’d prob­a­bly rather not be both­ered with the com­plex­i­ties of Unix or Linux own­er­ships and per­mis­sions. Your PHP or CGI script pre­tends to be you, and every­thing works the way you would expect.

The other rea­son is more sub­tle. You’re forced to be a good neigh­bor. Have you con­sid­ered mess­ing with your neighbor’s files, either by acci­dent or on pur­pose? Can you pop into the server via ftp, and mess with the other guy’s files? Of course not — you don’t own them. And now, nei­ther can your PHP or CGI script, because the script is no more (and no less) priv­i­leged than you are.

Con­sider the other sit­u­a­tion — that is, when the script does not pre­tend to be you. It does not pre­tend to be your neigh­bor either. If you both run PHP or CGI scripts, you both need to leave cer­tain files and direc­to­ries wide open. And, there­fore, you are vul­ner­a­ble to each other.

There­fore, rather than leave you vul­ner­a­ble to your neigh­bors, your server admin will prob­a­bly con­fig­ure the Apache server in such a way that your scripts pre­tend to be you. Your neighbor’s scripts pre­tend to be him, and there­fore can’t mess with your stuff.

On a ded­i­cated server, you don’t need to worry about mali­cious neigh­bors. You’re the only user of the server. There­fore, the first approach makes more sense. The script does not pre­tend to be you, and there­fore you can limit its access to only cer­tain files and directories.

On a shared server, your greater dan­ger is from your neigh­bors — remem­ber­ing that your neigh­bor could be a vic­tim of a hack­ing expe­di­tion. It makes more sense for your scripts to run as if they were you, side­step­ping those per­mis­sions prob­lems, and keep­ing you out of your neighbor’s stuff.

Warn­ing

Unix (and there­fore Linux) and arro­gance go together. Larry Wall, the cre­ater of Perl, calls it hubris, and declares it to be a manda­tory trait. A gen­er­a­tion ago, the stan­dard answer to any Unix ques­tion was “read the man page.” It may take you sev­eral days to fig­ure out which man page to go read; that fact was both assumed and expected. No self respect­ing Unix guru will waste his time with some­one inca­pable of fig­ur­ing out which man page to read; and all Unix gurus are self respecting.

Don’t be put off by the arro­gance and con­de­scen­sion of this arti­cle. I was por­tray­ing the atmos­phere tra­di­tion­ally endemic to all Unix and Linux dis­cus­sions. You do not, of course, need to put up with the hubris. Instead, just read the man page.