Security

  • class SecurityComponent(ComponentCollection $collection, array $config = [])
  • The Security Component creates an easy way to integrate tightersecurity in your application. It provides methods for various tasks like:

  • Restricting which HTTP methods your application accepts.

  • Form tampering protection
  • Requiring that SSL be used.
  • Limiting cross controller communication.
    Like all components it is configured through several configurable parameters.All of these properties can be set directly or through setter methods of thesame name in your controller’s beforeFilter().

By using the Security Component you automatically get form tampering protection.Hidden token fields will automatically be inserted into forms and checked by theSecurity component.

If you are using Security component’s form protection features andother components that process form data in their startup()callbacks, be sure to place Security Component before thosecomponents in your initialize() method.

Note

When using the Security Component you must use the FormHelper to createyour forms. In addition, you must not override any of the fields’ “name”attributes. The Security Component looks for certain indicators that arecreated and managed by the FormHelper (especially those created inView\Helper\FormHelper::create() andView\Helper\FormHelper::end()). Dynamically alteringthe fields that are submitted in a POST request (e.g. disabling, deletingor creating new fields via JavaScript) is likely to cause the request to besend to the blackhole callback.

You should always verify the HTTP method being used before executing to avoidside-effects. You should check the HTTP method oruse Cake\Http\ServerRequest::allowMethod() to ensure the correctHTTP method is used.

Handling Blackhole Callbacks

  • SecurityComponent::blackHole(object $controller, string $error = '', SecurityException $exception = null)
  • If an action is restricted by the Security Component it is‘black-holed’ as an invalid request which will result in a 400 errorby default. You can configure this behavior by setting theblackHoleCallback configuration option to a callback functionin the controller.

By configuring a callback method you can customize how the blackhole processworks:

  1. public function beforeFilter(Event $event)
  2. {
  3. parent::beforeFilter($event);
  4.  
  5. $this->Security->setConfig('blackHoleCallback', 'blackhole');
  6. }
  7.  
  8. public function blackhole($type, SecurityException $exception)
  9. {
  10. if ($exception->getMessage() === 'Request is not SSL and the action is required to be secure') {
  11. // Reword the exception message with a translatable string.
  12. $exception->setMessage(__('Please access the requested page through HTTPS'));
  13. }
  14.  
  15. // Re-throw the conditionally reworded exception.
  16. throw $exception;
  17.  
  18. // Alternatively, handle the error, e.g. set a flash message &
  19. // redirect to HTTPS version of the requested page.
  20. }

Note

use $this->Security->config() for CakePHP versions prior to 3.4

The $type parameter can have the following values:

  • ‘auth’ Indicates a form validation error, or a controller/action mismatcherror.
  • ‘secure’ Indicates an SSL method restriction failure.

New in version cakephp/cakephp: 3.2.6

As of v3.2.6 an additional parameter is included in the blackHole callback,an instance of the Cake\Controller\Exception\SecurityException isincluded as a second parameter.

Restrict Actions to SSL

  • SecurityComponent::requireSecure()
  • Sets the actions that require a SSL-secured request. Takes anynumber of arguments. Can be called with no arguments to force allactions to require a SSL-secured.

  • SecurityComponent::requireAuth()

  • Sets the actions that require a valid Security Component generatedtoken. Takes any number of arguments. Can be called with noarguments to force all actions to require a valid authentication.

Restricting Cross Controller Communication

  • allowedControllers
  • A list of controllers which can send requeststo this controller.This can be used to control cross controller requests.
  • allowedActions
  • A list of actions which are allowed to send requeststo this controller’s actions.This can be used to control cross controller requests.
    These configuration options allow you to restrict cross controllercommunication. Set them with the setConfig() method, orconfig() if you are using a CakePHP version below 3.4.

Form Tampering Prevention

