1. Advertising
    y u no do it?

    Advertising (learn more)

    Advertise virtually anything here, with CPM banner ads, CPM email ads and CPC contextual links. You can target relevant areas of the site and show ads based on geographical location of the user if you wish.

    Starts at just $1 per CPM or $0.10 per CPC.

Checking for safe file uploads

Discussion in 'PHP' started by Gmorkster, Aug 21, 2005.

  1. #1
    I'm writing a script that should, among others, allow users to upload resources (images but also any other file) to the server to be viewed/downloaded by visitors. The uploads are stored in a folder on the server. How should I go about making sure users don't upload unsafe scripts without restricting the service too much?
    SEMrush
    I could, for example, disallow any file with .php extension to be uploaded, but the server can be configured to parse PHP tags in any file, so a .txt containing PHP code could be executed.

    Same would go for any server-side script but also JS, ActiveX and other risk-prone files.

    Any suggestions?
     
    Gmorkster, Aug 21, 2005 IP
    SEMrush
  2. tflight

    tflight Peon

    Messages:
    617
    Likes Received:
    38
    Best Answers:
    0
    Trophy Points:
    0
    #2
    The most common way is to create a white list of allowed file extensions. You mention that the server could be configured to allow .txt files to execute PHP code which is true... but why would you?

    We'll also need to know what OS your server is running since that will make a difference in the tools and techniques available.
     
    tflight, Aug 21, 2005 IP
  3. J.D.

    J.D. Peon

    Messages:
    1,198
    Likes Received:
    64
    Best Answers:
    0
    Trophy Points:
    0
    #3
    Storing uploaded content in the web directory structure may cost you a server one day. When you receive a file to upload, copy it somewhere else and then, when the file is requsted, read and serve it using PHP file I/O functionality. When storing uploaded content, make sure nobody, not even admins, can execute any of the uploaded files locally on the machine. It is also a good idea to authenticate those users who upload files - if anybody uploads any dangerous content, at least you will have some info on them.

    J.D.
     
    J.D., Aug 21, 2005 IP
  4. Gmorkster

    Gmorkster Peon

    Messages:
    202
    Likes Received:
    7
    Best Answers:
    0
    Trophy Points:
    0
    #4
    Sorry I should have mentioned this first: the script is supposed to be made publicly available so I can't control the platform. It could run on any configuration.
     
    Gmorkster, Aug 21, 2005 IP
  5. Gmorkster

    Gmorkster Peon

    Messages:
    202
    Likes Received:
    7
    Best Answers:
    0
    Trophy Points:
    0
    #5
    Good points, cheers!
     
    Gmorkster, Aug 21, 2005 IP
  6. goldensea80

    goldensea80 Well-Known Member

    Messages:
    422
    Likes Received:
    10
    Best Answers:
    0
    Trophy Points:
    128
    #6
    I have to go for lunch now. You can check my latest blog for detail. Will come back later
     
    goldensea80, Aug 21, 2005 IP
  7. goldensea80

    goldensea80 Well-Known Member

    Messages:
    422
    Likes Received:
    10
    Best Answers:
    0
    Trophy Points:
    128
    #7
    Here is some handy code extract from my blog. If some one has better solution, I'd be appriciate if you comment to my blog.

    Get extension of the filename
    
    function get_ext($filename)
    {
        if (!empty($filename))
        {
           $pathinfo=pathinfo($filename);
           return $pathinfo['extension'];
        }
        else
        {
           return 'Unkown';
        }
    }
    
    PHP:
    Check if an extension is allow:
    //This us can use this line in your config script
    define ("EXT_ALLOWED",'mp3,wma,rm,mov,mid,swf,wmv');
    
    function is_ext_allowed($ext)
    {
       $EXT_ALLOWED=explode(',',EXT_ALLOWED);
       return in_array(strtolower($ext),$EXT_ALLOWED);
    }
    PHP:
     
    goldensea80, Aug 22, 2005 IP
  8. Gmorkster

    Gmorkster Peon

    Messages:
    202
    Likes Received:
    7
    Best Answers:
    0
    Trophy Points:
    0
    #8
    Thanks, but I don't want to rely on security based on an extension whitelist. BTW goldensea, you should also check if the MIME type of the uploaded file matches the extension (if you get some application/* on a .txt you know there's something wrong). You'll need PHP compiled with --with-mime-magic.

    The solution I settled for is:
    1. Store all uploaded content somewhere outside htdocs (or public_html) in a folder marked 0600 (Thanks JD!)
    2. Make all uploaded content 0600 (I don't think I need to be as paranoid as to set it to 0000 then chmod to 0400/0200 whenever I need to read/write the file, then set it back to 0000)
    3. When a resource needs to be accessed, content is either read using fread() (for text files) or sent for download via forced headers (except images, which are served using GD's functions). All text files are passed through htmlentities() before being displayed.

    I will allow an extension whitelist as an extra feature though, admins might choose to disallow certain files for whatever reasons, just won't rely on it to keep the system secure.
     
    Gmorkster, Aug 22, 2005 IP
  9. goldensea80

    goldensea80 Well-Known Member

    Messages:
    422
    Likes Received:
    10
    Best Answers:
    0
    Trophy Points:
    128
    #9
    That's right. Thanks again. I will follow the advices.
     
    goldensea80, Aug 22, 2005 IP