403 when performing PUT request - apache

I am very new to apache configurations and am trying to learn more. I am getting a 403 - Forbidden when making a PUT request, however a GET to the same URL works fine.
Is there something I need to enable to allow PUT requests?
I am using Apache and PHP

If you are working with Apache 2.4.x, a faulty or missing "Require" directive could the cause of the 403.
In the <Directory> block of your virtualhost config, or your .htaccess file add the following line:
Require all granted
For details on the "Require" syntax see: https://httpd.apache.org/docs/2.4/mod/mod_authz_core.html#require

Related

404 not being caught?

I have been running some automated security scans and the following URL triggers a 404:
/%FF%FE%3Cscript%3Ehaikumsg%28326%29%3C%2Fscript%3E
This is run from the route on the domain on an Apache server (so this should be easy to replicate).
My htaccess is setup with ErrorDocument 404 /site/404 but this isn't being caught. I know this because if I completely empty the htaccess file I am still presented with the same standard apache 404 page.
Clearly this is a tag hack so I have to be careful how its handled, however I'd like to know how to manage it so it at least does my /site/404 instead of nothing.
It turns out the solution is to move your 404 redirect to the Vhosts not htaccess!! Very simple solution and that will fix it. Apache obviously works with the URL before even getting to the htaccess file so moving the 404 redirect is needed at a higher level.
However if you need to decode and use the URLs then the following begins to help:
https://serverfault.com/questions/261683/how-does-apache-process-a-path-with-a-percent-encoded-url-in-it
Basically the solution is to add AllowEncodedSlashes On to the Vhosts file.
As per https://httpd.apache.org/docs/2.0/mod/core.html#allowencodedslashes.

Internal server error with Apache 2.4 in .htaccess on WAMP

The Apache 2.4 documentation mentions .htaccess as a valid context for using the <FilesMatch> directive, with, for example, a Require all denied in it.
Ref: https://httpd.apache.org/docs/2.4/en/mod/core.html#filesmatch
Yet, it leads to a 500 Internal Error if I place it in an .htaccess, and no error if I place it in the main configuration file.
However, it seems like it is less the FilesMatch directive that is a problem than the Require all denied, as no errors occurs if I leave the former empty.
Example of the block that I use:
<FilesMatch "[\._](htaccess|passwd|inf|ini|inc|cls)$">
Require all denied
</FilesMatch>
Any idea of how to make it work in the .htaccess file?

Debugging Apache AllowMethods error

We are running an API for our mobile app, and with the right HTTP headers, have been able to enable developing it locally using the live API without the need of a 'CORS plugin'.
Now, it does not work anymore, probably since moving the domain name from one user to another (using DirectAdmin), but I cannot figure out how to fix it. Moving the domain back to the original user does not fix it. We have been running Apache 2.4 for quite a while already, that's nothing new.
I tried adding the following to httpd.conf:
<Location /api>
AllowMethods GET POST OPTIONS DELETE PUT
Require all granted
</Location>
<Directory /home/username/domains/example.com/private_html/www/api>
AllowMethods GET POST OPTIONS DELETE PUT
Require all granted
</Directory>
I verified being in the right VirtualHost block by successfully changing the ErrorLog file location.
I also added Require all granted to all .htaccess documents from the private_html folder to the api folder, but the error log keeps saying: [allowmethods:error] [pid ...] [client ...] AH01623: client method denied by server configuration: 'OPTIONS' to /home/username/domains/example.com/private_html/www/api
Note that our mobile app actually still works (GET and POST), but PUT and DELETE don't, just like OPTIONS. It seems like the requests never even hit my domain folder, but get stuck in Apache config.
How can I debug this? How can I get Apache to tell me which policy is preventing that method?
I finally solved the issue with this httpd.conf block:
<Location "/">
AllowMethods GET POST OPTIONS DELETE PUT
Require all granted
</Location>
I was originally trying to limit that to just the API URL, but apparently that gets complicated because of RewriteRules. The first request on /api is passed through, but I needed a new block for each RewriteRule that happens. So I just used Location "/" to fully allow it... hope that doesn't introduce security issues.
#Sygmoral
This also fixed my problem!
If you ever get this message inside a new DirectAdmin environment getting the response on a OPTIONS method:
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>405 Method Not Allowed</title>
</head><body>
<h1>Method Not Allowed</h1>
<p>The requested method OPTIONS is not allowed for this URL.</p>
</body></html>
Or if you've checked the apache error logs containing: AH01623: client method denied by server configuration: 'OPTIONS'
You should head out to the section in DirectAdmin " Custom HTTPD Configurations " (as admin) and add the lines to your domains custom httpd.conf:
<Location "/">
AllowMethods GET POST OPTIONS DELETE PUT
Require all granted
</Location>

