Startseite > Security > Securing your PHP file upload scripts

Securing your PHP file upload scripts

2011/01/14

Since there is not much documentation on this topic i want to give you some suggestions about how to handle file uploads in PHP. This tutorial will just describe how to identify file formats and size.

First of all you may want to allow only certain file formats to be uploaded. Allowing the upload of PHP/html/etc. files is a really BAD idea since it can get you owned in just a few seconds. 🙂

So the first step is to create a WHITELIST of file formats allowed to be uploaded. Please note that you still can’t trust the file content, it can still contain anything.

File extensions (like .exe, .com, .txt and so on) can be easily changed, don’t rely on them solely. A good alternate way to identify file formats is by the so called „magic number“ which is just a 2-byte (or longer) identifier at the beginning of a file.

What wikipedia says about magic numbers:
http://en.wikipedia.org/wiki/File_format#Magic_number

a short overview of different magic numbers in files:
http://en.wikipedia.org/wiki/Magic_n…mbers_in_files

Now some sample code..
Here the magic number will be checked to allow only files in the libpcap format.

as http://wiki.wireshark.org/Development/LibpcapFileFormat says about the libpcap file header:

Code:
  typedef struct pcap_hdr_s {
        guint32 magic_number;   /* magic number */
        guint16 version_major;  /* major version number */
        guint16 version_minor;  /* minor version number */
        gint32  thiszone;       /* GMT to local correction */
        guint32 sigfigs;        /* accuracy of timestamps */
        guint32 snaplen;        /* max length of captured packets, in octets */
        guint32 network;        /* data link type */
} pcap_hdr_t;

magic_number:
used to detect the file format itself and the byte
ordering. The writing application writes 0xa1b2c3d4 with it’s native
byte ordering format into this field. The reading application will read
either 0xa1b2c3d4 (identical) or 0xd4c3b2a1 (swapped). If the reading
application reads the swapped 0xd4c3b2a1 value, it knows that all the
following fields will have to be swapped too.

..so we just have to check for:

PHP Code:

if ( is_uploaded_file ( $_FILES['file']['tmp_name'] ) )
{
print 'uploaded ' . $_FILES['file']['size'] . ' bytes <br />'; 

$filehandle = fopen($_FILES['file']['tmp_name'],"r");

// get file's magic number
$MNUMBER =  bin2hex(fread($filehandle,4));
// check if libpcap
if ("$MNUMBER" != "a1b2c3d4" && $MNUMBER != "d4c3b2a1") {
print 'bad file format ! <br />';
exit;
}
...

to allow only the upload of files in the libpcap file format.

to check for the size of the uploaded file:

PHP Code:
if ($_FILES['file']['size'] > 8388608)
   print 'file size limit reached ! <br />'; 
Advertisements
Kategorien:Security Schlagwörter: , ,
%d Bloggern gefällt das: