Security

We understand how important it is to protect your website or web application from various attacks: from hacking into the system and to Denial of Service attack (DoS). That is why our products and particularly File Uploader are developed with strict compliance to all standards and good practices.

File Uploader has client-server architecture. This means that while the widget (client) is executed in user's browser, the uploader works on your server as a script or an application depending on what programming language and technologies you use on your website.

This article describes features of File Manager, and also provides a number of advices on what you should keep an eye on to secure yourself from various treats caused by uploading files to the server. Even though all examples are listed in the context of File Uploader, the article still will be useful even for experienced developers and system administrators. If you don't know how to manage security of your website we recommend at least to take a brief look at each section below and make sure your website is configured how it should be.

Access control

The main security aspect of File Uploader configuration is configuring user permissions in the server part to access the uploader. Here what is important here: even if hackers don't have access to the widget, they still can send requests to the server that does not have properly configured access permissions.

So, there are three resources you should limit access to:

  • Uploader script (permission to send parameters and files to the uploader)
  • File upload directory (permission to download a file inside the directory)
  • Temporary upload directory (permission to download a file that the user has uploaded but not yet committed)

For example, if the File Uploader widget is used only by the administrator of the website to upload images to the website (images are available to everyone), permission must be set as follows:

       / + uploader script                 / - uploader script
admin  -  + upload directory            user - + upload directory
       \ + temporary directory              \ - temporary directory

And if anyone can use the widget, for example, by attaching a file to comments on the website, the access must not be restricted.

Access to all these resources can be restricted using means provided by your HTTP server, CMS or framework.
A detailed review of ways to restrict access to URL in various HTTP server and CMS goes beyond the scope of this article: possibly, you already know how to do this, and we listed directories to restrict access above.
However access to the uploader requires a more thorough view. The way to do this depends on the HTTP server (language, stack of technologies) as well as on the particular way to authorize users.

Forms authentication

Currently, a wide majority of websites use this authentication method when a user enters the data of his or her account to the authentication form on the website. After successful authorization, the server sends a specific Session ID that is put to client cookies. This Session ID is then used as a confirmation of the logged in state of the user.
User can have a certain role: customer, administrator, etc.

Here, restricting access to the server part of File Uploader must be accomplished with the same methods as in your web application. The goal is to check the user even before the uploader processes the query, and if the restricted account is detected, return 403 Forbidden response to a browser. This code will be processed by the widget, and it will display a corresponding message.

Depending on the platform, this can be done in several ways.

PHP

If you use PHP, change the isAuthorized() function in the auth.php file to make it return true if the current user who sent the request has permissions to access the uploader, and false otherwise (the script will send 403 to a browser).
Here is a trivial example:

function isAuthorized() {
    session_start();
    if ($_SESSION['name'] === 'admin' || $_SESSION['name'] === 'webmaster')
        return true;
    else
        return false;
}

Here, the function not just check if the session is present, but also checks the user name. Alternatively, instead of checking the name you can check the user role or something else depending on what data your authentication script saves to the session variable.

And one more option if your website already has tools to check sessions:

include '../../../mywebsite_scripts/my_auth.php';
function isAuthorized() {
    return isCurrentUserAdmin();
}

Java

If you use the uploader based on Java Servlets, the ideal solution for you is to write your own authentication filter. A filter here is Servlet Filter, a handler that allows to cut in URL processing of the handler it is mapped to. If the user does not meet some criteria (role is missing, anonymous user and so on), the filter can interrupt execution of the handler chain and return the status 403 to the client.

Probably, if you already use Forms authentication on your J2EE website, you already has such a filter, so you should merely map it to the URL the uploader is tied to. For example:

<filter>
    <filter-name>AuthFilter</filter-name>
    <filter-class>AuthFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>AuthFilter</filter-name>
    <url-pattern>/admin/uploader</url-pattern>
</filter-mapping>

Basic Auth

If you use Basic Auth to access the website control panel, you can limit access to the script using the same method.

Depending on the HTTP server used (Apache, nginx, Tomcat, etc.), a different way to control access to the uploader is used.
Anyway, the uploader is mapped to a particular URL. This mapping either matches the location of the file in the directory (in case of Apache + PHP, for instance), or is specified in the HTTP server settings file (nginx, Tomcat, etc.). Correspondingly, in the first case you should create a .htaccess file in the given directory (or in the .conf file of your website), and add all users who can access the script. In the second case you make the same in the settings files of the HTTP server.

