Skip to content

Exception on _switch_user when not logged in. #22729

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
peter17 opened this issue May 17, 2017 · 5 comments
Closed

Exception on _switch_user when not logged in. #22729

peter17 opened this issue May 17, 2017 · 5 comments

Comments

@peter17
Copy link
Contributor

peter17 commented May 17, 2017

Q A
Bug report? yes
Feature request? no
BC Break report? no
RFC? no
Symfony version any (tested on 3.2.8 and older versions)

The following problem appears on all my Symfony projects.

I set up a firewall on ^/admin with switch_user enabled. Everything works fine except one thing: any anonymous user can throw an Error 500 by visiting any /admin/xxx existing URL if they pass the _switch_user=_exit parameter in the URL.

For instance, when I am not logged in, if I visit:

https://www.mydomainnameforthisproject.com/app_dev.php/admin/index?_switch_user=_exit

I obtain this stack trace:

[1] Symfony\Component\Debug\Exception\FatalThrowableError: Type error: Argument 1 passed to Symfony\Component\Security\Http\Firewall\SwitchUserListener::getOriginalToken()
        must be an instance of Symfony\Component\Security\Core\Authentication\Token\TokenInterface, null given, called in
        /data/web/project1/vendor/symfony/symfony/src/Symfony/Component/Security/Http/Firewall/SwitchUserListener.php on line 164
    at n/a
        in /data/web/project1/vendor/symfony/symfony/src/Symfony/Component/Security/Http/Firewall/SwitchUserListener.php line 184
    at Symfony\Component\Security\Http\Firewall\SwitchUserListener->getOriginalToken(null)
        in /data/web/project1/vendor/symfony/symfony/src/Symfony/Component/Security/Http/Firewall/SwitchUserListener.php line 164
    at Symfony\Component\Security\Http\Firewall\SwitchUserListener->attemptExitUser(object(Request))
        in /data/web/project1/vendor/symfony/symfony/src/Symfony/Component/Security/Http/Firewall/SwitchUserListener.php line 84
    at Symfony\Component\Security\Http\Firewall\SwitchUserListener->handle(object(GetResponseEvent))
        in /data/web/project1/var/cache/dev/classes.php line 5393
    at Symfony\Component\Security\Http\Firewall->onKernelRequest(object(GetResponseEvent), 'kernel.request', object(TraceableEventDispatcher))
        in  line 
    at call_user_func(array(object(Firewall), 'onKernelRequest'), object(GetResponseEvent), 'kernel.request', object(TraceableEventDispatcher))
        in /data/web/project1/vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/Debug/WrappedListener.php line 106
    at Symfony\Component\EventDispatcher\Debug\WrappedListener->__invoke(object(GetResponseEvent), 'kernel.request', object(ContainerAwareEventDispatcher))
        in  line 
    at call_user_func(object(WrappedListener), object(GetResponseEvent), 'kernel.request', object(ContainerAwareEventDispatcher))
        in /data/web/project1/var/cache/dev/classes.php line 3272
    at Symfony\Component\EventDispatcher\EventDispatcher->doDispatch(array(object(WrappedListener), object(WrappedListener), object(WrappedListener),
        object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener),
        object(WrappedListener), object(WrappedListener)), 'kernel.request', object(GetResponseEvent))
        in /data/web/project1/var/cache/dev/classes.php line 3187
    at Symfony\Component\EventDispatcher\EventDispatcher->dispatch('kernel.request', object(GetResponseEvent))
        in /data/web/project1/vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php line 136
    at Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcher->dispatch('kernel.request', object(GetResponseEvent))
        in /data/web/project1/var/cache/dev/classes.php line 4622
    at Symfony\Component\HttpKernel\HttpKernel->handleRaw(object(Request), 1)
        in /data/web/project1/var/cache/dev/classes.php line 4592
    at Symfony\Component\HttpKernel\HttpKernel->handle(object(Request), 1, true)
        in /data/web/project1/vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Kernel.php line 168
    at Symfony\Component\HttpKernel\Kernel->handle(object(Request))
        in /data/web/project1/web/app_dev.php line 30

This is my firewall configuration.

