Force HTTPS
The Force HTTPS feature will ensure that your users will be reaching an application through HTTPS only.
Context
HTTPS is enabled by default for all the applications deployed on the platform. Once deployed an application can be accessed either with HTTP or HTTPS:
http://my-app.osc-fr1.scalingo.io
https://my-app.osc-fr1.scalingo.io
Or, once a custom domain has been added:
http://example.com
https://example.com
Activating the Force HTTPS feature enforces HTTPS access to all the domains
attached to the application. It is achieved by activating a permanent
redirection from HTTP to HTTPS and injecting the Strict-Transport-Security
header (abbreviated HSTS) in HTTPS responses.
Force HTTPS a Scalingo Application
Scalingo eases the process for you to enable “Force HTTPS” on your application. Head to the Settings tab of your web dashboard, in the Routing section, check “Force HTTPS”:
Or using the CLI:
scalingo --app my-app force-https
Technical Details
Permanent Redirect (301) from HTTP to HTTPS
Any request done to the application using HTTP will be redirected
using the status code 301
. It means browsers will remember this redirection
over time:
$ curl --head http://my-app.osc-fr1.scalingo.io
HTTP/1.1 301 Moved Permanently
Date: Thu, 22 Aug 2024 09:08:18 GMT
Content-Type: text/html
Connection: keep-alive
X-Request-ID: aa5e0e4e-5e3f-4e36-b4d4-c5f65a47812f
Location: https://my-app.osc-fr1.scalingo.io/
Injection of HSTS Header
The HTTP Strict-Transport-Security
header (also known as HSTS) is a HTTP header
which aims at instructing clients like browsers, to avoid connecting to a given
domain without using an encrypted connection.
The header will be automatically added to the request response of HTTPS requests:
$ curl --head https://my-app.osc-fr1.scalingo.io
HTTP/2 200
date: Thu, 22 Aug 2024 08:26:33 GMT
content-type: text/plain; charset=utf-8
x-request-id: c87a7b84-d43f-44fb-9524-54bf666e6ff1
strict-transport-security: max-age=31536000
The strict-transport-security: max-age=31536000
ensures that browsers won’t
access the domain in an insecure way during 1 year. By combining it with the
HTTP to HTTPS redirection, it is now sure that users can only access the
application once without using an encrypted connection: at their first
connection which is usually unauthenticated.
You can also update your application code to return the HSTS header. In such case, Scalingo would not override the header value returned by the application.
More documentation about HSTS on Mozilla Developer Network.
Disclaimers
-
Make sure your application works correctly using HTTPS before enabling the Force HTTPS feature. Once enabled, the application won’t be reachable without HTTPS.
-
Once the feature is enabled and that some users have received the HSTS header, they will always keep using HTTPS to reach your application. Hence, make sure HTTPS access keep working correctly, even if the feature is disabled.
- This feature adds a small lock-in to the platform as it depends on Scalingo’s
infrastructure. If that is something you want to avoid, you can implement it
at the application level. Libraries exist for most languages and framework to
create the exact same behavior. Here are a few examples:
- Ruby, Rack: rack-ssl-enforcer
- Ruby, Rails 4+: ssl options configuration
- Java, Springboot: HttpSecurity configuration
- Java/Scala, Play2: HTTP filters
- Python: Django: Security Middleware
- Node.js, Express middleware: hsts
- Node.js, Meteor: force-ssl
- PHP, Symfony: Nelmio Security Bundle
- PHP, Laravel: zae/strict-transport-security
-
In case of requests different than GET, tools (browsers, language libraries, Postman…) may not follow the RFC and may request GET on the redirection.
If the 301 status code is received in response to a request other than GET or HEAD, the user agent MUST NOT automatically redirect the request unless it can be confirmed by the user, since this might change the conditions under which the request was issued.
Note: When automatically redirecting a POST request after receiving a 301 status code, some existing HTTP/1.0 user agents will erroneously change it into a GET request.
(from ietf.org/rfc/rfc2616.txt section 10.3.2)
For example with Postman, POST on HTTP will display the result of GET on HTTPS.