@@ -54,7 +54,7 @@ In some cases this can be acceptable, but for most projects you will want to
54
54
extend the sample upload handlers to integrate user authentication, or implement
55
55
your own.
56
56
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
58
58
files, e.g. using the
59
59
[ sample server configurations] ( #secure-file-upload-serving-configurations ) .
60
60
@@ -69,7 +69,7 @@ uploaded files as static content.
69
69
70
70
The recommended way to do this is to configure the upload directory path to
71
71
point 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
73
73
with their default static files handler only.
74
74
75
75
Limiting 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.
122
122
> Always test your own setup and make sure that it is secure!
123
123
124
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 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
+ ```
126
131
127
132
### Apache config
128
133
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:
131
137
132
138
``` ApacheConf
133
139
<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:
135
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>
136
164
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))$">
148
170
ForceType none
149
171
Header unset Content-Disposition
150
172
</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
155
173
</Directory>
156
174
```
157
175
0 commit comments