How to safely prevent uploaded file from being run via PHP on any server?

后端 未结 10 2086
独厮守ぢ
独厮守ぢ 2021-02-15 13:13

I noticed that it\'s possible to run a file via PHP even if its extension wasn\'t .php, for example file test.xyz.php.whatever.zyx can be still run wit

相关标签:
10条回答
  • 2021-02-15 13:46

    On Apache you could disable all dynamic handlers for the directory that contains the untrusted files.

    SetHandler default-handler
    
    0 讨论(0)
  • 2021-02-15 13:53

    Instead of php_flag engine off you could remove the handler for PHP files using an .htaccess file for a single directory.

    In the directory you are disabling PHP in, your .htaccess should include:

    RemoveHandler .php .phtml .php3 .php4 .php5
    RemoveType .php .phtml .php3 .php4 .php5
    

    You can likely get away with the below however, depending on which AddHandler types you have configured in your default Apache configuration, which, on windows, should be in C:\Program Files\Apache<version>\conf\httpd.conf

    RemoveHandler .php 
    RemoveType .php 
    

    You will also need to ensure that in your main apache configuration file, that the directory containing the .htaccess file is in, is covered by a Directory statement which has AllowOverride FileInfo set. You may wish to consider AllowOverride All if you will be using .htaccess files for other purposes - see the Apache documentation for AllowOverride for an explanation of the differences.

    0 讨论(0)
  • 2021-02-15 13:57

    Personally, this is the main reason I no longer upload files to the web server under any circumstances. Instead, I use S3 / Amazon SDK to move the uploaded temp file directly to a bucket on S3 with Private permissions (I use S3, any other CDN will work just as well). If the file needs to be viewed or viewed by a web client, I use a "getter" function of sorts that integrates with the SDK to get the file and display it.

    There are just so many uncontrollable variables that come into play whenever you allow any kind of file upload to a web server, it can be difficult to manage permissions, filtering, and even just space. With S3 (or any other CDN), that is all very easy to manage, and all files are effectively quarantined from the server by default.

    0 讨论(0)
  • 2021-02-15 13:57

    The following .htaccess-code could work and deny access to files containing "php":

    <FilesMatch "php">
        Deny from all
    </FilesMatch>
    
    0 讨论(0)
  • 2021-02-15 13:58

    First of all you need to understand what happens here:

    test.xyz.php.whatever.zyx
    

    Such a file on a webserver on it's own would do nothing. Only added configuration does tell Apache to execute PHP on that file.

    So if you remove that added configuration, Apache won't care to find .php in there - be it at the very end or part of a stacked file-extension.

    Check which handler you have set for php in your server configuration. Remove it for the upload directory. This then won't resolve any other configuration issues you might have with uploaded files, however PHP files aren't executed by PHP any longer then - which is what you want if I understood you right.

    If you've got a problem to find out what this is about, you need to post your PHP configuration in your httpd.conf file and associated Apache HTTPD configuration files for your system.

    The directive somebody told you for .htaccess:

    php_flag engine off
    

    does only work if you're running PHP as an apache SAPI module.

    0 讨论(0)
  • 2021-02-15 14:00

    To be completely secure, you'll need to do a couple of things:

    Set your upload directory above your "public" folder, making it inaccessible from a browser. This setting is in php.ini (php config file). You'll need to restart Apache for this to take effect. On most Redhat / Fedora / CentOS web servers, this can be:

    upload_tmp_dir = "/var/tmp/"
    

    OR, on my local Windows 7 WAMP install, it is set to:

    upload_tmp_dir = "c:/wamp/tmp"
    

    Disable scripts from running on that directory (c:/wamp/tmp), in .htaccess:

    RemoveHandler .php .phtml .php3
    RemoveType .php .phtml .php3
    php_flag engine off
    

    In your PHP script, get the uploaded file, filter it based on mimetype (not filetype extension), change the filename, and put it into a secured publicly accessible folder. In more detail:

    • create a whitelist of filetypes, ex: only images (jpeg, png, gif, bmp). This can be done using mime_content_type() http://php.net/manual/en/function.mime-content-type.php or the newer finfo_file() http://us3.php.net/manual/en/function.finfo-file.php
    • choose a new filename, often it's best to use a random MD5 hash based on the original filename + salt + timestamp.
    • move it to a public folder, ex: "c:/wamp/www/project_name/public/uploads"

    Preferably use an MVC framework, such as Zend Framework, which includes filetype filtering.

    If you do all of that, you should be secure. Obviously you'll never be 100% safe, since there are countless obscure exploits targeting PHP, MySQL, the command line, etc, particularly on older systems. On larger company webservers (what I work on), they disable everything, and selectively enable only what is required for the project. With a system such as WAMP, they enable everything, to ease local development.

    Good practice for working on a professional project is to get a cloud server account with Rackspace or Amazon, and learn how to configure php.ini, and httpd.conf settings, as well as PHP security best practices. In general, do not trust the users input, expect it to be corrupt / malicious / malformed, and in the end you'll be secure.

    0 讨论(0)
提交回复
热议问题