0

I need to completely disable the control of the CSRF token for my application. I tried to use:

    public function beforeFilter(Event $event)
    {
      $this->getEventManager()->off($this->Csrf);
    }

In AppController but it does not seem to work. Manual link: Disabling the CSRF Component for Specific Actions

I did a lot of tests, read many posts but I could not solve.

Ty.

@omerowitz This is my AppController before filter action:

    public function beforeFilter(Event $event)
{
    $this->getEventManager()->off($this->Security);
    if($this->request->is('post')) {
        $this->getEventManager()->off($this->Csrf);
    }
    $this->Auth->allow(['index', 'view', 'display']);
}

but it still does not work, I still have the error 'CSRF token mismatch.' when I effect a request with postman

SOLUTION:

I have remove this :

->add(new CsrfProtectionMiddleware([
     'httpOnly' => true
  ]));

From Application.php. Why this is not indicated in the manual?

Ty all!

  • Are you externally calling an action from postman? – Sehdev Sep 03 '18 at 11:30
  • Whenever receiving errors, please always post **the _complete_ error**, that is, **including the _full_ stacktrace** (ideally copied from the logs where it is available in a properly readable fashion) - thanks! I think you'll find that the exception isn't triggered by the component, but [**by the middleware**](https://stackoverflow.com/questions/51916680/csrf-token-mismatch-in-post-request-in-3-6-version/51916959). – ndm Sep 03 '18 at 11:41
  • Yes, i call action with postman. This is the stack trace error [click](https://pastebin.ubuntu.com/p/VRDZph5QYS/) – Daniele Cancani Sep 03 '18 at 11:48
  • now I'm using the HTTP protocol, could it be a problem? – Daniele Cancani Sep 03 '18 at 12:02
  • @DanieleCancani Maybe you are sending a `PUT` request, so just remove the condition: `if($this->request->is('post')) {`. – Zlatan Omerović Sep 03 '18 at 12:38
  • @DanieleCancani Also check your `AppController` and it's `initialize()` method if it contains this call: `$this->loadComponent('Csrf');` - remove it and it should work. If you load `Security` component like that, try without it and see what happends. I personally never load `Security` in `AppController->initialize`. – Zlatan Omerović Sep 03 '18 at 12:41
  • @omerowitz The request is definitely in POST. I've already tried to remove the IF but it still does not work :( this is my initializ() in appController [click](https://pastebin.ubuntu.com/p/K5hQd4j5rT/) – Daniele Cancani Sep 03 '18 at 12:59
  • Take a close look at the stacktrace, [**as suspected**](https://stackoverflow.com/questions/52147836/cakephp-3-6-10-disable-completely-csrf-token-check#comment91247901_52147836) it's the middleware, not the component. – ndm Sep 03 '18 at 13:31
  • @ndm can you tell me how to fix this? thank you! – Daniele Cancani Sep 03 '18 at 14:37

6 Answers6

5

I think in Cake 3.6 You should remove CsrfProtectionMiddleware from middleware queue: src/Application.php

Dariusz Majchrzak
  • 1,227
  • 2
  • 12
  • 22
1

You also need to disable Security component. I use this for my API controllers:

$this->getEventManager()->off($this->Security);

if($this->request->is('post')) {
    $this->getEventManager()->off($this->Csrf);
}

I disable it only for POST requests, although disabling both Security and Csrf will work as well.


Edit: I put it in my AppController, although it will work per-controller.

Security component seems to enable CSRF and Form Tampering.

https://book.cakephp.org/3.0/en/controllers/components/security.html

Zlatan Omerović
  • 3,863
  • 4
  • 39
  • 67
0

You can try this

 public function beforeFilter(Event $event)
{
  $this->getEventManager()->makeMess($this->Csrf);
}

It's working for me!

You also try with Python Language or Symfony 2.8.

0

//Src/Application.php

public function middleware($middlewareQueue)
{
    $middlewareQueue
        // Catch any exceptions in the lower layers,
        // and make an error page/response
        ->add(ErrorHandlerMiddleware::class)

        // Handle plugin/theme assets like CakePHP normally does.
        ->add(new AssetMiddleware([
            'cacheTime' => Configure::read('Asset.cacheTime')
        ]))

        // Add routing middleware.
        // Routes collection cache enabled by default, to disable route caching
        // pass null as cacheConfig, example: `new RoutingMiddleware($this)`
        // you might want to disable this cache in case your routing is extremely simple
        ->add(new RoutingMiddleware($this, '_cake_routes_'));

        // Add csrf middleware.
        //Comment following Code.
       /* ->add(new CsrfProtectionMiddleware([
            'httpOnly' => true
        ]));*/

    return $middlewareQueue;
}

//Your perticular controller in my case //UsersController :

public function beforeFilter(Event $event)
{
    parent::beforeFilter($event);
    $this->viewBuilder()->layout('admin');
    $this->getEventManager()->off($this->Security);        
}

// for initialize method

public function initialize()
{
    parent::initialize();
    $this->loadComponent('RequestHandler');
    $this->loadComponent('Security');
}

Try this It's working...

Manoj
  • 1
  • 2
0

In CakePHP 3.6.10:

  1. go to src/Application.php
  2. Search function middleware
  3. Comment the below line:

    ->add(new CsrfProtectionMiddleware([ 'httpOnly' => true ]));

This would completely disable CSRF token check.

0

I'm using whitelistCallback for special prefix or action array

// in src/Application.php
use Cake\Http\Middleware\CsrfProtectionMiddleware;

public function middleware($middlewareQueue) {
    $csrf = new CsrfProtectionMiddleware();

    // Token check will be skipped when callback returns `true`.
    $csrf->whitelistCallback(function ($request) {
        // Skip token check for API URLs.
        if ($request->getParam('prefix') === 'api') {
            return true;
        }
    });

    // Ensure routing middleware is added to the queue before CSRF protection middleware.
    $middlewareQueue->add($csrf);

    return $middlewareQueue;
}
Jeremy Caney
  • 7,102
  • 69
  • 48
  • 77
vantungit
  • 1
  • 1