problems using mod_headers with php-fpm/mod_fastcgi - apache

I'm trying to add HSTS headers to every response, across my app.
My first thought was to use mod_headers — I placed this directive in an .htaccess file at the documentroot:
Header set Strict-Transport-Security "max-age=7776000"
This works fine on my local setup using Apache 2.2 and mod_php. All resources respond with the appropriate HSTS header.
My deployment environment uses Apache 2.2 and mod_fastcgi and the above technique works for any resource except php files.
Another SO question had a similar problem, where incoming requests (?) had headers stripped — but I'm concerned about modifying headers of response leaving the server.
How can I add response headers to php resources in the context of an .htaccess file?

According to the docs for mod_headers you probably need to set the optional conditional flag for the header directive.
So in this case, it would become
Header always set Strict-Transport-Security "max-age=7776000"

Related

HSTS Preload differing results

On one of my sites I have Header set Strict-Transport-Security "max-age=31536000" env=HTTPS and this was enough for HSTS to be preloaded but the exact same snippet in my .htaccess file doesn't allow preloading on another site. I've went with Header set Strict-Transport-Security: "max-age=31536000; includeSubDomains; preload" env=HTTPS which fixed the issue but I'm wondering why the shorter version worked and preloaded a the first site but not the second?
Any insight would be appreciated.
why the shorter version worked
The short version couldn't have "worked". It would have been sufficient to implement HSTS, but not to have been accepted for the HSTS preload list.
Something else in your config must have been sending the complete header.
The only way to confirm what is actually going on is to record the HTTP request/response headers being sent on the request, not by the directives in your (.htaccess?) config file.
Even the directive you posted is not necessarily sufficient by itself. You must have something that is setting the HTTPS environment variable (this is not the same as the HTTPS server variable). And if you have canonical redirects from www to non-www (or vice versa) then you are missing the always argument to set the header on the 301 redirect (HTTPS only) - which is also a requirement of the "preload list".
It is far easier and less prone to error to implement HSTS "preload" in the server config. If you only have access to .htaccess then I would be hesitant to go for "preload list" submission.
See also my answer to the following related question on CodeReview SE:
https://codereview.stackexchange.com/questions/250805/hsts-recommendations-in-htaccess

Apache2 no cache specific file only

I'm running and Amazon EC2 with Ubuntu 14.4 and Apache2 with no PHP or other server-side script--just a static content site. I used this tutorial to get to the point I am at now with the apache file (see screenshot at link below):
https://www.digitalocean.com/community/tutorials/how-to-configure-apache-content-caching-on-ubuntu-14-04
I want to have a directive (if that is the nomenclature) that tells Apache to not cache a single, specific file only, but still handle everything else as it is already configured. I'm no computer whizz here--just learning. Is there a way to do this? Currently I have made a new directory inside my images folder called "no-cache" where the image I do not want cached lives.
I tried adding a second location tag below the first one with "CacheDisable on" inside it, however this is not supported. Also tried using a Directory tag, but this also does not work with the current configuration.
Thanks in advance!
/etc/apache2/sites-enabled/000.default.conf
The link you provided is a bit confusing since it mentions so many different types of caching.
When dealing with Webservers and caching, what you usually mean is sending cache messages (using http headers) to define how the browser should handle caching, to improve visitors performance. This is the last item discussed in that link of yours, despite being the most common. The first section talks about Apache caching files itself to improve its own performance and is much less common.
If client side caching using mod_expiries is what you mean, then you can control this with location headings:
#Allow long term assets to be cached for 6 months as they are versioned and should never change
<Location /assets/libraries/ >
ExpiresDefault A15724800
Header set Cache-Control "public"
</Location>
#Do not cache these files
<Location /login >
Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
Header set Pragma "no-cache"
</Location>
I've a more detailed blog on this here: https://www.tunetheweb.com/performance/http-performance-headers/caching/.

mod_rewrite: add a header if it doesn't already exist

I am attempting to add CORS handling using apache and mod_rewrite. The apache instance is front-ending multiple tomcat applications using mod_jk. Some of these applications have their own logic for adding CORS headers Access-Control-Allow-Origin, Access-Control-Max-Age, etc.
For the applications that didn't take care of the CORS logic, I would like to manage it on apache using mod rewrite.
Does anyone know if its possible to add a header to an HTTP response using mod_rewrite only if the header doesn't already exist? The browser reports an error if the CORS origin header is written twice.
mod_rewrite is to rewrite url's, not to set headers. What you want to use is mod_headers (documentation).
I don't know if mod_rewrite runs before mod_headers, but I would suggest to set environment variables using SetEnvIf instead (documentation).
You can do something like this:
SetEnvIf Request_URI "^/my/app/(.*)/?$" ADDHEADERS=1
Header set Access-Control-Max-Age 123456 env=ADDHEADERS

