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

ActionController::InvalidAuthenticityToken #632

Open
lazaronixon opened this issue Jul 12, 2024 · 2 comments
Open

ActionController::InvalidAuthenticityToken #632

lazaronixon opened this issue Jul 12, 2024 · 2 comments
Labels
bug Something isn't working

Comments

@lazaronixon
Copy link

lazaronixon commented Jul 12, 2024

Describe the bug

When I try to submit to a main application controller, I receive ActionController::InvalidAuthenticityToken. For some reason, the session cookie is not created when I access /lookbook, but as soon as I open the main application and the session cookie is set, the following requests work without any problem.

To Reproduce

Rails.application.routes.draw do
  mount Lookbook::Engine, at: "/lookbook"
  resource :slow_action, only: :create
end
class SlowActionsController < ApplicationController
  # skip_forgery_protection

  def create
    sleep 3.seconds; head :created
  end
end

test/components/previews/button_preview/loading.html.erb

<%= form_with(url: main_app.slow_action_path) do |form| %>
  <%= form.button tag.span("Click and wait"), class: "btn btn--loading" %>
<% end %>
@lazaronixon lazaronixon added the bug Something isn't working label Jul 12, 2024
@allmarkedup
Copy link
Collaborator

allmarkedup commented Oct 9, 2024

Hey @lazaronixon, sorry for the super slow reply and thanks for the bug report.

I've just opened a PR that should fix this. I realise it's quite a while since you created this issue but if you are able to to test it and confirm it works for you too then that would be fantastic:

gem "lookbook", github: "lookbook-hq/lookbook", branch: "fix-preview-csrf-exception"

From my testing it seems to fix the issue so if I don't hear back with any problems I'll merge it in and get it out in the next release. Thanks again for bringing it to my attention :)

@halo
Copy link

halo commented Oct 10, 2024

Thank you for attempting to fix this issue. I'm a bit confused, though.

This is what my lookbook HTML looks like with a form_for tag:

<!-- http://127.0.0.1:3005/lookbook/inspect/toggle/async -->
<html>

<head>
  <!-- Your PR adds this one -->
  <meta name="csrf-token" content="3JWhDXzu1713DX..." /> 
</head>

<body>
  <!-- I don't think I can programmatically escape this iframe, right? I can't see the token above. -->
  <iframe>
    <html>

    <head>
      <title>Preview</title>
      <!-- This is from my Rails layout -->
      <meta name="csrf-token" content="iAhD6iIsCjEhorYn...">  
    </head>

    <body>
      <form id="..." action="..." accept-charset="UTF-8" method="post">
        <!-- This is what `form_for` adds -->
        <input type="hidden" name="authenticity_token" value="ReJTSC8SlGyDbfWo..." autocomplete="off">
      </form>
    </body>

    </html>
  </iframe>
</body>

</html>

What's being submitted is the token ReJTSC8SlGyDbfWo.... And because my session is not initialized yet, it will lead to a ActionController::InvalidAuthenticityToken.

However, if I add session[:test] = 'something' to the controller that takes the request (and reload the page), I have a session that matches the access token being submitted and I don't get the exception.

Your PR does not change this behavior.

My guess is that the underlying problem is the <iframe> that prevents the session from being set automatically. I don't think this is related to the meta tag in the lookbook layout at all.

See also https://discuss.rubyonrails.org/t/cant-verify-csrf-token-authenticity-in-iframe/85518 (but that is only addressing cross-domain issues I think)

See also https://security.stackexchange.com/questions/238443/iframe-friendly-csrf-protection

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants