Skip to content

Twig function csrf_token('authenticate') returns 'csrf_token' #59111

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

Closed
cavias opened this issue Dec 6, 2024 · 27 comments
Closed

Twig function csrf_token('authenticate') returns 'csrf_token' #59111

cavias opened this issue Dec 6, 2024 · 27 comments

Comments

@cavias
Copy link

cavias commented Dec 6, 2024

Symfony version(s) affected

7.2.0

Description

I am building a login form according to instructions here https://symfony.com/doc/current/security.html#form-login

When I make the following code:
<input type="hidden" name="_csrf_token" value="{{ csrf_token('authenticate') }}">

The function csrf_token('authenticate') generates thes tring csrf_token instead of an actual token. Making my login not work.

By comparison, executing csrf_token('randomstring') does generate a valid token.

What is happening here?

How to reproduce

Seems to be as simple as doing csrf_token('authenticate') in Twig.

Possible Solution

No response

Additional Context

No response

@Crovitche-1623
Copy link

By default, the new CSRF system is stateless since 7.2. That’s not a bug @cavias

@cavias
Copy link
Author

cavias commented Dec 7, 2024

By default, the new CSRF system is stateless since 7.2. That’s not a bug @cavias

@Crovitche-1623 the word stateless is not mentioned in neither Security login nor CSRF documentation, so I am failing to understand why this is relevant or what implications it has for this usecase?

See https://symfony.com/doc/current/security.html#form-login
And https://symfony.com/doc/current/security/csrf.html

@Crovitche-1623
Copy link

Crovitche-1623 commented Dec 7, 2024

@cavias You are right the documentation is not updated yet (see symfony/symfony-docs#20306) but it's already enabled (see https://symfony.com/blog/new-in-symfony-7-2-stateless-csrf). See in this section, the authenticate value is set by default

@Crovitche-1623
Copy link

As you probably installed Symfony 7.2, you also got the following recipe : symfony/recipes#1337

@dearaujoj
Copy link

@cavias I tried to reproduce it on a fresh 7.2 simple project with a protected page and login form and the login worked with the stateless csrf with string "csrf-token"

@cavias
Copy link
Author

cavias commented Dec 7, 2024

@Crovitche-1623 Thank you, that at least gives me some pointers as to what is going on. Disabling stateless_token_ids seems to "fix" it for now, but of course I'd like to get this working in the future. I see there is also a Stimulus csrf controller provided which I assume is relevant somehow.

Once documentation is released on how to actually use this I will re-enable it. The app won't be live for a few months anyways, and I am getting a bit tired of all the github deep-diving I have to do to get things working.

I will close this issue.

@cavias cavias closed this as completed Dec 7, 2024
@nicolas-grekas
Copy link
Member

The behavior you describe is correct and expected. The stateless CSRF protection that you enabled by adopting the recipe update leads to these not-random tokens.
Then, you write: "Making my login not work.", and this doesn't gives us any hint about what doesn't work.

@cavias
Copy link
Author

cavias commented Dec 7, 2024

The behavior you describe is correct and expected. The stateless CSRF protection that you enabled by adopting the recipe update leads to these not-random tokens. Then, you write: "Making my login not work.", and this doesn't gives us any hint about what doesn't work.

All I'm getting when trying to login is the error message "CSRF token invalid". I should have specified that, my apologies.

I'm assuming the Stimulus csrf controller is supposed to do something here, but which data attributes with which data it needs, I do not know.

@Crovitche-1623
Copy link

Crovitche-1623 commented Dec 7, 2024

You probably need to set a data-controller="csrf-protection" to your csrf input and replace the {{ csrf_token('authenticate') }} by csrf-token (with the stateless id configuration). That's what I did to make it work !

@nicolas-grekas
Copy link
Member

nicolas-grekas commented Dec 7, 2024

Oh, this might be something to add to the doc, right? PR welcome!

@Crovitche-1623
Copy link

@nicolas-grekas also to the make:security:form-login command no ?

@nicolas-grekas
Copy link
Member

nicolas-grekas commented Dec 7, 2024 via email

@Hanhan1989
Copy link

The issue described above has been fixed in version 7.2.1.
In version 7.2.0, the update process automatically generated a CSRF configuration file (‎config/packages/csrf.yaml). As of version 7.2.1, this file is no longer generated.

This is my assumption.

@whataboutpereira
Copy link

It seems to me that with stateless enabled and without the csrf-protection controller we'll be left without a token based CSRF check completely?

@nicolas-grekas
Copy link
Member

data-controller="csrf-protection" is required indeed if you enabled the JS snippet (which you did if you accepted the recipe update)

@nicolas-grekas
Copy link
Member

See symfony/recipes#1373 and linked issues

javiereguiluz added a commit to symfony/symfony-docs that referenced this issue Jan 7, 2025
…colas-grekas)

