Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

File uploads 1

Status
Not open for further replies.

jet042

MIS
Dec 23, 2002
258
US
I wrote a site for our internal users to upload files from clients over an SSL connection (as opposed to using FTP or e-mail to move these files). However, as always seems to happen, management now wants to allow clients to use the site as well. So, to that end, I need to shore up it's security a little bit. One thing that I want to do is limit the type of file that is uploaded, but everywhere I look I see people saying this is really difficult. I know you can't trust anything that is sent by the client, so how do I verify that that file sent up is either a PDF or Excel document?

Just to clarify, I don't have these files stored anywhere near the web doc root and I re-name all of them using a random number generator, so they can't be directly accessed. That's harder to explain to a sales manager, though, than just saying you can't upload anything but the allowed types and then prove it to them.
 
Well, you could use $_FILES['userfile']['type'] as described here
or

You could use $_FILES['userfile']['name'], separate the extension off and check on the file extension
Code:
$name=$_FILES['userfile']['name'];
list($base,$ext)=explode(".", $name);
$ok=stripos('pdf~txt~doc', $ext);
if ($ok === false && $ext != '')
{
  code to recject document ...
} else {
  code to process document ...
}

Hope this helps!



--
SouthBeach
The good thing about not knowing is the opportunity to learn - Yours truly, 2008.
 
The problem with both of those is that they can be spoofed or faked by a malicious client. They're definitely good first steps, but if I'm going to do something, I want to do it all the way, you know?
 
I do not know about $_FILES['userfile']['type'] been spoofed since it uses MIME to determine file type.

Just run a couple of tests and see what happens. I mean, take a binary file and rename it giving it a .xls extension; upload the document and see what $_FILES['userfile']['type'] comes back with.

In the same token, if you are so concerned about this, place the files in a quarantine directory where they would not be able to execute out of, write a second process to move out of quarantine once you have determined the file is safe. How do you determine if the file is safe? By hands on intervention.



--
SouthBeach
The good thing about not knowing is the opportunity to learn - Yours truly, 2008.
 
MIME type is sent by the browser and PHP does not verify it (they say so in the page you linked), so it can't be trusted any more than user input into a form.

I already do place the files in a directory where they're not going to be executable. I also re-name them (as I mentioned before) so they can't be called. Files are recovered using the same site, but through a different process and they are always taken down in a zip archive (again, no chance for execution).

All of that aside, I've still been asked to limit what files can be uploaded, so that's what I have to do. I'm kind of viewing this as a learning experience as well, hence the extra effort.
 
use something like this

Code:
function returnType($file){
    $finfo = finfo_open(FILEINFO_MIME); 
    $return = finfo_file($finfo, $file);
    finfo_close($finfo);
    return $return;
}
 
Thanks, jpadie. This looks like it will work, but it's pretty difficult to get running under Windows 2K3 and IIS6 with PHP 5.2.5. For anyone who searches for this later, here's how I did it.

1) Get "php_fileinfo.dll" from and put it in root path\PHP\ext\
2) Get the four mime files from and put them in your PHP root. Grab "file-4.23-bin.zip" and extract them from share/file in the archive.
3) Enable php_fileinfo.dll in php.ini by adding the line "extension=php_fileinfo.dll"
4) Re-start IIS

To test, use this script:

Code:
<?php

$finfo = finfo_open(FILEINFO_MIME, "[COLOR=blue]root path[/color]\\PHP\\magic");
$filename = "[COLOR=blue]web root path[/color]\\finfo_test.php";
echo finfo_file($finfo, $filename);

?>

The output should be "text/plain; charset=us-ascii" or similar.

You do need to explicitly list the path to the magic files, but leave off any extension (this is not very clear in the documentation).
 
did you try just using pecl?

Code:
pecl install --alldeps fileinfo
 
@jpadie: I haven't. If I end up needing to get this installed on another server I'll give that a shot.

Unfortunately, this doesn't look like it will work for me at this point either as the magic mime databases available from the sourceforge link above don't have entries for Excel spreadsheets. I'm going to look for some different mimes somewhere else.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top