Статьи

Программирование с Yii2: Безопасность

Если вы спрашиваете: «Что такое Yii?» Ознакомьтесь с разделом Введение в Yii Framework , в котором рассматриваются преимущества Yii и представлен обзор Yii 2.0.

В этой серии «Программирование с Yii2» я расскажу читателям, как использовать Yii2 Framework для PHP. Если вы планируете поделиться своим приложением с общественностью, вам нужно, чтобы оно было безопасным, и лучше всего планировать это с самого начала. К счастью, начинание с фреймворка, такого как Yii, делает это намного проще, чем могло бы быть. Как указано в Особенности Yii :

Yii оснащен множеством мер безопасности, которые помогают защитить ваши веб-приложения от атак, таких как внедрение SQL, межсайтовый скриптинг (XSS), подделка межсайтовых запросов (CSRF) и фальсификация файлов cookie.

В этом руководстве я познакомлю вас с основными концепциями безопасности в рамках приложения Yii. И, если вам интересно, будущие эпизоды будут работать для защиты приложения Meeting Planner, представленного в нашей серии запуска , по мере приближения к альфа-версии.

Прежде чем мы начнем, пожалуйста, помните, я стараюсь участвовать в обсуждениях ниже. Если у вас есть вопрос или предложение по теме, пожалуйста, оставьте комментарий ниже или свяжитесь со мной в Twitter @reifman .

Примечание. Если вы заметили разрыв между эпизодами серии «Программирование Yii», то это потому, что в прошлом году мне пришлось сделать операцию на мозге . Спасибо за ваше терпение и поддержку — приятно регулярно писать снова, и я с нетерпением жду продолжения освещения Yii2.

Если вы новичок в области безопасности веб-приложений, вы можете многое понять о предложениях Yii. Я приложу все усилия, чтобы предложить обзор, основанный на лучшем из документации Yii 2.0. Команда Yii делит безопасность на семь ключевых областей :

  1. Аутентификация
  2. авторизация
  3. Работа с паролями
  4. криптография
  5. Виды безопасности
  6. Auth Clients
  7. Лучшие практики

Давайте начнем погружаться в них один за другим.

Презентация Илько Качарова « Yii Framework Security» предлагает несколько полезных слайдов, которые суммируют цель аутентификации (и следующую подтему, авторизация). По сути, вот вопросы, на которые должны ответить эти темы:

  • Кто такой пользователь?
  • Является ли пользователь, который они говорят, что они?
  • Пользователь авторизован для доступа к ресурсу?
  • Пользователь авторизован для выполнения действия?
  • Имеет ли пользователь право выполнять действия с ресурсом?

Класс yii / web / User Yii интегрируется с интерфейсом yii \ web \ IdentityInterface для управления статусом аутентификации пользователя в вашем приложении.

В ноябре прошлого года я написал учебник по расширенному шаблону приложения Yii . Одним из преимуществ расширенного шаблона является то, что он обеспечивает встроенную интеграцию модели User с ActiveRecord и вашей базой данных. Таким образом, ваше приложение предлагает аутентификацию на основе базы данных прямо из коробки.

Модель User позволяет программно входить и выходить из системы пользователей:

  • login () устанавливает указанное удостоверение и запоминает статус аутентификации в сеансе и cookie.
  • logout () помечает пользователя как гостя и очищает соответствующую информацию от сессии и куки.
  • setIdentity () : изменяет личность пользователя, не касаясь сессии или cookie, лучше всего подходит для функциональности API.

Свойство $ isGuest определяет, вошел ли текущий пользователь в систему или нет. Когда пользователь выходит из системы, он имеет значение null, но в противном случае возвращает экземпляр IdentityInterface.

По сути, вам нужен класс User, который расширяет ActiveRecord и реализует методы для поддержки IdentityInterface, например:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
<?php
 
use yii\db\ActiveRecord;
use yii\web\IdentityInterface;
 
class User extends ActiveRecord implements IdentityInterface
{
    public static function tableName()
    {
        return ‘user’;
    }
 
    /**
     * Finds an identity by the given ID.
     *
     * @param string|integer $id the ID to be looked for
     * @return IdentityInterface|null the identity object that matches the given ID.
     */
    public static function findIdentity($id)
    {
        return static::findOne($id);
    }
 
    /**
     * Finds an identity by the given token.
     *
     * @param string $token the token to be looked for
     * @return IdentityInterface|null the identity object that matches the given token.
     */
    public static function findIdentityByAccessToken($token, $type = null)
    {
        return static::findOne([‘access_token’ => $token]);
    }
 
    /**
     * @return int|string current user ID
     */
    public function getId()
    {
        return $this->id;
    }
 
    /**
     * @return string current user auth key
     */
    public function getAuthKey()
    {
        return $this->auth_key;
    }
 
    /**
     * @param string $authKey
     * @return boolean if auth key is valid for current user
     */
    public function validateAuthKey($authKey)
    {
        return $this->getAuthKey() === $authKey;
    }
}

Кроме того, перед созданием пользователя приложение генерирует случайную строку в качестве ключа авторизации. Это может быть использовано в письмах «забыли пароль» или в других ссылках для входа в систему на основе электронной почты:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
class User extends ActiveRecord implements IdentityInterface
{
    ……
     
    public function beforeSave($insert)
    {
        if (parent::beforeSave($insert)) {
            if ($this->isNewRecord) {
                $this->auth_key = \Yii::$app->security->generateRandomString();
            }
            return true;
        }
        return false;
    }
}

Yii предоставляет два встроенных подхода к авторизации. Более простой список контроля доступа (ACL) определяет, каким пользователям или процессам разрешено выполнять действия с ресурсом, а более интенсивный контроль доступа на основе ролей (RBAC) помогает управлять доступом путем определения ролей. В RBAC только пользователи или системные задачи с определенными ролями могут выполнять определенные действия.

ACL иногда также называют фильтром контроля доступа (ACF). Yii обеспечивает поддержку ACL в yii \ filters \ AccessControl . Идеально подходит для приложений, которым нужен только простой контроль доступа. Это то, что я использовал до сих пор в Meeting Planner.

Вот пример общего SiteController, настраивающего поведение доступа для фильтрации доступа к доступным действиям, часто к страницам. В этом случае ACL действует при регистрации, входе в систему и выходе из системы. '?' указывает, что любой пользователь может получить доступ к страницам входа и регистрации, в то время как '@' означает, что доступ разрешен только зарегистрированным или прошедшим проверку пользователям. В приведенном ниже примере только зарегистрированные пользователи могут выйти из системы:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
use yii\web\Controller;
use yii\filters\AccessControl;
 
class SiteController extends Controller
{
    public function behaviors()
    {
        return [
            ‘access’ => [
                ‘class’ => AccessControl::className(),
                ‘only’ => [‘login’, ‘logout’, ‘signup’],
                ‘rules’ => [
                    [
                        ‘allow’ => true,
                        ‘actions’ => [‘login’, ‘signup’],
                        ‘roles’ => [‘?’],
                    ],
                    [
                        ‘allow’ => true,
                        ‘actions’ => [‘logout’],
                        ‘roles’ => [‘@’],
                    ],
                ],
            ],
        ];
    }
    // …
}

По мере роста контроллера каждое новое действие должно быть определено в правилах AccessControl. И, по мере роста вашего приложения, каждый контроллер и все его действия должны интегрировать фильтрацию ACL для безопасности.

Управление доступом на основе ролей (RBAC) обеспечивает более надежную систему аутентификации, но также требует гораздо большего предварительного проектирования и реализации.

С RBAC вы определяете аутентификацию через роли, которые могут быть унаследованы (или нет), и вы применяете роли к пользователям. Вы также можете определить правила для ролей. Реализации RBAC могут быть довольно сложными.

На рисунке ниже администраторы могут выполнять любую задачу, а авторы могут создавать сообщения и обновлять свои собственные сообщения. Джейн — администратор, поэтому она может выполнять задачи администраторов, а Джон — просто автор:

Иллюстрация наследования управления доступом на основе ролей в Yii Framework

Yii реализует то, что он называет «Общей иерархической системой RBAC, следуя модели NIST RBAC ». Функциональность RBAC обеспечивается его компонентом приложения authManager .

Я не буду вдаваться в подробности с RBAC здесь, но я надеюсь, что в следующем уроке. Опять же, это зависит от редакционных богинь — говорить с ними всегда нелегко:

Yii2 Security Редакция богини NoOne в Envato заботится о бизнесе
через PopSugar

В основном, чтобы полностью внедрить RBAC, вы должны:

  • определить роли и разрешения
  • установить отношения между вашими ролями и разрешениями
  • определить любые существующие правила
  • связать правила с вашими ролями и разрешениями
  • и, наконец, назначьте роли пользователям

Ниже приведен код, необходимый для включения начала системы RBAC:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<?php
namespace app\commands;
 
use Yii;
use yii\console\Controller;
 
class RbacController extends Controller
{
    public function actionInit()
    {
        $auth = Yii::$app->authManager;
 
        // add «createPost» permission
        $createPost = $auth->createPermission(‘createPost’);
        $createPost->description = ‘Create a post’;
        $auth->add($createPost);
 
        // add «updatePost» permission
        $updatePost = $auth->createPermission(‘updatePost’);
        $updatePost->description = ‘Update post’;
        $auth->add($updatePost);
 
        // add «author» role and give this role the «createPost» permission
        $author = $auth->createRole(‘author’);
        $auth->add($author);
        $auth->addChild($author, $createPost);
 
        // add «admin» role and give this role the «updatePost» permission
        // as well as the permissions of the «author» role
        $admin = $auth->createRole(‘admin’);
        $auth->add($admin);
        $auth->addChild($admin, $updatePost);
        $auth->addChild($admin, $author);
 
        // Assign roles to users.
        // usually implemented in your User model.
        $auth->assign($author, 2);
        $auth->assign($admin, 1);
    }
}