This PR was merged into the 6.4 branch.

Discussion
----------

Add data-controller="csrf-protection" to CSRF fields

Submitting on 6.4 so that the resulting apps can more easily be updated to 7.2

See symfony/symfony#59111

Commits
-------

e818e12 Add data-controller="csrf-protection" to CSRF fields
@Menelion
Copy link

Menelion commented Jan 7, 2025

Hello! I was directed here from discussion #59382 I created. I still cannot fix it for my setup (dev environment, debug on, Windows, no Docker). Stimulus bundle is here, but for some reason make:assets-install public does nothing, there is no assets directory inside public (I don't know if that is normal or not). This in login.twig.html still gives invalid CSRF token:

        <input type="hidden" name="_csrf_token"
        data-controller="csrf-protection"
        value="csrf_token"
        >

Any ideas appreciated. // CC @nicolas-grekas

@nicolas-grekas
Copy link
Member

If you cannot make it work, remove the csrf.yaml file brought by the recipe to revert back to previous behavior.

@RobQuistNL
Copy link

I'm just seeing 'csrf-token' in the value field. No Javascript, no cookies, no headers being sent. Request comes through "OK".

I had to delete the config;

# Enable stateless CSRF protection for forms and logins/logouts
framework:
    form:
        csrf_protection:
            token_id: submit

    csrf_protection:
        stateless_token_ids:
            - submit
            - authenticate
            - logout

to make CSRF actually work (so there are now random values in the field, making it stateful again).

With this setup (as described by this blog post), it seems to work, but all request work, making this seemingly CSRF protection, useless.

@Crovitche-1623
Copy link

@RobQuistNL You don't see any value because that's the point of the CSRF stateless check ! It's done using cookies and not a form value.

@RobQuistNL
Copy link

@Crovitche-1623 What cookie would that be? I see no cookies being sent in the request.

I see these 2;

main_deauth_profile_token=197ddd; PHPSESSID=3c2be52776f1dfb0972e43f21446ade9

If I edit both and submit the form, it succeeds and no CSRF error is reported.

@Crovitche-1623
Copy link

@RobQuistNL Add the mandatory data-controller on your CSRF input then. See:

symfony/symfony-docs#20530

@RobQuistNL
Copy link

@Crovitche-1623 that wasn't there indeed. I've added it, but its still simply accepting the request.

FYI: there is 0 javascript in the webpage. Should the be more stuff added? I'd think it would be a local piece of javascript code. But how does that work for people that have JS disabled?

@RobQuistNL
Copy link

Please note that all the paged so far have been generated using php bin/console make:controller Login and others, straight from the documentation.

I don't know exactly when the input field was added to the twig template, but it didn't add the data-controller="csrf-protection" as the docs here state; https://symfony.com/doc/current/security.html#form_login-csrf

@RobQuistNL
Copy link

Also the registration form as generated by;

composer require symfonycasts/verify-email-bundle
php bin/console make:registration-form

just shows this;

    <form name="registration_form" method="post">
        <div>(... just the form elements ...)</div>

        <button type="submit" class="btn">Sign up</button>
    <input type="hidden" id="registration_form__token" name="registration_form[_token]" data-controller="csrf-protection" value="csrf-token" /></form>

and it doesn't matter if I remove / edit cookies and submit. It just succeeds.

@RobQuistNL
Copy link

If I however change the value csrf-token to something else, I get this error; The CSRF token is invalid. Please try to resubmit the form.

@Hanhan1989
Copy link

If I however change the value csrf-token to something else, I get this error; The CSRF token is invalid. Please try to resubmit the form.

Symfony now enables Turbo UX by default, you will need to activate the AssetMapper

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants