@@ -54,7 +54,7 @@ In some cases this can be acceptable, but for most projects you will want to
5454extend the sample upload handlers to integrate user authentication, or implement
5555your own.
5656
57- It is also up to you to configure your Webserver to securely serve the uploaded
57+ It is also up to you to configure your web server to securely serve the uploaded
5858files, e.g. using the
5959[ sample server configurations] ( #secure-file-upload-serving-configurations ) .
6060
@@ -69,7 +69,7 @@ uploaded files as static content.
6969
7070The recommended way to do this is to configure the upload directory path to
7171point outside of the web application root.
72- Then the Webserver can be configured to serve files from the upload directory
72+ Then the web server can be configured to serve files from the upload directory
7373with their default static files handler only.
7474
7575Limiting file uploads to a whitelist of safe file types (e.g. image files) also
@@ -122,36 +122,54 @@ understand what they are doing and that you have implemented them correctly.
122122> Always test your own setup and make sure that it is secure!
123123
124124e.g. try uploading PHP scripts (as "example.php", "example.php.png" and
125- "example.png") to see if they get executed by your Webserver.
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+ ```
126131
127132### Apache config
128133
129- Add the following directive to the Apache config, replacing the directory path
130- with the absolute path to the upload directory:
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:
131137
132138``` ApacheConf
133139<Directory "/path/to/project/server/php/files">
134- # To enable the Headers module, execute the following command and reload Apache:
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:
135142 # 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>
136164
137- # The following directives prevent the execution of script files
138- # in the context of the website.
139- # They also force the content-type application/octet-stream and
140- # force browsers to display a download dialog for non-image files.
141- SetHandler default-handler
142- ForceType application/octet-stream
143- Header set Content-Disposition attachment
144-
145- # The following unsets the forced type and Content-Disposition headers
146- # for known image files:
147- <FilesMatch "(?i)\.(gif|jpe?g|png)$">
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))$">
148170 ForceType none
149171 Header unset Content-Disposition
150172 </FilesMatch>
151-
152- # The following directive prevents browsers from MIME-sniffing the content-type.
153- # This is an important complement to the ForceType directive above:
154- Header set X-Content-Type-Options nosniff
155173</Directory>
156174```
157175
0 commit comments