8000 [Routing][Security] When a `#[Route]` is marked as `stateless: true` and the `SameOriginCsrfTokenManager.php`, the check fails · Issue #59092 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content

[Routing][Security] When a #[Route] is marked as stateless: true and the SameOriginCsrfTokenManager.php, the check fails #59092

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
Crovitche-1623 opened this issue Dec 4, 2024 · 0 comments · Fixed by #59146

Comments

@Crovitche-1623
Copy link
Crovitche-1623 commented Dec 4, 2024

Symfony version(s) affected

7.2.0

Description

When a #[Route] is marked as stateless: true and the SameOriginCsrfTokenManager.php configuration is enabled, the stateless check fails because the hasSession(true)condition passes and the code is executed when it shouldn't be. Therefore, the CSRF strategy is persisted in the session (I have a csrf-token with the value 1 instead of no value at all).

To make the stateless check pass, I had to modify the following code:

    // line 208 of Symfony\Component\Security\Csrf\SameOriginCsrfTokenManager.php
    public function persistStrategy(Request $request): void
    {
        if ($request->hasSession(true) && $request->attributes->has($this->cookieName)) {
            $request->getSession()->set($this->cookieName, $request->attributes->get($this->cookieName));
        }
    }

to

    public function persistStrategy(Request $request): void
    {
        if ($request->hasSession(true) && $request->getSession()->isStarted() && $request->attributes->has($this->cookieName)) {
            $request->getSession()->set($this->cookieName, $request->attributes->get($this->cookieName));
        }
    }

@nicolas-grekas Maybe you wanted to check if the session was started instead of if a Session object exists ?

How to reproduce

Make a route marked as stateless. For instance:

#[Route(
    path: [
        'fr' => '/se_connecter',
        'en' => '/login',
    ],
    name: 'login',
    stateless: true,
)]
public function login() {
    // ...
}

And configure the app to use stateless CSRF token (https://symfony.com/blog/new-in-symfony-7-2-stateless-csrf)

Possible Solution

Check if the session is started instead of the session exists to define if a value must be written in the session or not.

Additional Context

No response

@Crovitche-1623 Crovitche-1623 changed the title bug: When a #[Route] is marked as stateless: true and the SameOriginCsrfTokenManager.php, the check fails [Security] When a #[Route] is marked as stateless: true and the SameOriginCsrfTokenManager.php, the check fails Dec 9, 2024
@Crovitche-1623 Crovitche-1623 changed the title [Security] When a #[Route] is marked as stateless: true and the SameOriginCsrfTokenManager.php, the check fails [Routing][Security] When a #[Route] is marked as stateless: true and the SameOriginCsrfTokenManager.php, the check fails Dec 10, 2024
fabpot added a commit that referenced this issue Jan 2, 2025
…g `SameOriginCsrfTokenManager` (Thibault G)

This PR was merged into the 7.2 branch.

Discussion
----------

[Security] Use the session only if it is started when using `SameOriginCsrfTokenManager`

| Q             | A
| ------------- | ---
| Branch?       | 7.2
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Issues        | Fix #59092
| License       | MIT

If I understand well, the `SameOriginCsrfTokenManager` has been created to provide a stateless way of creating CSRF tokens and therefore allow pages with CSRF tokens to be cached.

When using `Symfony\Component\Security\Csrf\SameOriginCsrfTokenManager`, I think an additionnal check must be done to ensure that the session is started in addition to verifying that it exists. If not, the CSRF strategy used will be persisted everytime in the session and the stateless check (used with the `#[Route]` attribute parameter) will therefore never pass.

Commits
-------

1327e38 [Security] Use the session only if it is started when using `SameOriginCsrfTokenManager`
@fabpot fabpot closed this as completed Jan 2, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants
0