CakePHP security component blackholing login (data[_Token][key] field not generated)

cakephp, cakephp-2.3, security

Solution

In what order did you add your components? The security-component should be put before other components that handle form-data in their `startup()`:

"If you are using Security component’s form protection features and other components that process form data in their startup() callbacks, be sure to place Security Component before those components in your $components array."

Security

Because the AuthComponent does handle form data inside the `startup()`, I think this applies, so be sure that the SecurityComponent is before the AuthComponent in your $components array;

public $components = array(
    'Security',
    'Session',
    'Auth' => array(
        // auth component settings
    )
);

Update

The 'final' answer as posted by the OP made clear that this question could not have been answered. as it turned out, somebody in the team made modifications to the HtmlHelper, causing it to not output 'hidden' blocks, and therefore not outputting the CSRF token.

In normal situations, you should never make modifications to the CakePHP Framework files themselves. CakePHP offers ways to override its functionality (including Helpers) without modifying the 'core' CakePHP files.

Why modifying CakePHP files is bad

Consider, for example, a car. What if a mechanic didn't like the design and decided to 'swap' the brake and accelerator pedals?

Of course, the car is still able to drive if you we're aware of this modification. However, without this important information, any other driver would definitely crash (and wonder what the heck just happened!?)

If the default behavior of the framework doesn't fit your needs, extend those classes. Do not modify the framework files themselves (unless there really is no other option). If modifications to the framework are absolutely nescessary, be sure to discuss this with the team and write documentation on the changes that have been made.

Keep in mind that it will no longer be possible to update the framework to a newer version, without applying the same modifications to the updated version as well. Again, if the changes have not been documented, somebody might update CakePHP and destroy your modifications.

Also, if you override or modify CakePHP, make sure that the overrides are compatible with the default behavior of CakePHP and the unit tests of CakePHP still run correctly (or create new Unit Tests for the modifications)

Using 'customised' Helpers in CakePHP

If you need to customise the CakePHP Helpers (or other components), there are various options to do so without modifying the CakePHP files;

1. Extend the Helper

class AwesomeHtmlHelper extends HtmlHelper {
    /**
     * enhanced tableHeaders method, outputs tableHeaders in a 'thead' tag
     *
     * {@inheritdoc}
     */
    public function tableHeaders(array $names, array $trOptions = null, array $thOptions = null)
    {
        $output = parent::tableHeaders($names, $trOptions, $thOptions);
        return '<thead>' . $output . '</thead>';
    }
}

Then, use your Helper the regular way:

echo $this->AwesomeHtml->tableHeaders(array('Date', 'Title', 'Active'));

2. 'Drop-in' replacement - use an alias (CakePHP > 2.3)

Since CakePHP 2.3 its possible to use an alias for a Helper. This functionality can be used in situations where (for example) two Helpers with the same name exist in your Application (e.g. Plugin.HtmlHelper).

Also, this allows you override a CakePHP Helper with your own Helper. See the documentation here: Using and Configuring Helpers

Be aware that this will override the Helper everywhere in your application!

public $helpers = array(
    'Html' => array(
        'className' => 'AwesomeHtml'
    )
);

Now, `$this->Html` will actually refer to the `AwesomeHtmlHelper` in your views:

echo $this->eHtml->tableHeaders(array('Date', 'Title', 'Active'));

Will output your 'enhanced' table headers

Problem

When I try to login, the request gets blackholed by teh `Security` component. How can I make it work right? I have a simple login form ``` <div class="container container-login"> <h2><?php echo __('Login'); ?></h2> <div class="wrap-form-signin"> <?php echo $this->Form->create('User', array('action' => 'login', 'class' => 'form-signin')); echo $this->Form->input('username', array('label' => '', 'placeholder' => __('Email'))); echo $this->Form->input('password', array('label' => '', 'placeholder' => __('Password'))); echo $this->Form->submit(__('Login')); echo $this->Form->end(); ?> </div> </div> ``` The controller action goes like this: ``` public function login() { if ($this->request->is('post')) { if ($this->Auth->login()) { return $this->redirect($this->Auth->redirectUrl()); } else { $this->Session->setFlash(__('Username or password is incorrect'), 'default', array(), 'auth'); } } } ``` And the `Security` component is included in `AppController` ``` public $components = array('Security', ... ); ``` In the error.log I get: ``` 2013-03-29 13:40:58 Error: [BadRequestException] The request has been black-holed Request URL: /users/login Stack Trace: #0 C:\wamp\www\cdx\lib\Cake\Controller\Component\SecurityComponent.php(234): SecurityComponent->blackHole(Object(UsersController), 'auth') #1 [internal function]: SecurityComponent->startup(Object(UsersController)) #2 C:\wamp\www\cdx\lib\Cake\Utility\ObjectCollection.php(131): call_user_func_array(Array, Array) #3 [internal function]: ObjectCollection->trigger(Object(CakeEvent)) #4 C:\wamp\www\cdx\lib\Cake\Event\CakeEventManager.php(247): call_user_func(Array, Object(CakeEvent)) #5 C:\wamp\www\cdx\lib\Cake\Controller\Controller.php(670): CakeEventManager->dispatch(Object(CakeEvent)) #6 C:\wamp\www\cdx\lib\Cake\Routing\Dispatcher.php(183): Controller->startupProcess() #7 C:\wamp\www\cdx\lib\Cake\Routing\Dispatcher.php(161): Dispatcher->_invoke(Object(UsersController), Object(CakeRequest), Object(CakeResponse)) #8 C:\wamp\www\cdx\app\webroot\index.php(92): Dispatcher->dispatch(Object(CakeRequest), Object(CakeResponse)) #9 {main} ``` How can I find what is making my request go to black hole? When I tried to use a custom blackhole handler, the type of the error was `auth`. But that's all the information I can get My version of CakePHP is 2.3.1 EDIT: The login works well without the `Security` component. After adding it to the `AppController`, the login stops working. EDIT2: I don't have any `data[_Token][key]` fields in the form EDIT3 THE SOLLUTION: Someone from my team has overriden the HTMLHelper class and it missed "hiddenblock" in the _tags array, which resulted in missing _Token fields. For details, see mine and thaJeztah's answers along with the comments bellow them

Original source