I want my app to always use HTTPS on AWS EB production deployment - can you help me use the force-ssl package?

I am trying to get my app to always use HTTPS in production, so I have added this package: https://atmospherejs.com/meteor/force-ssl

However, I’m not seeing it work correctly.

The readme for the force-ssl says the following:

Application bundles (meteor bundle) do not include an HTTPS server or certificate. A proxy server that terminates SSL in front of a Meteor bundle must set the standard x-forwarded-proto header for the force-ssl package to work.

I am deploying to ElasticBeanstalk on AWS and we are in fact using x-forwarded-proto. So I’m not sure why the force-ssl package is not working. I’m also not sure if this note means I should just be using x-forwarded-proto, or whether I should change how it is being used.

From the AWS docs I read the following:

The X-Forwarded-Proto request header helps you identify the protocol (HTTP or HTTPS) that a client used to connect to your server. Your server access logs contain only the protocol used between the server and the load balancer; they contain no information about the protocol used between the client and the load balancer. To determine the protocol used between the client and the load balancer, use the X-Forwarded-Proto request header. Elastic Load Balancing stores the protocol used between the client and the load balancer in the X-Forwarded-Proto request header and passes the header along to your server.

Your application or website can use the protocol stored in the X-Forwarded-Proto request header to render a response that redirects to the appropriate URL.

The X-Forwarded-Proto request header takes the following form:

X-Forwarded-Proto: originatingProtocol

The following example contains an X-Forwarded-Proto request header for a request that originated from the client as an HTTPS request:

X-Forwarded-Proto: https

I don’t think I can just force x-forwarded-proto to always send https – can I?

Also – is it possible that the “flag” on this package means it is broken in some other way? If so, any ideas?

Ok, so I got this working by adding the following lines on the client:

if (window.location.protocol != "https:") {
    if ( ! window.location.host.match(/localhost/)) {
        window.location.href = "https:" + window.location.href.substring(window.location.protocol.length);
    } else {
        console.log('not redirecting to HTTPS for localhost');
    }
}

Now there is no need for me to use the force-ssl package.

3 Likes

But this is delivered over plaintext- What if someone man in the middle’s the connection and removes this logic from your JS payload?

Better off disabling non ssl connections at a lower level (eg through AWS cloudfront or an nginx proxy etc)

1 Like

Github oauth login does not work from non-HTTPS clients, so no harm done from the man-in-the-middle.

Your suggestion of disabling non-ssl connections seems worse to me since then users will just be left in the dark instead of being helpfully redirected.

Sorry - I don’t mean disable non-https connections, I mean re-direct them at a lower level, i.e not in your client side Javascript which relies on being executed safely by the browser

Otherwise you’re potentially exposing your users to a risk for no reason (and it will be slower to switch to https as they have to download the meteor app and execute the JS before redirecting).

Yes, this was what I originally wanted to do – but the force-ssl package does not work.