Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Normalize URI before redirect in order to avoid :badarg failure from nil port in URI #328

Merged

Conversation

bfolkens
Copy link
Contributor

Per #327 - URI.merge/2 overwrites port attribute with nil during merge with relative redirect URI. Since URI.merge/2 correctly follows RFC 3986 5.2 Relative Resolution, a separate normalization step is needed to include RFC 3986 6.2.3 Scheme-Based Normalization.

Note: a test was not included since Bypass runs on a port other than 80 or 443, and we would explicitly need to test to see if the port will be defaulted to 80/443 (depending on the original URI scheme). However, we were able to confirm a test watching for :badarg exit fails prior to the patch and succeeds after the patch. This test has been excluded from the PR since it hangs the tests while waiting for a connection timeout in the success case.

@wojtekmach
Copy link
Owner

Thank you. Could you look into testing it using the :plug feature, without bypass?

@bfolkens
Copy link
Contributor Author

I tried to implement a test using the :plug feature via the following:

test "inherit port", c do
  relative_redirect = fn
    %Plug.Conn{host: "redirected", port: nil} ->
      flunk("port cannot be nil")

    %Plug.Conn{host: "redirected", port: 80} = conn ->
      Plug.Conn.send_resp(conn, 200, "ok")

    conn ->
      conn
      |> Plug.Conn.put_resp_header("location", "//redirected")
      |> Plug.Conn.send_resp(301, "")
  end

  assert ExUnit.CaptureLog.capture_log(fn ->
           assert Req.get!(c.url, plug: relative_redirect).status == 200
         end) =~ "[debug] redirecting to //redirected"
end

However, in the underlying Plug.Adapters.Test.Conn.conn/4 port is coalesced into 80 (https://github.com/elixir-plug/plug/blob/2eda50618296b1c0e5fd9d0066e382c34b28ea0a/lib/plug/adapters/test/conn.ex#L39), so it masks the failure case and the above test will always pass.

The above test at least ensures that there's no fatal error with the normalize_redirect_uri/1 code, though I don't think it's entirely useful. Happy to entertain any other ideas...

@wojtekmach wojtekmach merged commit 95a6b14 into wojtekmach:main Mar 25, 2024
2 checks passed
@wojtekmach
Copy link
Owner

Thank you!

wojtekmach added a commit that referenced this pull request Mar 25, 2024
@wojtekmach
Copy link
Owner

@bfolkens fyi turns out there was an existing similar test, I was able to adjust it to fail before your change and pass afterwards. b303130

@bfolkens bfolkens deleted the 327_normalize_uri_before_redirect branch March 25, 2024 16:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants