Страница 1 из 1

Как лучше поступить с данными из формы(безопасность) ?

Добавлено: 2017.04.18, 16:25
zxczxc12
Hi

Подскажите плиз как лучше сделать .

Есть форма с данными которые вводят пользователи : Имя , о себе и тп

Как лучше поступить что бы не нарваться на XSS ?

Есть вариант выводить в браузер с Html::encode()

Но меня посетила мысль . А не лучше сразу фильтровать данные пользователя и уже отфильтрованные данные заносить в БД ?

Прописать в модели так , что бы данные уже автоматом фильтровались скажем как это: Yii::$app->formatter->asNtext($text)

Как лучше ?
И если второй вариант хорош < То как практически сделать что бы при валидации применялся нужный фильтр по функционалу похожий на Yii::$app->formatter->asNtext($text) или Html::encode ?

Код: Выделить всё

/**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            ['login', 'trim'],
            ['user_name', <ФИЛЬТР>],
        ];
    }

Re: Как лучше поступить с данными из формы(безопасность) ?

Добавлено: 2017.04.18, 16:29
urichalex
1. Я считаю, что при выводе всё равно надо фильтровать, так что лишний фильтр в базу - лишнее
2. Есть валидатор

Код: Выделить всё

public function rules()
    {
        return [
            ['login', 'trim'],
            ['user_name', 'filter', 'filter' => 'trim']
        ];
    }

Re: Как лучше поступить с данными из формы(безопасность) ?

Добавлено: 2017.04.18, 17:41
Alexum
Если очень хочется, то можно:

Код: Выделить всё

/**
     * @inheritdoc
     */
    public function rules()
    {
        return [
	     ...
            ['user_name', 'filter', 'filter' => '\yii\helpers\HtmlPurifier::process']
        ];
    }
При выводе всё равно продолжаем экранировать, мало ли.

Re: Как лучше поступить с данными из формы(безопасность) ?

Добавлено: 2017.04.18, 17:59
urichalex
Alexum писал(а): 2017.04.18, 17:41 Если очень хочется, то можно:

Код: Выделить всё

/**
     * @inheritdoc
     */
    public function rules()
    {
        return [
	     ...
            ['user_name', 'filter', 'filter' => '\yii\helpers\HtmlPurifier::process']
        ];
    }
При выводе всё равно продолжаем экранировать, мало ли.
А если надо сконфигурировать

Код: Выделить всё

/**
     * @inheritdoc
     */
    public function rules()
    {
        return [
	     ...
            ['user_name', 'filter', 'filter' => function($value) {
            	return \yii\helpers\HtmlPurifier::process($value, [
            		...
            	]);
            }]
        ];
    }

Re: Как лучше поступить с данными из формы(безопасность) ?

Добавлено: 2017.04.18, 20:13
samdark
Входные данные не надо изменять, их надо экранировать при выводе. Потом понадобится выводить в консоль или редактировать, а они уже изменённые.

Re: Как лучше поступить с данными из формы(безопасность) ?

Добавлено: 2017.04.18, 21:24
zxczxc12
Всем спасибо !

Но тогда ещё вопрос , как лучше эранировать ( чем )

В смысле , достаточно ли Html::encode или HtmlPurifier ?
И вообще, всякий таких "очистителей" - вагон:
как средствами самого PHP ( strip_tags, htmlspecialchars )
так и средствами фреймворка и его библиотек:
HtmlPurifier
Yii::$app->formatter->asNtext($text);
Yii::$app->formatter->asText($text);

и тп ?

Что выбрать с точки зрения быстродействия и безопасности ?
И что выбрать если выводится просто текст и текст с BB-кодами ?

Разнообразие выбора вводит в заблуждения и я начинаю заблуждаться :-)

Re: Как лучше поступить с данными из формы(безопасность) ?

Добавлено: 2017.04.19, 01:07
samdark
Просто текст — Html::encode. HTML — HtmlPurifier. Это если выводите в HTML.

Re: Как лучше поступить с данными из формы(безопасность) ?

Добавлено: 2017.04.19, 01:07
samdark
BBCode даёт вам HTML, так что HtmlPurifier.

Re: Как лучше поступить с данными из формы(безопасность) ?

Добавлено: 2017.04.20, 14:48
zxczxc12
Еще вопросик

В модели с атрибутами требующих экранирование, сделал так:

Код: Выделить всё

class UserProfile extends MainUserProfile
{
    public function afterFind()
    {
        parent::afterFind();

        $this->greeting = prepareText($this->greeting);
        $this->additional_interests = prepareText($this->additional_interests);
        $this->about = prepareText($this->about);
        $this->name = prepareText($this->name, false);
    }

и вот такую глобальную функцию в хелпере

Код: Выделить всё

//  Очищение строки перед выводом в браузер
function prepareText($string, $up_first_string = true, $html = false)
{
    $string=preg_replace("/[\r\n]+/", "\n", $string);
    $string=preg_replace("/[ \t]+/", " ", $string);

    if ($html == false) {
        $string = strip_tags($string);
        $string = htmlspecialchars($string);
    } else {
        $string=str_replace( "\n", '<br />', $string);
        $string = \yii\helpers\HtmlPurifier::process($string, [
            'HTML.Allowed' => 'p,br',
        ]);
    }
    if ($up_first_string) {
        $string = mb_ucfirst($string);
    }

    return $string;
}

Вроде бы все хорошо и удобно ибо везде во вьюхах у меня будет выводиться содержимое пользователя по феншую и риск где то забыть экранирование полностью отсутствует.

Но , проблема ( проблема ? ) в том , что функция prepareText будет вызываться даже тогда , когда вывод текста и не предполагается


Стоит ли заморачиваться на некоторую задержку в скорости работы приложения или лучше таки фильтровать непосредственно во вьюхе каждый нужный атрибут ?

Re: Как лучше поступить с данными из формы(безопасность) ?

Добавлено: 2017.04.21, 07:50
maleks
zxczxc12 писал(а): 2017.04.20, 14:48
Но , проблема ( проблема ? )
Еще проблемы:
- данные у вас теперь искажены и любой другой код, работающий с этой моделью, получит искаженные данные
- перед сохранением, придется в beforeSave делать обратное преобразование

Re: Как лучше поступить с данными из формы(безопасность) ?

Добавлено: 2017.04.21, 13:15
caHek2x
лучше таки фильтровать непосредственно во вьюхе каждый нужный атрибут !

Re: Как лучше поступить с данными из формы(безопасность) ?

Добавлено: 2017.04.21, 19:39
zxczxc12
Всем спасибо , все понятно !