Bypass basic authentication for Content-Security-Policy reporting requests
If your site is using "Content-Security-Policy" (CSP) headers, you maybe want to know if there are violations. For this reason, the CSP standard provides report-uri (deprecated) or report-to options to tell your browser an endpoint, where it automatically reports the violations with additional information.
And maybe you and your customers want to test the CSP implementations on a non-public staging system before deploying it to production.
At least, this was my scenario a few days ago: I am working on a TYPO3 upgrade from version 11 LTS to version 12 LTS, which introduces a very nice optional feature with CSP headers and also includes a reporting module in the backend, which I wanted to use.
Firefox #
Unfortunately, I realized that my favorite browser Firefox does not send the authorization header to the CSP reporting endpoint. The authorization header would be required in my case, because the complete staging system is for internal use only and is protected by a basic authentication password protection
As you can see in the request headers, there is no "Authorization" header and the response code is 401 which means "Unauthorized"
Chromium #
To my surprise, all chromium based browsers do it correctly.
As you can see in the request headers, there is and "Authorization" header and the response code is 200 which means "OK"
Skip Authentication for CSP Reportings #
If you have an Apache server, the solution is only three lines away, if you know what you need to do. If you are running another server, I'm pretty sure you can use this inspiration and will know the right syntax to do it for your case.
Initial situation #
Let's assume, we have this simple Basic Auth configuration:
AuthName "Password Protected Area"
AuthType Basic
AuthUserFile /var/www/files/.htpasswd
Order Deny,Allow
Satisfy any
Deny from all
Require valid-user
Modifications #
First of all, we need to detect CSP reporting requests and set an environment variable. In this case, we use the
variable name noauth
but it will work with other names, too.
With this first additional line, we introduce condition to check the Content-Type
header and if it is identical with
application/csp-support
, the variable noauth=1
is set.
SetEnvIfExpr "%{HTTP:Content-Type} == 'application/csp-report'" noauth=1
The other two lines must be placed inside the authentication block. The first line tells the server to not necessarily
require a valid user, but also accept another criteria. The other allowed criteria is introduced in the last line and
says, if the environment variable noauth
is set, it also is a valid call.
Satisfy any
# ...
Allow from env=noauth
I'm not absolutely sure, if the order of the lines matter. But this is my solution, and it works as I expect:
# set an environment variable "noauth" for known CSP content-type
SetEnvIfExpr "%{HTTP:Content-Type} == 'application/csp-report'" noauth=1
# deny and allow access
AuthName "Password Protected Area"
AuthType Basic
AuthUserFile /var/www/files/.htpasswd
Order Deny,Allow
Satisfy any
Deny from all
Require valid-user
Allow from env=noauth