Security issues with file_upload ?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • el_roachmeister@yahoo.com

    Security issues with file_upload ?

    I want to ask my web hosts to allow file uploads with php since it is
    currently turned off. I was wondering does this pose a security risk to
    the server? What kinds of things should I check in my script when I use
    file uploads?

    Thanks!

  • Senator Jay Billington Bulworth

    #2
    Re: Security issues with file_upload ?

    el_roachmeister @yahoo.com wrote in news:1107562396 .779944.218020
    @l41g2000cwc.go oglegroups.com:
    [color=blue]
    > I want to ask my web hosts to allow file uploads with php since it is
    > currently turned off. I was wondering does this pose a security risk to
    > the server? What kinds of things should I check in my script when I use
    > file uploads?[/color]

    First, rudimentary file typing. Suppose you have an image gallery and you
    want people to upload only JPG images. If some yahoo uploads a .ZIP file, you
    want to recognize this right off, and tell him to get bent:

    <?php
    #Note 'upload' is the name of the <input type="file"> HTML element
    if(is_uploaded_ file($_FILES['upload']['tmp_name']) && ($_FILES['upload']
    ['size'] > 0)){
    #Was this a jpg file or something bogus?
    $extension = substr($_FILES['upload']['name'], -3);
    if(strcasecmp($ extension, 'jpg') != 0)
    die('How about you try again, and this time send a JPG.');
    else{
    //Process upload...
    }
    }
    ?>

    (This would not prevent someone from renaming a .ZIP file to end in .JPG and
    sending that up. You could test the file data itself using the GD library.)

    You'll also want to check the uploaded filename for directory traversal
    attempts. This is true anytime you write to files and the filename is
    supplied by the user or some untrusted data source.

    How you do this depends on how you're going to handle naming the uploads. In
    most cases I tend to generate random filenames for uploads, then I tie that
    filename into a database somewhere (e.g. to associate an uploaded file to a
    certain user's account). Handling uploads in this manner makes eliminating
    directory traversal pretty easy, you just ignore the user-supplied filename
    completely.

    If you want to keep the uploader's filename, I would suggest stripping it
    down to alphanums only. Something like this:

    <?php
    $newname = preg_replace("/[^a-zA-Z0-9_\.]/", '', $_FILES['upload']['name']);
    while(strstr($n ewname, '..')){
    $newname = str_replace('.. ', '.', $newname);
    }
    ?>

    This will cut out any funny stuff using escape characters, % signs, forward
    or backward slashes, pound signs, semicolons, etc. It also strips out any
    dot-dots. Combine that with a hardcoded destination directory, and make sure
    that the source argument to move_uploaded_f ile() is the tmp_name, not the
    name element of the upload:

    <?
    #newname came from above code
    $newpath = "/home/www/uploads/$newname";
    move_uploaded_f ile($_FILES['upload']['tmp_name'], $newpath);
    ?>

    If I left out anything major, someone else will notice.. :)

    hth


    --

    Bulworth : PHP/MySQL/Unix | Email : str_rot13('f@fu ng.arg');
    --------------------------|---------------------------------
    <http://www.phplabs.com/> | PHP scripts, webmaster resources

    Comment

    • Geoff Berrow

      #3
      Re: Security issues with file_upload ?

      I noticed that Message-ID: <Xns95F3DE37CB8 D0CANDLETRUCK@6 5.24.7.150>
      from Senator Jay Billington Bulworth contained the following:
      [color=blue]
      > #Was this a jpg file or something bogus?
      > $extension = substr($_FILES['upload']['name'], -3);
      > if(strcasecmp($ extension, 'jpg') != 0)
      > die('How about you try again, and this time send a JPG.');
      > else{
      > //Process upload...
      > }[/color]

      Slightly easier to use $_FILES['upload']['type'] which should
      =="image/jpg" if it's a jpg

      Not sure if it actually checks type though, or just extension.

      --
      Geoff Berrow (put thecat out to email)
      It's only Usenet, no one dies.
      My opinions, not the committee's, mine.
      Simple RFDs http://www.ckdog.co.uk/rfdmaker/

      Comment

      • Geoff Berrow

        #4
        Re: Security issues with file_upload ?

        I noticed that Message-ID: <nga901ltbild8v n0f5rteuvttclmr 5fss2@4ax.com>
        from Geoff Berrow contained the following:
        [color=blue]
        >Not sure if it actually checks type though, or just extension.[/color]

        Just tested. It checks extension.

        --
        Geoff Berrow (put thecat out to email)
        It's only Usenet, no one dies.
        My opinions, not the committee's, mine.
        Simple RFDs http://www.ckdog.co.uk/rfdmaker/

        Comment

        • Dani CS

          #5
          Re: Security issues with file_upload ?

          Geoff Berrow wrote:[color=blue]
          > I noticed that Message-ID: <nga901ltbild8v n0f5rteuvttclmr 5fss2@4ax.com>
          > from Geoff Berrow contained the following:
          >
          >[color=green]
          >>Not sure if it actually checks type though, or just extension.[/color]
          >
          >
          > Just tested. It checks extension.
          >[/color]

          I think that the mime type is sent by the browser (and therefore you
          can't trust it).

          <quote src="http://es.php.net/manual/en/features.file-upload.php">

          $_FILES['userfile']['type']

          The mime type of the file, if the browser provided this
          information. An example would be "image/gif".

          </quote>

          Comment

          • denisb

            #6
            Re: Security issues with file_upload ?

            Dani CS <contusiones.me rluza@yahoo.es. quita-la-merluza> wrote:[color=blue]
            > Geoff Berrow wrote:[color=green]
            > > I noticed that Message-ID: <nga901ltbild8v n0f5rteuvttclmr 5fss2@4ax.com>
            > > from Geoff Berrow contained the following:[color=darkred]
            > >>Not sure if it actually checks type though, or just extension.[/color]
            > > Just tested. It checks extension.[/color]
            > I think that the mime type is sent by the browser (and therefore you
            > can't trust it).[/color]

            why not using getimagesize function ?

            <http://es.php.net/manual/en/function.getima gesize.php>

            " Returns an array with 4 elements.
            Index 0 contains the width of the image in pixels. Index 1 contains the
            height.
            *********
            Index 2 is a flag indicating the type of the image: 1 = GIF, 2 = JPG, 3
            = PNG, 4 = SWF, 5 = PSD, 6 = BMP, 7 = TIFF(intel byte order), 8 =
            TIFF(motorola byte order), 9 = JPC, 10 = JP2, 11 = JPX, 12 = JB2, 13 =
            SWC, 14 = IFF, 15 = WBMP, 16 = XBM. These values correspond to the
            IMAGETYPE constants that were added in PHP 4.3.0.
            *********
            Index 3 is a text string with the correct height="yyy" width="xxx"
            string that can be used directly in an IMG tag. "


            $verif_type = GetImageSize($t he_file);
            if ($verif_type[2] != '1') { // not a gif picture
            if ($verif_type[2] != '2') { // not a jpg picture
            if ($verif_type[2] != '3') { // not a png picture
            if ($verif_type[2] != '4') { // .....

            --
            @@@@@
            E -00 comme on est very beaux dis !
            ' `) /
            |\_ =="

            Comment

            Working...