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

Favour redirection over Same-Site: None #3

Open
tomtaylor opened this issue Oct 16, 2024 · 3 comments
Open

Favour redirection over Same-Site: None #3

tomtaylor opened this issue Oct 16, 2024 · 3 comments

Comments

@tomtaylor
Copy link

Problem Statement

The Apple OAuth implementation is a bit odd, in that it performs a cross site form POST request to the callback URL, not a GET redirection. This means that any cookies with anything other than Same-Site: None are not sent on the callback request. Currently the library encourages users to downgrade the security of those cookies to Same-Site: None, but I believe there's a better solution.

Solution Brainstorm

Instead of downgrading the security, ueberauth_apple could implement a POST handler action, which takes the form params and converts them to a GET request to the callback with query params. The GET request will include the cookies with Same-Site: Lax/Strict, so it will behave in the same way to any other Ueberauth callback. I've implemented something similar manually, and it works well, but I think it could be included in the library for a smoother path.

@aj-foster
Copy link
Contributor

Hello there. I'm interested in this proposal. Is there any chance we could see the implementation you have currently? That would help me ensure I understand the flow correctly.

@tomtaylor
Copy link
Author

Hey @aj-foster, sure thing.

In my our controller which implements the Ueberauth callback, we also have the following action:

  @doc """
  The Apple provider hits our callback URL as a cross site `POST` request.
  Because we implement `Same-Site: Lax` on our cookies, this means the request
  lands without any cookies. To work around this, we redirect the user to the
  normal `GET` callback URL, using the action below, which passes the original
  form parameters as query params. Following the redirect, the browser sends the
  usual cookies with this request, and the callback can proceed as normal.
  """
  def post_redirector(%Plug.Conn{} = conn, %{"provider" => provider}) do
    conn
    |> redirect(to: ~p"/en-gb/auth/#{provider}/callback?#{conn.body_params}")
  end

The provider is defined like so:

    apple:
      {Ueberauth.Strategy.Apple,
       [
         default_scope: "name email",
         request_path: "/en-gb/auth/apple",
         callback_path: "/en-gb/auth/apple/callback",
         callback_methods: ["POST", "GET"]
       ]}

And then our router is defined similar to:

  scope "/en-gb", PoplarWeb do
    pipe_through :minimal_browser

    post "/auth/:provider/callback", OauthController, :post_redirector
  end

Does that give you enough to go on?

@lifeiscontent
Copy link

@tomtaylor can you show what exists in the pipeline of minimal_browser?

I've got something similar:

  pipeline :skip_csrf_protection do
    plug :accepts, ["html"]
    plug :fetch_session
    plug :fetch_live_flash
    plug :put_root_layout, html: {InterestspotlightWeb.Layouts, :root}
    plug :put_secure_browser_headers
    plug :fetch_current_user
  end

but this still isn't working for me, I'm getting an error that looks like this:

%{current_user: nil, flash: %{}, ueberauth_failure: %Ueberauth.Failure{provider: :apple, strategy: Ueberauth.Strategy.Apple, errors: [%Ueberauth.Failure.Error{message_key: "invalid_client", message: "error requesting token"}]}}

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

No branches or pull requests

3 participants