4

I would like to modify an existing Nginx location block to serve an HTTP 403 status to any PHP files in the .well-known directory and its subdirectories. I am using .well-known for legitimate purposes, but a recent server compromise has shown I need to be a lot more strict on what's permitted.

My current Nginx location block is:

    location ^~ /.well-known/ {
        allow all;
        default_type "text/plain";
        root /var/www/example.com/_well-known/;
        try_files $uri/ $uri =404;
    }

The root is deliberately outside the public HTML directory (which is at /var/www/example.com/live/ if it's relevant).

How can I modify this block or provide an additional location block to serve HTTP 403 to all PHP file requests under the .well-known directory?

Thank you.

4
  • Have you configured nginx to execute php files it serves? If not, I don't see the need to 403 php files in .well-known. If yes, then I recommend not having the webserver execute php files, but instead proxy such request to a dedicated application server (such as php-fpm). Or otherwise at least limit such execution to the location blocks that actually need it.
    – marcelm
    Commented Aug 4 at 13:08
  • @marcelm I am using PHP-FPM for legitimate PHP usage inside the public directory. I am unsure as to how malicious files ended up outside the public HTML directory, though I suspect errant permissions on my part (which I think are now addressed). Commented Aug 4 at 15:04
  • Ah, unknown php files showed up there? Then the cause of that really needs to be determined. It suggests that there's a security hole (perhaps in the php application) that allows an attacker to upload files to arbitrary paths, which is a huge issue. Find and fix the cause for that. Just because different permissions might've stopped that attack at that particular location doesn't mean there's not still a security hole with file uploads. Find the real issue. Honestly, configuring nginx to not serve those php files seems neither necessary nor helpful to me.
    – marcelm
    Commented Aug 5 at 7:39
  • 1
    @marcelm You're absolutely right, and I agree. It was a dubious Wordpress plugin and a legacy account for a rogue Wordpress admin that appears to be the culprit. I'm not just restricting access to PHP in .well-known, it's part of a list of measures I'm taking. There is no valid need (to my knowledge) to have PHP scripts in there so it's a belt-and-braces approach. Thank you for your perspective, I do appreciate it. Commented Aug 5 at 9:09

3 Answers 3

3

You need a regular expression location block to match URLs that end with .php.

The ^~ operator on the current location block means that this new regular expression location block must be nested within the existing block.

For example:

location ^~ /.well-known/ {
    allow all;
    default_type "text/plain";
    root /var/www/example.com/_well-known/;
    try_files $uri/ $uri =404;

    location ~* \.php$ { return 403; }
}

Any URL that begins with /.well-known/ and ends with .php will result in a 403 status.

3
  • Either the order of paragraphs in the documentation for the location directive is confusing or regex directives inside a ^~ block won't work either; it is mentioned below the "some exceptions mentioned below". Commented Aug 4 at 7:23
  • 1
    Nginx documentation is ambiguous at times. But the ^~ operator affects the evaluation of location statements within the same context. Nested location blocks are not affected. FYI the "mentioned below" refers to the = and @ paragraphs. Commented Aug 4 at 8:50
  • Good to know, and that is also way more logical. What a poor documentation. Commented Aug 4 at 9:50
2

You could to use nested locations like this:

location ^~ /.well-known/ {
    . . .
    location ~ \.php$ {
        deny all;
    }
}

...although the documentation suggests this should fail:

location blocks can be nested, with some exceptions mentioned below.

If the longest matching prefix location has the “^~” modifier then regular expressions are not checked.

Another option would be to remove the ^~ modifier and add a regex location that matches .php in /.well-known/.

location /.well-known/ {
    . . .
}

location ~ ^/.well-known/.*\.php$ {
    deny all;
}

location ~ \.php$ {
    . . .
}
-2

To modify your existing Nginx configuration to serve an HTTP 403 status to any PHP files in the .well-known directory and its subdirectories, you can add an additional location block within the existing one to handle PHP files specifically. Here is the updated configuration:

    location ^~ /.well-known/ {
    allow all;
    default_type "text/plain";
    root /var/www/example.com/_well-known/;
    try_files $uri/ $uri =404;

    # Deny access to PHP files
    location ~* \.php$ {
        deny all;
    }
}
1
  • 1
    Isn't this just a copy of the answer from Richard? Commented Aug 4 at 9:43

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .