Strict-Transport-Security influence on http reverse proxy that redirects to https - apache

The server response comes with HSTS header, and since I'm using reverse proxy HSTS header is also being sent through proxy response.
Since there are different domains (proxy and server) does HSTS make the browser automatically change the schema from http://proxyhost.com to https://proxyhost.com? or the preload list will call automatically https://serverhost.com when the user will request http://proxyhost.com?

does HSTS make the browser automatically change the schema from http to https
Indeed! and since:
a reverse proxy HSTS header is also being sent through proxy response.
... the configuration of a reverse proxy can involuntarily make your domain set theHSTS header.
Took some while to see why my apache server sets the HSTS header - for I hadn't configured that in the apache web server. It was due to a ReverseProxy: as the foreign domain sets theHSTS header this header comes then (reverse proxy!) with my domain's name. This was then propagated to the client's browser which stores it. Thus, all my domain's sites (and in this case also all my subdomains!) where forced to use https (not when using e.g. curl of course, but firefox, chromium etc.).
Thanks for your question - it was already the perfect direction!
In my case I simply could use aRewriteRule instead of a reverse proxy :) but this of course depends on your scenario.
You also gave the proper answer in your comment:
in this case I should unset HSTS header in the reverse proxy
Right! Just add Header unset Strict-Transport-Security directly after the ProxyPassReverse directive, and you can use a reverse proxy without inherit the HSTS header.

Related

Apache Server: Redirection via http headers

I am trying to force browser to use https even when the user enters http URL. The idea is to use http response headers from the server. I am able to implement redirection using redirect (in site.conf) & Rewrite (which is disliked universally) but want to test out this method too.
Now I have tried adding the the following to my /etc/apache/sites-enabled/mysite.conf but despite the browser receiving the header response the user is not redirected to https (default apache page is shown):
Header set Location https://www.example.com/
Header set X-Forwarded-Proto: https
Header set Strict-Transport-Security "max-age=180; includeSubdomains"
Do I have to change anything else in the apache configuration to achieve this? (all modules are correctly loaded)
The Location header is only used for redirect responses (with a HTTP response code of 3XX) or Created responses (with a HTTP response code of 201):
https://www.rfc-editor.org/rfc/rfc7231#section-7.1.2
Just setting the header on a random page will not make the browser redirect.
When you use apache Redirect and Rewrite rules they set the response header AND add the location header. I really don't know why you'd want to do this manually.
And rewrite is not "universally disliked". It just overused when redirect would be simpler and more efficient in a lot of cases. If you need something more complicated then Rewrite is the right tool to use.
Finally you should not sent the Strict-Transport-Security header on a HTTP response (and the browser will rightly ignore it you do) but only on a HTTPS responses.

Request Header (Host attribute) lost/Reset from WebSeal to Apache web server