By default the SecurityComponent prevents users from tampering with forms inspecific ways. The SecurityComponent will prevent the following things:

  • Unknown fields cannot be added to the form.
  • Fields cannot be removed from the form.
  • Values in hidden inputs cannot be modified.
    Preventing these types of tampering is accomplished by working with the FormHelperand tracking which fields are in a form. The values for hidden fields aretracked as well. All of this data is combined and turned into a hash. Whena form is submitted, the SecurityComponent will use the POST data to build the samestructure and compare the hash.

Note

The SecurityComponent will not prevent select options from beingadded/changed. Nor will it prevent radio options from being added/changed.

  • unlockedFields
  • Set to a list of form fields to exclude from POST validation. Fields can beunlocked either in the Component, or withFormHelper::unlockField(). Fields that have been unlocked arenot required to be part of the POST and hidden unlocked fields do not havetheir values checked.
  • validatePost
  • Set to false to completely skip the validation of POSTrequests, essentially turning off form validation.
    The above configuration options can be set with setConfig() orconfig() for CakePHP versions below 3.4.

Usage

Using the security component is generally done in the controller’sbeforeFilter(). You would specify the security restrictions youwant and the Security Component will enforce them on its startup:

  1. namespace App\Controller;
  2.  
  3. use App\Controller\AppController;
  4. use Cake\Event\Event;
  5.  
  6. class WidgetsController extends AppController
  7. {
  8. public function initialize()
  9. {
  10. parent::initialize();
  11. $this->loadComponent('Security');
  12. }
  13.  
  14. public function beforeFilter(Event $event)
  15. {
  16. parent::beforeFilter($event);
  17.  
  18. if ($this->request->getParam('admin')) {
  19. $this->Security->requireSecure();
  20. }
  21. }
  22. }

The above example would force all actions that had admin routing torequire secure SSL requests:

  1. namespace App\Controller;
  2.  
  3. use App\Controller\AppController;
  4. use Cake\Event\Event;
  5.  
  6. class WidgetsController extends AppController
  7. {
  8. public function initialize()
  9. {
  10. parent::initialize();
  11. $this->loadComponent('Security', ['blackHoleCallback' => 'forceSSL']);
  12. }
  13.  
  14. public function beforeFilter(Event $event)
  15. {
  16. parent::beforeFilter($event);
  17.  
  18. if ($this->request->getParam('admin')) {
  19. $this->Security->requireSecure();
  20. }
  21. }
  22.  
  23. public function forceSSL($error = '', SecurityException $exception = null)
  24. {
  25. if ($exception instanceof SecurityException && $exception->getType() === 'secure') {
  26. return $this->redirect('https://' . env('SERVER_NAME') . Router::url($this->request->getRequestTarget()));
  27. }
  28.  
  29. throw $exception;
  30. }
  31. }

Note

Use $this->request->here() for CakePHP versions prior to 3.4.0

This example would force all actions that had admin routing to require secureSSL requests. When the request is black holed, it will call the nominatedforceSSL() callback which will redirect non-secure requests to securerequests automatically.

CSRF Protection

CSRF or Cross Site Request Forgery is a common vulnerability in webapplications. It allows an attacker to capture and replay a previous request,and sometimes submit data requests using image tags or resources on otherdomains. To enable CSRF protection features use theCross Site Request Forgery.

Disabling Security Component for Specific Actions

There may be cases where you want to disable all security checks for an action(ex. AJAX requests). You may “unlock” these actions by listing them in$this->Security->unlockedActions in your beforeFilter(). TheunlockedActions property will not affect other features ofSecurityComponent:

  1. namespace App\Controller;
  2.  
  3. use App\Controller\AppController;
  4. use Cake\Event\Event;
  5.  
  6. class WidgetController extends AppController
  7. {
  8. public function initialize()
  9. {
  10. parent::initialize();
  11. $this->loadComponent('Security');
  12. }
  13.  
  14. public function beforeFilter(Event $event)
  15. {
  16. parent::beforeFilter($event);
  17.  
  18. $this->Security->setConfig('unlockedActions', ['edit']);
  19. }
  20. }

Note

Use $this->Security->config() for CakePHP versions prior to 3.4.0

This example would disable all security checks for the edit action.