The same you do with the access to directory containing uploaded files except that you may want to give read access to everyone. Other variants are possible too: for example, limiting access to certain directories. But still the configuration is similar to the above: you assign user accounts to a URL or a URL template they can access.

Please keep in mind that if your website works via HTTP (without SSL, i.e. it is not available with the https:// prefix), then using Basic Auth is generally not safe, because of lack of encryption, which opens possibility for password interception. This is true not only for the uploader, but for the entire website.

Apache example

Here is an example of how to configure authorization on the Apache web server. At first, you should add user accounts to some file (we use /etc/apache2/.htpasswd here) using the standard htpasswd command. Then, in the main configuration file of the website (or in .htaccess) write:

<Directory "/uploader/">
    AuthType Basic
    AuthName "Restricted Content"
    AuthUserFile /etc/apache2/.htpasswd
    Require valid-user
</Directory>

Apparently, uploaded files should be available with a URL different from /uploader/files, because authorization will block access to them for non-authorized users of the website. A possible solution is to configure uploading of images to /images/. And by the way, you don't have to change the server config file for that - you can simply define a symbolic link to the directory containing files.

Uploaded code execution control in PHP

When we allow uses to upload something to the server, we should strictly control what they upload and how these files are treated by the server. This is especially vital for PHP-based websites. Their specific is often that the URL structure often mirrors the directory structure, and the .php executables are scattered all the way through mixed with various resources. Hence, there is a non-zero probability that your server is configured to treat a file as a script based on its extension.

An example of such vulnerability would be uploading of a malicious PHP script and accessing it by its URL (that is, execution). What should you do to prevent this? You must forbid executing any files in the uploading directories and in the temporary directories.

Apache

In Apache this is configured using the .htaccess file or the global configuration file. Such a .htaccess file already comes with the uploader, so simply do not delete it. This method works if your web server does not put limits on using .htaccess files in the directories of the website. For example, if the AllowOverride All setting allows redefining global settings of the website with settings from .htaccess merging the, hierarchically. Otherwise, you should first make sure that this method works. If it does not, use the same settings in the global settings file of your website (usually, it is something like /etc/apache2/sites-enabled/001-mysite.conf) - for the specific directory. Example:

<VirtualHost mywebsite.com:80>
        ...
        <Directory /images/uploads/>
            <IfModule mod_php5.c>
                php_value engine off
            </IfModule>
            <IfModule mod_php4.c>
                php_value engine off
            </IfModule>
        </Directory>
        ...
</VirtualHost>

Nginx

In Nginx, to disable executing uploaded files from the upload directory, add the corresponding directive to nginx.conf. The code you need goes in the below example. The first line forbids execution of uploaded files as PHP files. Then we simply demonstrate definition of a file handler for files with the .php extension: it is this behaviour that we redefine.

location ^~ /jsplusFileUploader/uploader/files/ {}

location ~ \.php$ {
  fastcgi_split_path_info ^(.+\.php)(/.+)$;
  fastcgi_pass 127.0.0.1:9000;
  fastcgi_index index.php;
  include fastcgi_params;
}

Uploaded file type control

To limit unwanted uploads, you can use upload file filtering by extension.
allowedExtensions.

In some cases, this isn't reliable protection from code execution on the server by hackers (the reliable way is described above), but still limiting file types that the server accepts is a good practice. This parameter also protects your users from files uploaded by other users. For example, allowing sharing of .exe files on your website is considered unsafe. So, simply set the list of allowed extensions of files and images. By default it is an empty string meaning any types of files are allowed.

PHP example (config.php):

$config['allowedExtensions'] = 'jpeg,jpg,png,gif,zip,pdf';

Java Servlets example (web.xml):

    <servlet>
        ...
        <init-param>
            <param-name>allowedExtensions</param-name>
            <param-value>jpeg,jpg,png,gif,zip,pdf</param-value>
        </init-param>
    </servlet>

Protection from overload (DoS)

If you use File Uploader within the website control/admin panel, or if only trusted and accredited users can access it (for example, employees of your company), security settings come down to restricting access to the server part of the uploader for all other users. But if many people can leave comments on your website, even anonymously, and attach images and files to such comments, you must make sure that their requests do not create excessive load to the server.

For that, configure the following parameters on your server:

maxUploadFileSize - defines the maximum file size of uploads. The default value is 0 (no limits)

maxImageResizeWidth and maxImageResizeHeight define the maximum target scale in pixels. If a user specifies too big values, scaling an image to such resolution may consume a significant chunk of RAM of the server. By default, these parameters are set to 5000.