security:
    firewalls:
        dev:
            pattern: '^/(_(profiler|wdt)|css|images|js)/'
            security: false

        assets:
            pattern: '^/assets'
            security: false

        security:
            pattern: '^/admin/(login|forgotpassword|resetpassword.*)$'
            security: false

        admin:
            pattern: '^/admin'
            form_login:
                provider: admin
                csrf_token_generator: security.csrf.token_manager
                login_path: /admin/login
                check_path: /admin/login_check
                default_target_path: /admin/
            logout:
                path: /admin/logout
                target: /admin
            anonymous: false
            switch_user: { role: ROLE_SUPPORT }

I think this is a bug, because an anonymous user should NOT ne able to do anything (especially producing an uncaught Exception) on the /admin/xxx URLs...

Regards

@dmaicher
Copy link
Contributor

Thanks for the report!

I could reproduce the issue and proposed a fix here #22732

fabpot added a commit that referenced this issue Jun 19, 2017
…ken (dmaicher)

This PR was merged into the 2.7 branch.

Discussion
----------

[Security] fix switch user _exit without having current token

| Q             | A
| ------------- | ---
| Branch?       | 2.7
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #22729
| License       | MIT
| Doc PR        | -

Attempting to `_exit` from a switched user caused an error when not having any token in the storage (for example happens when not logged in + disallowing anonymous users on that firewall):

`[1] Symfony\Component\Debug\Exception\FatalThrowableError: Type error: Argument 1 passed to Symfony\Component\Security\Http\Firewall\SwitchUserListener::getOriginalToken()
        must be an instance of Symfony\Component\Security\Core\Authentication\Token\TokenInterface, null given, called in
        symfony/symfony/src/Symfony/Component/Security/Http/Firewall/SwitchUserListener.php on line 164`

Commits
-------

16da686 [Security] fix switch user _exit without having current token
@fabpot fabpot closed this as completed Jun 19, 2017
@peter17
Copy link
Contributor Author

peter17 commented Jul 5, 2017

I still have this problem with Symfony-3.3.3...

The problem is indeed solved when passing _exit but it now happens when passing other arguments such as /?_switch_user=toto@toto.net

Symfony\Component\Debug\Exception\FatalThrowableError:
Type error: Argument 1 passed to Symfony\Component\Security\Http\Firewall\SwitchUserListener::getOriginalToken() must be an instance of Symfony\Component\Security\Core\Authentication\Token\TokenInterface, null given, called in /data/web/project1/vendor/symfony/symfony/src/Symfony/Component/Security/Http/Firewall/SwitchUserListener.php on line 114

  at vendor/symfony/symfony/src/Symfony/Component/Security/Http/Firewall/SwitchUserListener.php:184
  at Symfony\Component\Security\Http\Firewall\SwitchUserListener->getOriginalToken(null)
     (vendor/symfony/symfony/src/Symfony/Component/Security/Http/Firewall/SwitchUserListener.php:114)
  at Symfony\Component\Security\Http\Firewall\SwitchUserListener->attemptSwitchUser(object(Request))
     (vendor/symfony/symfony/src/Symfony/Component/Security/Http/Firewall/SwitchUserListener.php:87)
  at Symfony\Component\Security\Http\Firewall\SwitchUserListener->handle(object(GetResponseEvent))
     (var/cache/dev/classes.php:4791)
  at Symfony\Component\Security\Http\Firewall->onKernelRequest(object(GetResponseEvent))
     (vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/EventListener/FirewallListener.php:48)
  at Symfony\Bundle\SecurityBundle\EventListener\FirewallListener->onKernelRequest(object(GetResponseEvent), 'kernel.request', object(TraceableEventDispatcher))
  at call_user_func(array(object(FirewallListener), 'onKernelRequest'), object(GetResponseEvent), 'kernel.request', object(TraceableEventDispatcher))
     (vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/Debug/WrappedListener.php:104)
  at Symfony\Component\EventDispatcher\Debug\WrappedListener->__invoke(object(GetResponseEvent), 'kernel.request', object(ContainerAwareEventDispatcher))
  at call_user_func(object(WrappedListener), object(GetResponseEvent), 'kernel.request', object(ContainerAwareEventDispatcher))
     (var/cache/dev/classes.php:3472)
  at Symfony\Component\EventDispatcher\EventDispatcher->doDispatch(array(object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener)), 'kernel.request', object(GetResponseEvent))
     (var/cache/dev/classes.php:3355)
  at Symfony\Component\EventDispatcher\EventDispatcher->dispatch('kernel.request', object(GetResponseEvent))
     (vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php:146)
  at Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcher->dispatch('kernel.request', object(GetResponseEvent))
     (var/cache/dev/classes.php:4432)
  at Symfony\Component\HttpKernel\HttpKernel->handleRaw(object(Request), 1)
     (var/cache/dev/classes.php:4402)
  at Symfony\Component\HttpKernel\HttpKernel->handle(object(Request), 1, true)
     (vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Kernel.php:171)
  at Symfony\Component\HttpKernel\Kernel->handle(object(Request))
     (web/app_dev.php:30)