Чтобы реализовать RBAC, вы должны быть готовы написать много кода заранее или по мере роста вашего приложения. И, если вы это сделаете, Yii будет управлять аутентификацией в соответствии с вашей структурой аутентификации. Другими словами, дизайн и кодирование обеспечивают надежную и детальную аутентификацию.

Как узнал Марк Цукерберг в июне, некоторые веб-сайты хранят пароли пользователей в виде простого текста , но ваши не должны; чтобы быть справедливым по отношению к Цукербергу, моя учетная запись на Facebook когда-то была взломана из-за того, что PHPList сделал то же самое — до дней менеджеров паролей. В любом случае, Yii позволяет легко шифровать и надежно проверять пароли.

Функция crypt в Yii использует bcrypt для генерации хэшей для вашего пароля. Когда люди регистрируются, создается хеш:

1
$hash = Yii::$app->getSecurity()->generatePasswordHash($password);

Затем, когда пользователь пытается войти в систему, он хэшируется и сравнивается с хэшем в базе данных:

1
2
3
4
5
if (Yii::$app->getSecurity()->validatePassword($password, $hash)) {
    // all good, logging user in
} else {
    // wrong password
}

Но вы также можете использовать Yii для защиты данных с помощью криптографии.

Yii Framework предоставляет ряд встроенных функций для поддержки защиты данных:

Любые данные, поступающие от пользователей, могут быть заражены атаками, такими как SQL-инъекция или кросс-браузерные сценарии. Важно, чтобы любые данные, которые вы выводите пользователям в представлениях, были очищены. Yii предлагает несколько способов для этого.

Во-первых, есть Html::encode , который существенно нарушает любой SQL или скриптинг:

1
2
3
4
5
6
7
<?php
use yii\helpers\Html;
?>
 
<div class=»username»>
    <?= Html::encode($user->name) ?>
</div>

И есть интеграция с библиотекой HtmlPurifier для больших текстовых блоков:

1
2
3
4
5
6
7
<?php
use yii\helpers\HtmlPurifier;
?>
 
<div class=»post»>
    <?= HtmlPurifier::process($post->text) ?>
</div>

Yii также предоставляет возможность сторонней аутентификации, что особенно полезно для поддержки входа в социальные сети через Google, Facebook, Twitter и т. Д.

Я написал несколько руководств для Envato Tuts + по использованию AuthClient в Yii Framework с социальными логинами:

Я обнаружил, что социальный вход в систему отлично работает для Meeting Planner . Новые пользователи могут начать планировать встречу без пароля.

Yii также рекомендует несколько лучших практик, когда речь заходит о безопасности веб-приложений. И его документация предоставляет хороший учебник по этим темам для всех.

  1. Фильтрация ввода и вывода
  2. Как избежать SQL-инъекций
  3. Избегание межсайтовых сценариев (XSS)
  4. Как избежать подделки межсайтовых запросов (CSRF)
  5. Как избежать воздействия на файл
  6. Как избежать отладочной информации и инструментов на производстве
  7. Использование безопасного соединения по TLS

Первые три темы, описанные выше, хорошо управляются путем кодирования, описанного выше в Views Security

Yii также предоставляет встроенную защиту CSRF для обычных действий — и может быть отключена при необходимости. В Meeting Planner мне пришлось отключить CSRF, чтобы принимать сообщения, отправленные из сервисов API Mailgun .

Что касается раскрытия файла, структура помогает минимизировать это, направляя все входные запросы в файл запроса web / index.php. Это значительно ограничивает необходимость написания кода приложения, который фильтрует запросы. Это хорошо в одном месте.

Наконец, использование HTTPS может помочь защитить ваши соединения и работать с Yii для защиты пользователей. Ранее в этом году я писал о Let’s Encrypt — вы можете использовать это руководство и для установки HTTPS для приложений Yii.

Если вы заинтересованы в чтении более подробных материалов по этим темам, Yii 1.x Framework предлагает эти посты. Конечно, они старше и менее специфичны для Yii 2, но они остаются полезными.

Надеюсь, вам понравился мой обзор безопасности для Yii2. Если вы интегрируете аспекты большинства или всех вышеперечисленных понятий в свое приложение, у вас должен быть в основном безопасный веб-сервис. Возможно, вы захотите ознакомиться с нашей серией «Построение стартапа с помощью PHP» для практической реализации некоторых из этих методов обеспечения безопасности.

Следите за будущими уроками в нашей серии «Программирование с Yii2», поскольку мы продолжаем изучать различные аспекты фреймворка. Я приветствую тематические и тематические запросы. Вы можете опубликовать их в комментариях ниже или написать мне по электронной почте на моем сайте Lookahead Consulting .

Если вы хотите узнать, когда появится следующий учебник по Yii2, следуйте за мной @reifman в Твиттере или зайдите на страницу моего инструктора . Моя страница инструктора будет включать все статьи из этой серии, как только они будут опубликованы.

Давайте работать вместе, чтобы радовать редакционных богинь.