Php – How to use max_post_size and upload_max_filesize in an Apache directive

apache-2.2mod-rewritePHPSecurityupload

My users want to upload large files (50-100MB) in the CMS backend of a PHP web application. I could adjust the upload_max_filesize and post_max_size settings for PHP globally in this virtual host, but I'm afraid that would make Denial of Service attacks easier than necessary.

In theory, these two settings can be adjusted per directory (either in the virtual host config file, or via .htaccess files), and I only need the larger values in the admin area. Unfortunately, this application has only a start.php in the web root (single point of entry), and all other PHP files are included from there. This appears to make a per-directory setting impossible. I've tried to match the path used in the CMS with <Location>, but even with the correct path, the php_value directives don't have any effect.

<LocationMatch ^/admin>
   php_value  upload_max_filesize  100MB
   php_value  post_max_size        100MB
</LocationMatch>

(mod_rewrite is used to translate a path like /admin/content/bla to /start.php?_p=/admin/content/bla, which is why the "start.php" file name does not appear in the above expression.)

Is there any way to make this work? I'm also open for alternative suggestions; for example, an IP-based setup might be possible in our case.

TIA.

Best Answer

Apache doesn't seem to be able to do this. However, you can set the limit high globally for Apache or php-fpm and use nginx with proxy_pass or fastcgi_pass and set the per-url limit using nginx client_max_body_size directive in separate locations:

location / {
  client_max_body_size 1M;
  try_files NOT_EXISTS @proxy;
}
location = /upload.php {
  client_max_body_size 100M;
  try_files NOT_EXISTS @proxy;
}
location @proxy {
  proxy_pass http://localhost:9000/; #Apache listening on port 9000;
  # other proxy directives may be needed, e.g. to set Host headers
}
Related Topic