Best regards

@dmaicher
Copy link
Contributor

dmaicher commented Jul 5, 2017

@peter17 thanks for the report. But it also fails for older symfony versions (like 3.3.2), right?

Seems we need to apply a similar fix for switching as well like we did for exiting.

@peter17
Copy link
Contributor Author

peter17 commented Feb 8, 2019

It is still present in my project upgraded to Symfony 4.2.3...

{
    "class": "Symfony\\Component\\Debug\\Exception\\FatalThrowableError",
    "message": "Argument 1 passed to Symfony\\Component\\Security\\Http\\Firewall\\SwitchUserListener::getOriginalToken() must be an instance of Symfony\\Component\\Security\\Core\\Authentication\\Token\\TokenInterface, null given, called in /project/vendor/symfony/symfony/src/Symfony/Component/Security/Http/Firewall/SwitchUserListener.php on line 119",
    "code": 0,
    "file": "/project/vendor/symfony/symfony/src/Symfony/Component/Security/Http/Firewall/SwitchUserListener.php:187",
    "trace": [
        "/project/vendor/symfony/symfony/src/Symfony/Component/Security/Http/Firewall/SwitchUserListener.php:119",
        "/project/vendor/symfony/symfony/src/Symfony/Component/Security/Http/Firewall/SwitchUserListener.php:90",
        "/project/vendor/symfony/symfony/src/Symfony/Component/Security/Http/Firewall.php:117",
        "/project/vendor/symfony/symfony/src/Symfony/Component/Security/Http/Firewall.php:90",
        "/project/vendor/symfony/symfony/src/Symfony/Bundle/SecurityBundle/EventListener/FirewallListener.php:48",
        "/project/vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/EventDispatcher.php:212",
        "/project/vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/EventDispatcher.php:44",
        "/project/vendor/symfony/symfony/src/Symfony/Component/HttpKernel/HttpKernel.php:126",
        "/project/vendor/symfony/symfony/src/Symfony/Component/HttpKernel/HttpKernel.php:67",
        "/project/vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Kernel.php:198",
        "/project/vendor/symfony/symfony/src/Symfony/Component/HttpKernel/HttpCache/SubRequestHandler.php:85",
        "/project/vendor/symfony/symfony/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php:448",
        "/project/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/HttpCache/HttpCache.php:57",
        "/project/vendor/symfony/symfony/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php:420",
        "/project/vendor/symfony/symfony/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php:317",
        "/project/vendor/symfony/symfony/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php:192",
        "/project/web/app.php:16"
    ]
}

So this bug was never really solved... is it possible to repen it?

@xabbuh
Copy link
Member

xabbuh commented Feb 8, 2019

Can you create a small example application that will allow us to reproduce the issue?

@xabbuh xabbuh reopened this Feb 8, 2019
@fabpot fabpot closed this as completed Feb 12, 2019
fabpot added a commit that referenced this issue Feb 12, 2019
…ntoine Lamirault)

This PR was merged into the 3.4 branch.

Discussion
----------

[Security] fix switch user without having current token

| Q             | A
| ------------- | ---
| Branch?       | 3.4
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #22729
| License       | MIT

Attempting to switch a user cause an error when not having any token in the storage

Commits
-------

15db914 [Security] fix switch user without having current token
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

6 participants