URL (https://xyz.abc.com/cc) when load balancer see /cc it will forward request to WebSeal (Revers Proxy server).
WebSeal add/set (Header Host : xyz.abc.com) and forward request to Apache2 (web server). In web seal we have standard junction (/cc) which will process the request from LB.
When request comes to Apache2 it loosing HOST header value (xyz.abc.com) and reset it to Apache2 server name (xyzapacheweb1)
Now finally request pass from apache2 to Liferay Portal (6.2) and it showing URL (xyzapacheweb1) instead of (xyz.abc.com)
Liferay need HOST name when web server fronting so we have to hard code URL (in property file or in apache2)
We want to remove Hard-Code value and pass dynamic host name so we can use multiple URLs for individual applications.
Note : When we don't have WebSeal in picture it preserve the HOST name. i.e. Apache2 show actual domain name (xyz.abc.com)
Can you please help me to resolve this problem?
Let me know if you need more info.
If you're using mod_proxy to forward from apache to tomcat you're missing the option
ProxyPreserveHost On
This is because of forwarding through http. If you're using ajp this is automatically taken care of for you by the protocol.
I'm not sure of the equivalent option for webseal though, maybe the apache one helps you to find it
I came up with two solutions.
Temporary :
Set custom header attribute in request from WebSeal i.e. domain-host-name. From LB -> WebSeal set the host value to this variable.
Apache web server is able to retrieve this value because it's not default request header. Based on the domain-host-name value Set Header HOST value from Apache webserver for Liferay.
remove web.server.host.name property in Liferay it will automatically get the HOST value (which was set by Apache).
Set xyz.abc.com if domain-host-name is set to xyz.abc.com
SetEnvIf domain-host xyz.abc.com HAVE_MyRequestHeader
RequestHeader set Host xyz.abc.com env=HAVE_MyRequestHeader
Set abc.xyz.com if domain-host-name is set to abc.xyz.com
SetEnvIf domain-host abc.xyz.com HAVE_MyRequestHeader_1
RequestHeader set Host abc.xyz.com env=HAVE_MyRequestHeader_1
This is a temporary solution because here we have to hardcode host name check in Apache. So if there is new URL then you have to configure it in Apache.
Permanent :
WebSeal has Virtual Junction concept. Where webseal can be configure to play virtual hosting role.
Please refer : http://www-01.ibm.com/support/knowledgecenter/SSPREK_6.1.1/com.ibm.itame.doc_6.1.1/am611_webseal_admin642.htm%23vhost-scenario1?lang=en
Let me know if you are facing similar type issue I can help to resolve it.

Apache & Tomcat reverse proxy with basic authentication: Can Tomcat receive the username?

I've successfully configured Apache to listen over SSL/443 and proxy Tomcat listening on HTTP/8080. I have also set up basic authentication in Apache.
Once the user connects to my Tomcat servlet, will the HttpServletRequest.getRemoteUser() be populated or null. If null, how might I get the remote user?
The simplest solution may be to use mod_proxy_ajp, which in addition to proxying requests also transfers a variety of metadata to Tomcat, including authentication information such as REMOTE_USER.
These docs for Alfresco discuss this configuration, which includes changes on both the Tomcat side (so that it knows to trust the forwarded authentication) and the Apache side.
If you're using a generic http proxy like mod_proxy, you would need to arrange for Apache to add the value of REMOTE_USER to the request (possibly as an X- header), and then arrange for your Tomcat application to recognize and trust that header (and you would obviously need to arrange for your front-end proxy to strip that header from any incoming requests).
I don't know how you would do this on the tomcat side, but this post seems to have some suggestions.
I needed to add
<Location />
Order allow,deny
Allow from all
RequestHeader unset Authorization
</Location>
to the wrapping location, the RequestHeader being the specialty that fixed it.
I found this (again) via http://codeblow.com/questions/remove-fundamental-authentication-header-with-apache-mod-proxy/ - don't know where I originally found it last year, it was a last measure for some security issue.

Unset or Expire HSTS Policy on Apache Server

I set this line in a ssl vhost on my server. I am running Apache 2.x
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains"
This was a major mistake, because now I want to remove it and force users back to http pages sometimes. It was not enabled for very long, but I don't want to lose anyone. If I try to force users back to http pages right now they end up in a redirect loop.
How can I unset or expire HSTS using settings on the server so that when users do visit the site and hit the https version of the site the Strict-Transport-Security setting is removed from their browser and they are able to be redirected to http?
I already know I made a dumb mistake. I learned a lesson and just need to clean it up now.
Figured it out:
NOTE: A max-age value of zero (i.e., "max-age=0") signals the UA to
cease regarding the host as a Known HSTS Host, including the
includeSubDomains directive (if asserted for that HSTS Host).
See also Section 8.1 ("Strict-Transport-Security Response
Header Field Processing").
From the RFC 6797 document.
So, I will just set the following line and leave it for a few months before removing it.
Header always set Strict-Transport-Security "max-age=0; includeSubDomains"

How to remove a cookie in Apache

I need to remove a cookie from the HTTP request that gets to the server. Doing it on the client (that writes this cookie) or on the server (that reads it) is not an option. I have Apache 2.0 that proxies requests between client and the server, so I was hoping to remove the cookie right there in Apache using mod_rewrite.
My question is, is there a way to remove a certain cookie from the HTTP request using mod_rewrite?
If not possible to remove just one cookie then as a last resort to remove all cookies from the request?
I am open to other suggestions of how to accomplish this if mod_rewrite is not the right tool for this task.
Apache mod_rewrite allows manipulation of URLs but not of HTTP headers, however 'mod_headers' will let you do that.
So, you could use:
RequestHeader unset Cookie
This will strip all cookies from the request. I'm not sure if its possible to remove just a particular cookie using this technique.
Alternatively, you can stop cookies being passed back to the client using:
Header unset Set-Cookie
if that's more appropriate.
With Apache > 2.2.4, you could have used :
RequestHeader edit Cookie "^(.*?)ANY_COOKIE=.*?;(.*)$" $1$2
You can manage specific cookies using following statements in apache reverse proxy configurations:
To remove any specific cookie you can use:'Header add Set-Cookie "ANY_COOKIE='';expires='SOME_DATE_IN_PAST'; Max-Age=0; Path=COOKIE_PATH"'
By specifying past date, you tell the browser that the cookie has expired and browser will discard the cookie.
To add any cookie you can use:'Header add Set-Cookie "ANY_COOKIE='ANY_VALUE';expires='SOME_FUTURE_DATE'; Path=COOKIE_PATH"'
Be sure that you specify the some future date. If you do not specify any date, the cookie will be treated as session cookie.
Try using the following to remove specific cookie from request:
'RequestHeader add Cookie "ANY_COOKIE='';expires='SOME_PAST_DATE'; Path=COOKIE_PATH"'
I use this to unset all cookies (good to serve static content)
Header unset Cookie
Header unset Set-Cookie