On Thu, June 23, 2005 7:42 am, Jack Jackson said: > I cannot see a way to validate or examine Word or Excel files for > validity (and assume that older word files would validate differently > from newer ones).
If your PHP does not have the mime_type functions, you could probably use http://php.net/exec with the "file" utility which does much the same thing under Un*x-like systems. "man file" on the command line for more info. > The PEAR http upload script mentioned twice in the user notes at that > manual page does not *seem* to validate other than denying certain > extensions like php, php3, etc. I could be wrong of course. Does it catch .asp, .cgi, .pl, .htm, .html, .jpg, .png, .gif, .jpeg, .pdf, and .swf? Cuz at certain directories on *my* server, those are all PHP scripts! Well, okay, .pl and .cgi aren't. Actually, I think I still have a .cgi somewhere that *is* a PHP script... It's equally dangerous either way. Maybe someday they will be on your server, too, once you run into the zillion IE bugs where the URL counts for more than the Content-type: header. It's really Bad Practice to rely on the last N characters of a filename as some kind of Security Measure to stop a serious attack... > Also, it seems that directories must be blown wide open (777) to allow > the script to copy the file over from /tmp. My ISP won't allow > directories to be set to 777 under public_html/ -- but we need to access > the files via web browser which is the whole point. Well, requring 777 just plain sucks... You *should* have a directory writable by the PHP user/group as the minimum requirement. If PEAR really and truly requires 777, then that feature of PEAR sucks, and you shouldn't use it. Sorry, PEAR guys. Gotta call 'em as I see 'em. And if the best it can do is outlaw .php .php3 ..., then that ain't much either. I'd rather code it myself than have that weak of a safety. > So my questions: > 1. How do you validate Word and Excel files before upload? You don't. Any validation done before upload is done on the client, and is therefore something that can be easily bypassed by the savvy user. It might be useful as a User-Interface feature to catch obvious stupid mistakes by honest folk... But it's USELESS as a Security Measure to stop Bad Guys. Oh yeah: You may need to use move_uploaded_file to move the files to a staging area before you use exec/file on them... At least, under *MY* webhost's setup, I can't directly read PHP uploaded files from /tmp, even though PHP can move_uploaded_file() them... That may have been changed/fixed, but it's a possible configuration issue. So, use move_uploaded_file to let PHP do its checks, but put stuff in a staging area that the PHP user can read/write, and is *NOT* in the web-tree. Then, do all of YOUR checks. getimagesize, exec("/usr/bin/file $file"...) etc. If that all passes, move the file (again) to its final destination, which should *still* be out-side the web tree on most shared servers. Write a PHP script that only allows files already listed in your database to be served up, and which readfile's the data from outside the webtree to spew it out. *IF* you are on a dedicated server, or *IF* your webhost has a unique UID/GID for you to have directories that no *OTHER* user on that webhost can write to your PHP-writable directories/files, *then* it is probably/maybe just as safe to put stuff in your webtree as to readfile it from outside the web tree... Even then, I'd only do the direct to webtree if performance was a major issue. It just doesn't make sense to me to let untrusted users put stuff in the webtree where they might manage to trick the server into executing it as Perl, PHP, JSP, ASP, or [deity] knows what code to do Evil things. It's gonna be a lot tougher for them to fool PHP's readfile into executing code. Hell, if they can do that, they already own your server. > 2. How can I make a passthrough from a file above public_html to one > below it so that people can surf in with a browser and download files > which have been uploaded by the script? There's an easy one. :-) Put the files *OUTSIDE* your webtree. Then write a PHP script that takes an ID of a valid uploaded file that your previously stored in your database, looks up the path to that file, and use http://php.net/readfile on it. You were real close with passthrough which is http://php.net/passthru which is kind of the same, only not. You'd only put files in the webtree if PHP readfile proved too slow, *AND* you were sure no user on the box could ever manage to infiltrate a damaging file into the webtree... That second one is a pretty Tall Order... I can see somebody justifying it, but, honestly, if the overhead of readfile is that big of a deal, then maybe you're living too close to the edge on performance in the first place, and it's time to buy more/better hardware anyway. So, in MY opinion, you should NEVER put uploaded files from untrusted users in the webtree. Sure, if it's the site's "admin" user or some trusted user who you have a Reasonable Expectation that they simply wouldn't upload Bad Stuff, putting in the webtree isn't quite as bad... But you have to consider the ultimate source of the content. Are they just uploading what somebody else sends them for a headshot? You really think there isn't somebody out there that couldn't generate a reasonable-looking headshot that, if passed through PHP, would do Bad Things on your server? Jeez, I think even *I* could manage that. Throw some PHP code into the Comments section. If they can manage to get that file to end up in a directory of PHP scripts that generate GD images, and those scripts end in .gif to fool the broken IE browsers as some of mine do, it could be Game Over. Maybe this can't happen on your server today, but can you guarantee you'll NEVER have sombody playing around with GD and using ForceType to solve the IE bugs? Put it outside the webtree and use readfile, and you can't go wrong. -- Like Music? http://l-i-e.com/artists.htm -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php