1

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.

Zilk
  • 351
  • 4
  • 9
  • 1
    The basis for doing on per directory is that you are afraid that it will make dos attacks easier. What is your reasoning that allowing bigger uploads will make dos attacks easier? If the file uploading is done in the CMS backend (which Im sure has access control), how will the attacker access the uploading mechanism? – Josh Brower Jul 12 '10 at 19:03
  • They can't access the CMS, but they could just post to any other .php file (by building their own form). I've thought about this some more, and I've discovered that I have an even bigger problem. The way Apache is set up in the distro I'm using, POST is allowed to any resource - even images and other static resources. Ideally, POST should be disallowed for any resource type other than PHP, and then PHP's internal settings could be used to limit the request size. I need to figure out how fix this first. Thanks for asking the right question to get my brain going. – Zilk Jul 23 '10 at 23:04

2 Answers2

2

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
}
ColinM
  • 701
  • 8
  • 19
  • +1 for question archaeology. 5 years later, I would agree that adding a proxy in front of the application/web server is the best defense against DoS (and other types of attack). – Zilk Sep 30 '15 at 15:09
  • @Zilk Hehe, yes I noticed it was an old question. Maybe I'll get the Necromancer badge. :) Found the question via Google when looking for the answer myself so once I found the solution figured I might as well keep SO relevant. – ColinM Sep 30 '15 at 21:55
-1

First try if it works at least using '/':

<LocationMatch ^/>

If yes, then try one of these:

<LocationMatch ^/start.php\?_p=/admin>

<LocationMatch ^/start.php?_p=/admin>

<LocationMatch _p=/admin>

Pleae also note that:

< Location> sections are processed in the order they appear in the configuration file, after the sections and .htaccess files are read, and after the sections.

src: http://httpd.apache.org/docs/2.0/mod/core.html#location

Weboide
  • 3,345
  • 1
  • 25
  • 33