security-passwords.md 5.1 KB
Newer Older
1 2 3
Security
========

4
> Note: This section is under development.
Qiang Xue committed
5

Aris Karageorgos committed
6
Good security is vital to the health and success of any application. Unfortunately, many developers cut corners when it comes to security, either due to a lack of understanding or because implementation is too much of a hurdle. To make your Yii powered application as secure as possible, Yii has included several excellent and easy to use security features.
7

8

9
Hashing and verifying passwords
10
-------------------------------
11

Aris Karageorgos committed
12
Most developers know that passwords cannot be stored in plain text, but many developers believe it's still safe to hash passwords using `md5` or `sha1`. There was a time when using the aforementioned hashing algorithms was sufficient, but modern hardware makes it possible to reverse such hashes very quickly using brute force attacks.
13

Aris Karageorgos committed
14
In order to provide increased security for user passwords, even in the worst case scenario (your application is breached), you need to use a hashing algorithm that is resilient against brute force attacks. The best current choice is `bcrypt`. In PHP, you can create a `bcrypt` hash  using the [crypt function](http://php.net/manual/en/function.crypt.php). Yii provides two helper functions which make using `crypt` to securely generate and verify hashes easier.
15

Larry Ullman committed
16
When a user provides a password for the first time (e.g., upon registration), the password needs to be hashed:
17

Aris Karageorgos committed
18

19
```php
20
$hash = Yii::$app->getSecurity()->generatePasswordHash($password);
21 22
```

Aris Karageorgos committed
23 24 25
The hash can then be associated with the corresponding model attribute, so it can be stored in the database for later use.

When a user attempts to log in, the submitted password must be verified against the previously hashed and stored password:
26 27 28


```php
29
if (Yii::$app->getSecurity()->validatePassword($password, $hash)) {
30
    // all good, logging user in
Larry Ullman committed
31
} else {
32
    // wrong password
33 34 35
}
```

Aris Karageorgos committed
36
Generating Pseudorandom data
37 38
-----------

39
Pseudorandom data is useful in many situations. For example when resetting a password via email you need to generate a token, save it to the database, and send it via email to end user which in turn will allow them to prove ownership of that account. It is very important that this token be unique and hard to guess, else there is a possibility that attacker can predict the token's value and reset the user's password.
Aris Karageorgos committed
40 41

Yii security helper makes generating pseudorandom data simple:
42 43 44


```php
45
$key = Yii::$app->getSecurity()->generateRandomString();
46 47
```

Aris Karageorgos committed
48 49
Note that you need to have the `openssl` extension installed in order to generate cryptographically secure random data.

50 51 52
Encryption and decryption
-------------------------

53
Yii provides convenient helper functions that allow you to encrypt/decrypt data using a secret key. The data is passed through the encryption function so that only the person which has the secret key will be able to decrypt it.
Aris Karageorgos committed
54
For example, we need to store some information in our database but we need to make sure only the user which has the secret key can view it (even if the application database is compromised):
55 56 57


```php
Aris Karageorgos committed
58
// $data and $secretKey are obtained from the form
59
$encryptedData = Yii::$app->getSecurity()->encryptByPassword($data, $secretKey);
60 61 62
// store $encryptedData to database
```

Aris Karageorgos committed
63
Subsequently when user wants to read the data:
64 65

```php
Aris Karageorgos committed
66
// $secretKey is obtained from user input, $encryptedData is from the database
67
$data = Yii::$app->getSecurity()->decryptByPassword($encryptedData, $secretKey);
68 69
```

70
Confirming data integrity
71 72
--------------------------------

73
There are situations in which you need to verify that your data hasn't been tampered with by a third party or even corrupted in some way. Yii provides an easy way to confirm data integrity in the form of two helper functions.
Aris Karageorgos committed
74 75 76

Prefix the data with a hash generated from the secret key and data

77

Aris Karageorgos committed
78
```php
79
// $secretKey our application or user secret, $genuineData obtained from a reliable source
80
$data = Yii::$app->getSecurity()->hashData($genuineData, $secretKey);
Aris Karageorgos committed
81 82 83 84 85
```

Checks if the data integrity has been compromised

```php
86
// $secretKey our application or user secret, $data obtained from an unreliable source
87
$data = Yii::$app->getSecurity()->validateData($data, $secretKey);
Aris Karageorgos committed
88
```
89 90


91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
todo: XSS prevention, CSRF prevention, cookie protection, refer to 1.1 guide

You also can disable CSRF validation per controller and/or action, by setting its property:

```php
namespace app\controllers;

use yii\web\Controller;

class SiteController extends Controller
{
    public $enableCsrfValidation = false;

    public function actionIndex()
    {
        // CSRF validation will not be applied to this and other actions
    }

}
```

To disable CSRF validation per custom actions you can do:

```php
namespace app\controllers;

use yii\web\Controller;

class SiteController extends Controller
{
    public function beforeAction($action)
    {
        // ...set `$this->enableCsrfValidation` here based on some conditions...
        // call parent method that will check CSRF if such property is true.
        return parent::beforeAction($action);
    }
}
```

130 131 132 133
Securing Cookies
----------------

- validation
134
- httpOnly is default
135 136 137 138

See also
--------

139
- [Views security](structure-views.md#security)
140