Apache 2.4 + PHP-FPM and Authorization headers

Summary:
Apache 2.4's mod_proxy does not seem to be passing the Authorization headers to PHP-FPM. Is there any way to fix this?
Long version:
I am running a server with Apache 2.4 and PHP-FPM. I am using APC for both opcode caching and user caching. As recommended by the Internet, I am using Apache 2.4's mod_proxy_fcgi to proxy the requests to FPM, like this:
ProxyPassMatch ^/(.*\.php)$ fcgi://127.0.0.1:9000/foo/bar/$1
The setup works fine, except one thing: APC's bundled apc.php, used to monitor the status of APC does not allow me to log in (required for looking at user cache entries). When I click "User cache entries" to see the user cache, it asks me to log in, clicking on the login button displays the usual HTTP login form, but entering the correct login and password yields no success. This function is working perfectly when running with mod_php instead of mod_proxy + php-fpm.
After some googling I found that other people had the same issue and figured out that it was because Apache was not passing the Authorization HTTP headers to the external FastCgi process. Unfortunately I only found a fix for mod_fastcgi, which looked like this:
FastCgiExternalServer /usr/lib/cgi-bin/php5-fcgi -host 127.0.0.1:9000 -pass-header Authorization
Is there an equivalent setting or some workaround which would also work with mod_proxy_fcgi?
Various Apache modules will strip the Authorization header, usually for "security reasons". They all have different obscure settings you can tweak to overrule this behaviour, but you'll need to determine exactly which module is to blame.
You can work around this issue by passing the header directly to PHP via the env:
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
See also Zend Server Windows - Authorization header is not passed to PHP script
In some scenarios, even this won't work directly and you must also change your PHP code to access $_SERVER['REDIRECT_HTTP_AUTHORIZATION'] rather than $_SERVER['HTTP_AUTHORIZATION']. See When setting environment variables in Apache RewriteRule directives, what causes the variable name to be prefixed with "REDIRECT_"?
This took me a long time to crack, since it's not documented under mod_proxy or mod_proxy_fcgi.
Add the following directive to your apache conf or .htaccess:
CGIPassAuth on
See here for details.
Recently I haven'd problem with this arch.
In my environement, the proxy to php-fpm was configured as follow:
<IfModule proxy_module>
ProxyPassMatch ^/(.*\.php)$ fcgi://127.0.0.1:9000/usr/local/apache2/htdocs/$1
ProxyTimeout 1800
</IfModule>
I fixed the issue set up the SetEnvIf directive as follow:
<IfModule proxy_module>
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
ProxyPassMatch ^/(.*\.php)$ fcgi://127.0.0.1:9000/usr/local/apache2/htdocs/$1
ProxyTimeout 1800
</IfModule>
I didn't find any similar settings with mod_proxy_fcgi BUT it just works for me by default. It asks for user authorization (.htaccess as usual) and the php gets it, and works like with mod_php or fastcgi and pass-header. I don't know if I was helpful...
EDIT:
it only works on teszt.com/ when using the DirectoryIndex... If i pass the php file name (even if the index.php!) it just doesn't work, don't pass the auth to the php. This is a blocker for me, but I don't want to downgrade to apache 2.2 (and mod_fastgi) so I migrate to nginx (on this machine too).

How to enable ErrorDocument for 400 error?

I have installed apache2 on my ubuntu machine. As I need to work with subdomains I created a proper entry in sites-available which looks like this:
<VirtualHost *:80>
ServerName xxx.localhost
DocumentRoot /var/www/
</VirtualHost>
I also enabled mod_rewrite (and changed "AllowOverride All" in my sites-available/default file) but other than that nothing else was changed.
My .htaccess file does work, and I wanted to handle some error codes. Doing so with 404 worked pretty well, but for some reason other errors don't seem to work. I'm mostly interested in handling error 400:
ErrorDocument 400 /400.php
ErrorDocument 404 /404.php
Is there anything else I should look at? I couldn't seem to find any place where 404 are allowed while other error codes aren't.
If the php is returning the 400 error, then php should generate the error document.
Use something like:
if( $someError )
{
http_response_code(400);
include("{$_SERVER['DOCUMENT_ROOT']}/400.php");
exit();
}
From the Apache documentation:
Although most error messages can be overriden, there are certain circumstances where the internal messages are used regardless of the setting of ErrorDocument. In particular, if a malformed request is detected, normal request processing will be immediately halted and the internal error message returned. This is necessary to guard against security problems caused by bad requests.
Try adding it directly in the httpd.conf and restart Apache.