Re: [PHP] Re: Strategy for Secure File Storage
Kevin Murphy wrote: The problem is IE7. All browsers work with this code as is but IE says Internet Explorer cannot download test.pdf from XXX The problem with IE was when you told it not to cache the document. If you just want the browser to download the file rather than let the Adobe plug-in handle it, as it looks like you intend with the Content-disposition set to attachment, you have to send just the right headers to make IE happy. (I think Brian's example should do it.) Otherwise, IE knows it can handle the document internally with a plug-in and will still try to open the file anyway. For some reason when IE tries to handle files like PDF, it downloads the file, saves it to cache, and then tells the Adobe plug-in to open the file from the cache. Since you've told IE not to cache the file, IE honors that request -- it builds the cache filename (and may even save the file before promptly deleting it) and then sends that file name to the Adobe plug-in which then tries to open a file that does not exist in your computer's local cache. On 9/24/07, brian [EMAIL PROTECTED] wrote: echo 'Your software provider sucks eggs. Get a better browser.'; LOL. I love that approach, too. Unfortunately, it's not very practical. :-\ -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
[PHP] Re: Strategy for Secure File Storage
Kevin Murphy wrote: $ext = explode(.,$file); $extension = $mimetypes[$ext[1]]; Other people have provided answers so I'll just make a quick comment on this bit. It's not ideal but if you only upload a subset of file types then I guess it's OK. Also if the file has more than a single dot in it (e.g. my.image.jpg) which is perfectly valid, then $ext[1] will contain (image) which isn't right. If possible use e.g. http://www.php.net/manual/en/function.mime-content-type.php or Example 606 here http://www.php.net/manual/en/function.finfo-file.php but these may not be available on your PHP install. You should probably check more thoroughly: e.g. $mimetype = 'application/octet-stream'; // default $ext = array_pop($dummy = explode('.', $file)); if (!empty($mimetypes[$ext])) $mimetype = $mimetypes[$ext]; or something similar (not tested above!) Hope this helps ya. Col -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
[PHP] Re: Strategy for Secure File Storage
Kevin Murphy wrote: 1) Write secure files to MySQL as a blob (only secure files would be written there) Personally I don't like this strategy but it is always a hot topic on this list. I don't mind storing a few small images in the db but when you start to store 200-300Megs it just complicates your database backup strategy. If you use snapshot-based filesystem level backups (e.g. using LVM) then this is mitigated but still has many downsides IMO. 3) Use Unix passwords to protect a folder in the web level and then the CMS knows the password and can pass the password for access (so that the user doesn't know this password, but the CMS does). Nah... seems to complex. 4) Some various forms of link obfuscation, where the CMS goes through all the secure files once an hour or so and rewrites the file name with a random string. Still not 100% secure and overly complex IMO. 2) Write secure files to the level below the web root and come up with a way of copying the files over to a temporary directory for access, then delete the files as soon as they are accessed. 5) Or I'm open to suggestions. I think you are kind of on the right track with 2 but there is no need to do this copying. Simply put all requests for your file through a PHP script. This can be done with PATH_INFO or mod-rewrite in Apache (just google this for examples. You PHP script will then check the access credentials of the user (e.g. a logged in Session) and then output relevent cache headers (again google) before issuing a Content-Type header with the correct mime type for the file in question along with the Content-Length header with the physical size of the file (not strictly speaking necessary but nicer for the client) before simply calling include('/path/to/file/not/in/webroot.ext') to push the content to the user. Hope this helps. Col -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Re: Strategy for Secure File Storage
Ok, I'm almost there. I took what everyone said (and a few Google searches later) and built this, which works great on Firefox and Safari (both mac and PC). The $path leads to a directory outside the web root, and there is also an array with all the mime types in it ($mimetype). $file_path = $path./.$file; $ext = explode(.,$file); $filesize = filesize($file_path); $extension = $mimetypes[$ext[1]]; header(Content-type: $extension); header(Content-length: $filesize); header(Content-Disposition: attachment; filename=\$file\); header(Pragma: no-cache); $file = file_get_contents($file_path); echo ($file); The problem is IE7. All browsers work with this code as is but IE says Internet Explorer cannot download test.pdf from XXX Any suggestions? -- Kevin Murphy Webmaster: Information and Marketing Services Western Nevada College www.wnc.edu 775-445-3326 P.S. Please note that my e-mail and website address have changed from wncc.edu to wnc.edu.
Re: [PHP] Re: Strategy for Secure File Storage
Kevin Murphy wrote: Ok, I'm almost there. I took what everyone said (and a few Google searches later) and built this, which works great on Firefox and Safari (both mac and PC). The $path leads to a directory outside the web root, and there is also an array with all the mime types in it ($mimetype). $file_path = $path./.$file; $ext = explode(.,$file); $filesize = filesize($file_path); $extension = $mimetypes[$ext[1]]; header(Content-type: $extension); header(Content-length: $filesize); header(Content-Disposition: attachment; filename=\$file\); header(Pragma: no-cache); $file = file_get_contents($file_path); echo ($file); The problem is IE7. All browsers work with this code as is but IE says Internet Explorer cannot download test.pdf from XXX Any suggestions? echo 'Your software provider sucks eggs. Get a better browser.'; heh ... I just did precisely this (the script, not the sucks eggs comment) for a project i'm working on. There's a file store above document root and a script that does user validation, then reads the top dir of the file store and display links for each directory or file in there (of course, they're not direct links), letting the user drill down as far as it goes. What exactly is in the var $extension? header(Content-type: $extension); Don't do this: $file = file_get_contents($file_path); echo ($file); Do this instead: readfile($file_path); exit; Here's the business end of my script: -- snip -- header ('Cache-Control: must-revalidate, post-check=0, pre-check=0'); header ('Content-Type: application/octet-stream'); header('Content-Transfer-Encoding: Binary'); header('Content-length: ' . filesize($filepath)); header('Content-disposition: attachment; filename=' . basename($filepath) .''); readfile($filepath); exit; -- snip -- Note that i'm not trying to give the option for the browser to hand off the file to a helper application or plugin. This script is for downloading only, hence no MIME type and the octet-stream' 'attachment'. I just checked another project where i did pass the MIMIE to allow for the file to open in Adobe Reader, MSExcel, etc. You also might want to add these two with your no-cache header: header ('Expires: Mon, 1 Apr 1974 05:00:00 GMT'); header ('Last-Modified: ' . gmdate('D,d M YH:i:s') . ' GMT'); I seem to remember that it was IE that wanted these in order to play nice. brian -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php