Securing Applications

Preventing SQL Injections

SQL Injections are a common type of attack
and can take very different forms.

The ORM will quote any values that are passed as condition values automatically in order to
protect your application from injection attacks.

  1. $author = 'UNTRUSTED USER INPUT';
  2. Posts::find('first', [
  3. 'conditions' => ['author' => $author]
  4. ]);

However you cannot rely on this feature if you use user input in any other place of a query. The
following example shows how untrusted user input can be used safely used to specify the set of
fields to be retrieved. As a countermeasure we first check if the provided field actually exists.

  1. $field = 'UNTRUSTED USER INPUT';
  2. if (!Posts::hasField($field)) {
  3. throw new Exception('Invalid field.');
  4. }
  5. Posts::find('first', [
  6. 'fields' => [$field, 'title']
  7. ]);

Securing Form Fields and Values

The FormSignature class cryptographically signs web forms, to prevent adding or removing
fields, or modifying hidden (locked) fields.

Using the Security helper, FormSignature calculates a hash of all fields in a form, so that
when the form is submitted, the fields may be validated to ensure that none were added or
removed, and that fields designated as locked have not had their values altered.

To enable form signing in a view, simply call $this->security->sign() before generating your
form. In the controller, you may then validate the request by passing $this->request to the
check() method.

Inside the view:

  1. <?php $this->security->sign() ?>
  2. <?= $this->form->create($post) ?>
  3. <?= $this->form->field('title') ?>
  4. <?= $this->form->field('body', ['type' => 'textarea']) ?>
  5. <?= $this->form->field('') ?>
  6. <?= $this->form->submit('save') ?>
  7. <?= $this->form->end() ?>

Inside a controller action:

  1. if ($this->request->is('post') && !FormSignature::check($this->request)) {
  2. // The key didn't match, meaning the request has been tampered with.
  3. }

To make form signing work, you must use the form helper to create the form and its fields.

When fields are inserted dynamically into the form (i.e. through JavaScript) then those can
be manually excluded while checking the signature.

  1. FormSignature::check($this->request, [
  2. 'exclude' => [
  3. '_wysihtml5'
  4. ]
  5. ]);

Preventing Mass Assignment

To prevent your application from opening up to the so called mass assingment vulnerabilty,
the framework provides you with the whitelist feature. This whitelist can be used to limit the set of fields which get updated during create or update operations.

  1. $data = [
  2. 'name' => 'John Doe',
  3. 'email' => 'haxx0r@example.org' // Added by the attacker.
  4. ];
  5. $user = Users::findById($authed['user']['id']);
  6. $user->save();

As a countermeasure additionally use the whitelist feature. So that in this
case really just the name field gets updated.

  1. $user = Users::findById($authed['user']['id']);
  2. $user->save($data, [
  3. 'whitelist' => ['name']
  4. ]);

Always prefer whitelisting over blacklisting.

Secure Your Database

There has recently been a study into how many people aren’t properly securing their mongo databases. The study found that over 40,000 sites using MongoDB didn’t correctly configure their databases to use a password so that a malicious user could connect without any verification. When putting your database system online, make sure that you properly configure your database so that it is secure.