Upgrade filebrowser; minor fixes relevant to the upgrade.
[redakcja.git] / src / fileupload / static / lib / jQuery-File-Upload-10.32.0 / SECURITY.md
1 # File Upload Security
2
3 ## Contents
4
5 - [Introduction](#introduction)
6 - [Purpose of this project](#purpose-of-this-project)
7 - [Mitigations against file upload risks](#mitigations-against-file-upload-risks)
8   - [Prevent code execution on the server](#prevent-code-execution-on-the-server)
9   - [Prevent code execution in the browser](#prevent-code-execution-in-the-browser)
10   - [Prevent distribution of malware](#prevent-distribution-of-malware)
11 - [Secure file upload serving configurations](#secure-file-upload-serving-configurations)
12   - [Apache config](#apache-config)
13   - [NGINX config](#nginx-config)
14 - [Secure image processing configurations](#secure-image-processing-configurations)
15 - [ImageMagick config](#imagemagick-config)
16
17 ## Introduction
18
19 For an in-depth understanding of the potential security risks of providing file
20 uploads and possible mitigations, please refer to the
21 [OWASP - Unrestricted File Upload](https://owasp.org/www-community/vulnerabilities/Unrestricted_File_Upload)
22 documentation.
23
24 To securely setup the project to serve uploaded files, please refer to the
25 sample
26 [Secure file upload serving configurations](#secure-file-upload-serving-configurations).
27
28 To mitigate potential vulnerabilities in image processing libraries, please
29 refer to the
30 [Secure image processing configurations](#secure-image-processing-configurations).
31
32 By default, all sample upload handlers allow only upload of image files, which
33 mitigates some attack vectors, but should not be relied on as the only
34 protection.
35
36 Please also have a look at the
37 [list of fixed vulnerabilities](VULNERABILITIES.md) in jQuery File Upload, which
38 relates mostly to the sample server-side upload handlers and how they have been
39 configured.
40
41 ## Purpose of this project
42
43 Please note that this project is not a complete file management product, but
44 foremost a client-side file upload library for [jQuery](https://jquery.com/).  
45 The server-side sample upload handlers are just examples to demonstrate the
46 client-side file upload functionality.
47
48 To make this very clear, there is **no user authentication** by default:
49
50 - **everyone can upload files**
51 - **everyone can delete uploaded files**
52
53 In some cases this can be acceptable, but for most projects you will want to
54 extend the sample upload handlers to integrate user authentication, or implement
55 your own.
56
57 It is also up to you to configure your web server to securely serve the uploaded
58 files, e.g. using the
59 [sample server configurations](#secure-file-upload-serving-configurations).
60
61 ## Mitigations against file upload risks
62
63 ### Prevent code execution on the server
64
65 To prevent execution of scripts or binaries on server-side, the upload directory
66 must be configured to not execute files in the upload directory (e.g.
67 `server/php/files` as the default for the PHP upload handler) and only treat
68 uploaded files as static content.
69
70 The recommended way to do this is to configure the upload directory path to
71 point outside of the web application root.  
72 Then the web server can be configured to serve files from the upload directory
73 with their default static files handler only.
74
75 Limiting file uploads to a whitelist of safe file types (e.g. image files) also
76 mitigates this issue, but should not be the only protection.
77
78 ### Prevent code execution in the browser
79
80 To prevent execution of scripts on client-side, the following headers must be
81 sent when delivering generic uploaded files to the client:
82
83 ```
84 Content-Type: application/octet-stream
85 X-Content-Type-Options: nosniff
86 ```
87
88 The `Content-Type: application/octet-stream` header instructs browsers to
89 display a download dialog instead of parsing it and possibly executing script
90 content e.g. in HTML files.
91
92 The `X-Content-Type-Options: nosniff` header prevents browsers to try to detect
93 the file mime type despite the given content-type header.
94
95 For known safe files, the content-type header can be adjusted using a
96 **whitelist**, e.g. sending `Content-Type: image/png` for PNG files.
97
98 ### Prevent distribution of malware
99
100 To prevent attackers from uploading and distributing malware (e.g. computer
101 viruses), it is recommended to limit file uploads only to a whitelist of safe
102 file types.
103
104 Please note that the detection of file types in the sample file upload handlers
105 is based on the file extension and not the actual file content. This makes it
106 still possible for attackers to upload malware by giving their files an image
107 file extension, but should prevent automatic execution on client computers when
108 opening those files.
109
110 It does not protect at all from exploiting vulnerabilities in image display
111 programs, nor from users renaming file extensions to inadvertently execute the
112 contained malicious code.
113
114 ## Secure file upload serving configurations
115
116 The following configurations serve uploaded files as static files with the
117 proper headers as
118 [mitigation against file upload risks](#mitigations-against-file-upload-risks).  
119 Please do not simply copy&paste these configurations, but make sure you
120 understand what they are doing and that you have implemented them correctly.
121
122 > Always test your own setup and make sure that it is secure!
123
124 e.g. try uploading PHP scripts (as "example.php", "example.php.png" and
125 "example.png") to see if they get executed by your web server, e.g. the content
126 of the following sample:
127
128 ```php
129 GIF89ad <?php echo mime_content_type(__FILE__); phpinfo();
130 ```
131
132 ### Apache config
133
134 Add the following directive to the Apache config (e.g.
135 /etc/apache2/apache2.conf), replacing the directory path with the absolute path
136 to the upload directory:
137
138 ```ApacheConf
139 <Directory "/path/to/project/server/php/files">
140   # Some of the directives require the Apache Headers module. If it is not
141   # already enabled, please execute the following command and reload Apache:
142   # sudo a2enmod headers
143   #
144   # Please note that the order of directives across configuration files matters,
145   # see also:
146   # https://httpd.apache.org/docs/current/sections.html#merging
147
148   # The following directive matches all files and forces them to be handled as
149   # static content, which prevents the server from parsing and executing files
150   # that are associated with a dynamic runtime, e.g. PHP files.
151   # It also forces their Content-Type header to "application/octet-stream" and
152   # adds a "Content-Disposition: attachment" header to force a download dialog,
153   # which prevents browsers from interpreting files in the context of the
154   # web server, e.g. HTML files containing JavaScript.
155   # Lastly it also prevents browsers from MIME-sniffing the Content-Type,
156   # preventing them from interpreting a file as a different Content-Type than
157   # the one sent by the webserver.
158   <FilesMatch ".*">
159     SetHandler default-handler
160     ForceType application/octet-stream
161     Header set Content-Disposition attachment
162     Header set X-Content-Type-Options nosniff
163   </FilesMatch>
164
165   # The following directive matches known image files and unsets the forced
166   # Content-Type so they can be served with their original mime type.
167   # It also unsets the Content-Disposition header to allow displaying them
168   # inline in the browser.
169   <FilesMatch ".+\.(?i:(gif|jpe?g|png))$">
170     ForceType none
171     Header unset Content-Disposition
172   </FilesMatch>
173 </Directory>
174 ```
175
176 ### NGINX config
177
178 Add the following directive to the NGINX config, replacing the directory path
179 with the absolute path to the upload directory:
180
181 ```Nginx
182 location ^~ /path/to/project/server/php/files {
183     root html;
184     default_type application/octet-stream;
185     types {
186         image/gif     gif;
187         image/jpeg    jpg;
188         image/png    png;
189     }
190     add_header X-Content-Type-Options 'nosniff';
191     if ($request_filename ~ /(((?!\.(jpg)|(png)|(gif)$)[^/])+$)) {
192         add_header Content-Disposition 'attachment; filename="$1"';
193         # Add X-Content-Type-Options again, as using add_header in a new context
194         # dismisses all previous add_header calls:
195         add_header X-Content-Type-Options 'nosniff';
196     }
197 }
198 ```
199
200 ## Secure image processing configurations
201
202 The following configuration mitigates
203 [potential image processing vulnerabilities with ImageMagick](VULNERABILITIES.md#potential-vulnerabilities-with-php-imagemagick)
204 by limiting the attack vectors to a small subset of image types
205 (`GIF/JPEG/PNG`).
206
207 Please also consider using alternative, safer image processing libraries like
208 [libvips](https://github.com/libvips/libvips) or
209 [imageflow](https://github.com/imazen/imageflow).
210
211 ## ImageMagick config
212
213 It is recommended to disable all non-required ImageMagick coders via
214 [policy.xml](https://wiki.debian.org/imagemagick/security).  
215 To do so, locate the ImageMagick `policy.xml` configuration file and add the
216 following policies:
217
218 ```xml
219 <?xml version="1.0" encoding="UTF-8"?>
220 <!-- ... -->
221 <policymap>
222   <!-- ... -->
223   <policy domain="delegate" rights="none" pattern="*" />
224   <policy domain="coder" rights="none" pattern="*" />
225   <policy domain="coder" rights="read | write" pattern="{GIF,JPEG,JPG,PNG}" />
226 </policymap>
227 ```