Forcing https not working on localhost, what am I missing?

I’m trying to force all http request to redirect to https.

In short I have added the below to my endpoint config.

  url: [host: "localhost", port: 80],
  force_ssl: [hsts: true, rewrite_on: [:x_forwarded_proto], host: "localhost"]

I’ve tried just simply force_ssl: [hsts: true] with no luck as well.

Apps:

:phoenix, "1.4.10"
:plug, "1.8.3"

Browsers:

Chrome: Ubuntu Version 78.0.3904.97 (Official Build) (64-bit)

When making a http request the request is successful but it never redirects to https.

Heres the whole config.

config :morphic_pro, MorphicProWeb.Endpoint,
  http: [port: 4000],
  https: [
    port: 4001,
    cipher_suite: :strong,
    certfile: "priv/cert/localhost.crt",
    keyfile: "priv/cert/localhost.key"
  ],
  debug_errors: true,
  code_reloader: true,
  check_origin: false,
  watchers: [
    node: [
      "node_modules/webpack/bin/webpack.js",
      "--mode",
      "development",
      "--watch-stdin",
      cd: Path.expand("../assets", __DIR__)
    ]
  ],
  url: [host: "localhost", port: 80],
  force_ssl: [hsts: true, rewrite_on: [:x_forwarded_proto], host: "localhost"]

I have read over https://hexdocs.pm/phoenix/1.4.10/endpoint.html#using-ssl and was a little confused about the note about making https requests on 4000. I assume that maybe a typo that the protocol was https not http

EDIT: I now understand the point of the comment around being redirected from http to https but still keeping the port as 4000 but I’ve yet to see that since I don’t seem to be redirecting any of my requests.

1 Like

From the docs it looks like :hsts is not combinable with any other options:

https://hexdocs.pm/phoenix/endpoint.html#hsts

Ah missed that part. will confirm then again.

Simply having.

config :morphic_pro, MorphicProWeb.Endpoint,
  http: [port: 4000],
  https: [
    port: 4001,
    cipher_suite: :strong,
    certfile: "priv/cert/localhost.crt",
    keyfile: "priv/cert/localhost.key"
  ],
  debug_errors: true,
  code_reloader: true,
  check_origin: false,
  watchers: [
    node: [
      "node_modules/webpack/bin/webpack.js",
      "--mode",
      "development",
      "--watch-stdin",
      cd: Path.expand("../assets", __DIR__)
    ]
  ],
  force_ssl: [hsts: true]

Does not seem to force any type of redirect on http://localhost:4000/

The example config just has force_ssl: :hsts, not even wrapped in a list.

PS: having HSTS for localhost is nasty… You shouldn’t activate it before you know how to remove it from your browser after wards…

1 Like

Also please read the full section over HSTS I linked above, HSTS will only work for port 80 according to that page.

1 Like

Hmmm,

Compiling 21 files (.ex)

== Compilation error in file lib/morphic_pro_web/endpoint.ex ==
** (FunctionClauseError) no function clause matching in Keyword.put_new/3    
    
    The following arguments were given to Keyword.put_new/3:
    
        # 1
        :hsts
    
        # 2
        :host
    
        # 3
        {MorphicProWeb.Endpoint, :host, []}
    
    Attempted function clauses (showing 1 out of 1):
    
        def put_new(keywords, key, value) when is_list(keywords) and is_atom(key)
    
    (elixir) lib/keyword.ex:627: Keyword.put_new/3
    lib/morphic_pro_web/endpoint.ex:2: (module)
    (stdlib) erl_eval.erl:680: :erl_eval.do_apply/6
    (elixir) lib/kernel/parallel_compiler.ex:229: anonymous fn/4 in Kernel.ParallelCompiler.spawn_workers/7

Ok I think I finally understand.

First it looks as if I need to wrap the config in a list as I had done initially and if I do per the doc shows I will end up with the compile time error as shown above.

From there I’m not seeing redirection on 4000 because as stated above redirection only happens on port 80.

Though that was overlooked by the fact the endpoint is still handling http requests on port 4000 because of the http config section http: [port: 4000], which I assumed would be a conflict with the whole idea of HSTS.

I want simple http redirection for localhost which normally is not on 80 without odd circumstance.
What is the simplest way to do this without all this headache.

IE if I go to http://localhost:4000 it redirects its request to https://localhost:4001
thats all I want to do. It really should not be this confusing as to how to redirect all http calls to https

I believe localhost is excluded from the SSL plug by default, check out https://github.com/elixir-plug/plug/blob/master/lib/plug/ssl.ex#L46

1 Like

Its as if what I’m trying to do is a horrible idea.

You are aware of the difference between enabling HSTS for a domain and forcing HTTPS through a regular redirect?

sure, I’m just grasping at straws to make anything work without going to nginx at this point.

I mean in rails its legit this simple.

  config.force_ssl = true
  config.ssl_options = {  redirect: { status: 307, port: 81 } }

Then you know why it is a bad idea on localhost, and why some servers might disable it there.

Try it on another name and with port 80, but only after you made sure regular served traffic works through it.

That’s not HSTS, that’s a regular redirect.

No I dont know its bad idea, I still dont understand why its bad idea. All I want is that if I go to

http://localhost:4000 it goes to https://localhost:4001 I dont understand how I’m confusing this issue.

This should be simple to do, what do I need to make this ^^^^ happen. Thats it.

I dont care if thats redirection or its HSTS, what ever makes it happen is all I want to know.

I read this
https://hexdocs.pm/phoenix/endpoint.html#force-ssl

I do what it says and it does not work for localhost.

I’m gonna end this thread since its mostly the same as Proper way to enforce https only? because this is all I want but for localhost while developing.

HSTS is a bad idea for localhost, as it will require you to provide HTTPS for all applications that you happen to develop on that computer, also for some browsers you won’t be able to use self signed or outdated certificates along with HSTS.

They become very strict once HSTS was activated for a domain.

1 Like