Can mod_headers change headers generated by uWSGI?

I have a uWSGI service running behing an apache front-end. The part of my apache conf handling that lools like:
<Location /myapp>
SetHandler uwsgi-handler
uWSGISocket /var/run/uwsgi/myapp.sock
Allow from all
</Location>
and I'd like to add a custom header to the responses of my app. I know I can do that by adding some code in the app, but I would prefer doing it with mod_headers, by adding the following line in the Location directive
Header set Custom-Header "hello world"
It does not seem to work, although mod_headers documentation states
This directive can replace, merge or remove HTTP response headers.
The header is modified just after the content handler and output filters are run,
allowing outgoing headers to be modified.
What do I do wrong, or understand wrong?
As stated in the docs mod_uwsgi is very raw and uses the 'assbackwards' mode, unless you enable the CGI mode. This mode (assbackwards) gives superior performance but breaks basically all of the filters. You should use mod_proxy_uwsgi (fully apache-friendly) or let uWSGI do the hard work for you using the internal routing:
http://uwsgi-docs.readthedocs.org/en/latest/InternalRouting.html
(or the --add-header more invasive option)

Authorization header missing in django rest_framework, is apache to blame?

I've managed to extend TokenAuthentication and I have a working model when using the request session to store my tokens, however when I attempt to pass Authorization as a header parameter as described here, I noticed that my Responses come back without the META variable HTTP_AUTHORIZATION. I also noticed that if I pass "Authorization2" as a header parameter that it is visible in the request:
{
'_content_type': '',
'accepted_media_type': 'application/json',
'_request': <WSGIRequest
path:/api/test_auth/,
GET:<QueryDict: {}>,
POST:<QueryDict: {}>,
COOKIES:{
'MOD_AUTH_CAS_S': 'ba90237b5b6a15017f8ca1d5ef0b95c1',
'csrftoken': 'VswgfoOGHQmbWpCXksGUycj94XlwBwMh',
'sessionid': 'de1f3a8eee48730dd34f6b4d41caa210'
},
META:{
'DOCUMENT_ROOT': '/etc/apache2/htdocs',
'GATEWAY_INTERFACE': 'CGI/1.1',
'HTTPS': '1',
'HTTP_ACCEPT': '*/*',
'HTTP_ACCEPT_CHARSET': 'ISO-8859-1,utf-8;q=0.7,*;q=0.3',
'HTTP_ACCEPT_ENCODING': 'gzip,deflate,sdch',
'HTTP_ACCEPT_LANGUAGE': 'en-US,en;q=0.8',
'HTTP_AUTHORIZATION2': 'Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4c',
...
My first guess is that the authorization header is being removed by apache, and I have read a few S/O questions that state that apache will throw out the value if it does not match basic authorization and authenticate, but I have no idea how to allow the Authorization header to 'pass through' to Django and the WSGIRequest. Does anyone know how to solve this problem?
I also use mod_auth_cas and mod_proxy, if that changes anything..
If you are using Apache and mod_wsgi, then I found the easy solution to this in the official Django REST framework website
Apache mod_wsgi specific configuration
Note that if deploying to Apache using mod_wsgi, the authorization header is not passed through to a WSGI application by default, as it is assumed that authentication will be handled by Apache, rather than at an application level.
If you are deploying to Apache, and using any non-session based authentication, you will need to explicitly configure mod_wsgi to pass the required headers through to the application. This can be done by specifying the WSGIPassAuthorization directive in the appropriate context and setting it to 'On'.
# this can go in either server config, virtual host, directory or .htaccess
WSGIPassAuthorization On
Sorry to answer my own question minutes after asking it. But it turns out it was apache2 after all! After crawling the webs and looking through a few search results I found this in a comment:
RewriteEngine on
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]
Adding the above lines to my conf file seemed to solve all of my problems! Hopefully this helps users down the road!
It depends on which kind of Django/Apache deployment you did. You need to tell the correct Apache module to allow to pass "Authentication" HTTP header:
Apache/mod_wsgi:
WSGIPassAuthorization On
Apache/mod_fcgid:
FcgidPassHeader Authorization
In other words: many Apache modules filters "Authentication" HTTP header, so Django will not receive it. You have to be sure your Django App is receiving it in request.
See:
django_rest doc and Apache fcgid doc.
NOTE:
After modifying Apache configuration you'll need to restart apache daemon or tell to reload your .cgi file (i.e: touch my_site_fcgifile.fcgi).
The issue is the underscore in the HTTP header HTTP_AUTHORIZATION. Most webservers just ignores the headers with underscores.
Django dev server also exhibits the same, omitting headers with underscores.
This is the reason why Authorization2 works.
A Quick work around is to replace _ underscores in headers with - dashes,
Ex. changing the HTTP_AUTHORIZATION to HTTP-AUTHORIZATION