Redirection on Apache (Maintain POST params) - apache

I have Apache installed on my server and I need to redirect from http to https. The reason for this is our load balancer solution cannot hand https so requests come in on http and then we transfer them to https using the below lines in the httpd.conf file.
<VirtualHost 10.1.2.91:80>
Redirect 302 /GladQE/link https://glad-test.com/GladQE/link.do
</VirtualHost>
This works fine for GET requests but POST requests will lose the parameters passed on the URL. What would be the easiest way to perform this redirect and maintain POST params?
I need to get from http://glad-test.com/GladQE/link.do to here https://glad-test.com/GladQE/link.do maintaining POST params
Thanks
Tom

You can try with the HTTP status code 307, a RFC compilant browser should repeat the post request.
Reference: http://en.wikipedia.org/wiki/List_of_HTTP_status_codes
In contrast to how 302 was historically implemented, the request
method is not allowed to be changed when reissuing the original
request. For instance, a POST request should be repeated using another
POST request.
To change from 302 to 307, do that:
<VirtualHost 10.1.2.91:80>
Redirect 307 /GladQE/link https://glad-test.com/GladQE/link.do
</VirtualHost>

Standard Apache redirects will not be able to handle POST data as they work on the URL level. POST data is passed in the body of the request, which gets dropped if you do a standard redirect.
You have an option of either using a PHP script to transparently forward the POST request, or using a combination of Rewrite (mod_rewrite) and Proxy (mod_proxy) modules for Apache like follows:
RewriteEngine On
RewriteRule /proxy/(.*)$ http://www.example.com/$1 [P,L]
P flag passes the request to the Proxy module, so anything that comes to your site (via GET or POST doesn't matter) with a URL path starting with a /proxy/ will transparently be handled as a proxy redirect to http://www.example.com/.
For the reference:
http://httpd.apache.org/docs/current/mod/mod_rewrite.html
http://httpd.apache.org/docs/current/mod/mod_proxy.html

Either your public facing website MUST use SSL to protect confidentiality or there is no sensitive data enver passing through it, and no possibility that your site will ever be used for a lauinchboard for sslstripping (there's a very good reason why Google serve up search results over HTTPS).
If you are not encrypting traffic between browser and your site then why are you trying to encrypt them between your load balancer and your webserver? If you do happen to have a SSL termination outside the load balancer (a very silly approach) then using HTTPS between the load balancer and the webserver is far from efficient. The question also implies lots of other security problems like session fixation/sniffing and SSLStripping vulnerabilities.

Related

How to setup authorization for proxy request a-la x-sendfile?

In a setting of apache + mod_wsgi and nginx + uwsgi, what could be the way to setup web-server to proxy big "intranet" files requests?
What I am thinking about is a way a la x-sendfile, but where the wsgi application points to a file URL "intranet" location in its response, web-server downloads and uploads the file to the original requester without revealing it's "intranet" location. Of course, nothing happens if there is no authentication and access rights check on wsgi application side.
It's very hard to find this kind of setup by googling, not even sure what term to use.
By "intranet" I mean files, accessible via HTTPS requests from the proxy server, which may have its own credentials to them, but not from public internet or by local filesystem (like is the use case with x-sendfile)
If using mod_wsgi in daemon mode, you can return an empty HTTP 200 response with Location response header and when that is seen by the Apache process proxying to the mod_wsgi daemon process, it will evaluate that as a sub request. The path in that could be mapped to a new URL handler in Apache configuration which is actually a proxy setup which sends the request to another downstream backend server. The response from that will then be proxied back to the client. If you don't want that secondary URL handler to be visible outside, ie., someone can't request it direct if they work out the URL path, you need to use a mod_rewrite rule to reject any request if it isn't a sub request.
So you might have something like:
RewriteCond %{IS_SUBREQ} false
RewriteRule ^/hidden/stuff/ - [F]
ProxyPass /hidden/stuff/ http://backend.example.com/
The WGSI response would then be empty HTTP 200 response with Location header of:
Location: /hidden/stuff/some-file-name
The sub request request would end up being:
http://backend.example.com/some-file-name
against backend server with response proxied back to client.

Implicit https for apache redirects when using AWS ELB to terminate SSL

I have an autoscaling application, which uses an ELB to terminate SSL, and forward 443 requests to http 80 on the instances.
This works fine, except that if I do a redirect within apache, it implicitly uses http rather than https.
for example, I have the following rewrite rule...
RewriteRule ^/v10/(.*) /v11/$1 [R]
If I do the following...
curl -v "https://[mydomain.com]/v10/somescript.js"
I get a 302 response like this...
Location: http://[mydomain.com]/v11/somescript.js
... which then breaks my application, as the browser won't load the script via http.
Of course this makes sense, since as far as apache is concerned, it is http. However aside from re-writing all my redirect rules, I'm wondering if there is some way to convince apache to implicitly generate https redirects, even though it isn't terminating the SSL?

301 Redirect and HSTS in .htaccess

I've changed a site to https and have set up a redirect in .htaccess. But I've also set Strict Transport Security. Are both necessary or useful?
<IfModule mod_headers.c>
Header always set Strict-Transport-Security "max-age=16070400"
</IfModule>
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
</IfModule>
Cheers
A redirect tells people who enter http://www.example.com to go to https://www.example.com. Since the default is http, if you leave off the protocol and just type www.example.com then you will go to http://www.example.com so yes you need this redirect.
There's a few problems with this though.
First up http is insecure and can be read, and altered by other people on the network. That's the very reason you should use https. However, as http is insecure, that means they could intercept your redirect and keep you on http version and continue to intercept your traffic. Or alternatively redirect you to https://www.evilexample.com instead.
HTTP Strict Transport Security (or HSTS) is a security mechanism which attempts to address this issue. Your server tells the browser to ALWAYS use https for that site. Even if the don't type the protocol (when http would normally be used) and even if you DO type the protocol as http.
Once a browser has loaded HSTS for a site it will not even send a http request at all and will automatically change these to https instead. This has several advantages:
It's more secure as it cannot be intercepted.
It's quicker as doesn't waste time sending a request to http://www.example.com just to be told to go to https://www.example.com.
It can be used to address mixed content errors as http resources (for that site only but not loaded from other sites) will automatically be changed if you accidentally include a http source. Content Security Policy's upgrade-insecure-requests is probably a better solution for that but HSTS still provides a basic version.
Also as the other answer stated another separate benefit is that this setting also means browsers will not allow visitors to click through certificate errors for this site which adds extra security against attacks.
The main downsides of HSTS are that:
Your site needs to be https only - which may seem obvious but easy to miss part of the site on http only. Or a subdomain on http if using includeSubdomain option.
The visitor needs to visit the site first to pick up the HSTS policy though you can preload this into browsers but that's not a decision to be taken likely.
Browser support is not universal yet. And even if it was crawlers used by search engines and the like probably wouldn't use it.
So hopefully that explains why HSTS is a good thing and is something you should keep. On top of the redirect.
Yes! You should keep both of them. From OWASP docs, there're many benifits to use HSTS. E.g:
automatically redirects HTTP requests to HTTPS.
prevent user from overridding invalid certificate message.
I think you should have a look on this documentation https://varvy.com/pagespeed/hsts.html which says:
It is basically like a 301 redirect, but at the browser level, rather than the webpage level. It is superior to a 301 redirect as it can be implemented to always only use https, whereas 301 redirects are actually unsecure when first seen by a browser.
After reading the documentation, you can decide about it.

mod_pagespeed with SSL: from // to https://

Apache 2.2.15 on RHELS 6.1
Using mod_pagespeed on a server behind https (implemented by the network's Reverse Proxy).
All html urls are written as "//server.example.com/path/to/file.css" (so, without the protocol specified).
Problem : using the default configuration, pagespeed rewrites the urls as "http://server.example.com/path/to/file.css"
I'm trying to figure out how to have it rewrite the urls as https (or leave it unspecified as //).
After reading the documentation, I tried using ModPagespeedMapOriginDomain like this
ModPagespeedMapOriginDomain http://localhost https://server.example.com
Also tried
ModPagespeedMapOriginDomain http://localhost //server.example.com
ModPagespeedMapOriginDomain localhost server.example.com
... To no avail. Urls keep being rewritten with "http://".
Question: how can I have pagespeed use https instead of http in its urls?
Full pagespeed config here, if needed
It turns out mod_pagespeed does not work with "protocol-relative" urls.
Still, the issue is bypassed if you enable trim_urls
ModPagespeedEnableFilters trim_urls
Be mindful of the potential risks (depending on your javascript codebase, ajax calls could break or produce unexpected html).
Adding this to your configuration might work:
ModPagespeedRespectXForwardedProto on
That works, if your reverse proxy forwards the X-Forwarded-Proto header in its requests.
That request header tells PageSpeed what the original protocol was that was used for the request at the loadbalancer, and thereby hands it all it needs to know to correctly rewrite urls.

Level of obscurity of destination URLs via mod_rewrite

To achieve a single layer of content delivery security, I'm looking into the possibility of obscuring a resource URL via an .htaccess RewriteRule:
RewriteEngine on
RewriteBase /js/
RewriteRule obscure-alias\.js http://example.com/sensitive.js
It would of course be implemented as:
<script type="text/javascript" src="obscure-alias.js"></script>
Because this is not a 301 redirect, but rather a routing scenario similar to that of many of our frameworks we used today, would it be safe to say that this RewriteRule adequately obfuscates the actual URL where this resource is located, or:
Can the destination URL still be found out via some HTTP header sniffing utility
Might a web browser be able to reveal the "Download URL"
I'm going to pre-answer my own questions by saying no to both since the "internal proxy" is taking place on the server-side and not on the client side if I understand it correctly: http://httpd.apache.org/docs/current/mod/mod_rewrite.html. I just wanted to confirm that when Apache goes to serve the destination URL, that it also isn't passing along information to the user agent what the URL was that it rewrote the original request as.
It depends on how you specify the redirect target.
If your http://example.com/ is running on the same server, there will be an internal redirect that is invisible to the client. From the manual:
Absolute URL
If an absolute URL is specified, mod_rewrite checks to see whether the hostname matches the current host. If it does, the scheme and hostname are stripped out and the resulting path is treated as a URL-path. Otherwise, an external redirect is performed for the given URL. To force an external redirect back to the current host, see the [R] flag below.
if the absolute URL points to a remote domain, a header redirect will be performed. A header redirect is visible to the client and will reveal the sensitive location.
To make sure no external redirect takes place, specify a relative URL like
RewriteRule obscure-alias\.js sensitive.js
Note that the sensitive JS file's URL can still be guessed.
To find out whether a request results in a header redirect, log in onto a terminal (eg. on a Linux server) and do
wget --server-response http://www.example.com
If the first HTTP/.... line (there may be more than one) is something that begins with a 3xx, like
HTTP request sent, awaiting response...
HTTP/1.1 302 Moved Temporarily
you are looking at a header redirect.
Possible using proxy throughput.
See http://httpd.apache.org/docs/2.4/rewrite/proxy.html
Also alluded to here as well: mod_rewrite not working as internal proxy