Laravel защищает форму скрытых полей и URL

У меня есть редактирование, сделанное с помощью лезвия, для редактирования ресурса, например:

{{Form::model( $post ,['action'=> ['PostController@update', 'id' => $post->id], 'method' => 'post'])}}

Который генерирует форму с действием

http://example.com/posts/edit/123

И мои поля с текстом и скрытым вводом

Увидев этот URL-адрес, злонамеренный пользователь может легко обновить другие сообщения.

Как я могу защитить маршрут, чтобы он не работал, если идентификатор манипулируется инспектором? Есть ли встроенная функция для токенизации идентификатора, чтобы убедиться, что он совпадает? Можно ли применить это ко всем скрытым входам?

Спасибо

РЕДАКТИРОВАТЬ:

Пример использования моих скрытых полей: мои сообщения, как правило, представляют собой вопросы и ответы, когда пользователь пытается добавить ответ на вопрос, я устанавливаю question_id в качестве скрытого поля и хочу проверить, что им не манипулируют.


person SkarXa    schedule 08.04.2015    source источник
comment
Вместо того, чтобы пытаться защитить свои URL-адреса, вы должны защитить свои данные с помощью аутентификации и авторизации. Вместо того, чтобы полагаться на то, что пользователь не знает правильный URL-адрес, вы должны проверить логин и (при необходимости) разрешения пользователя.   -  person lukasgeiter    schedule 08.04.2015
comment
Я уже делаю это $this-›abortIfLoggedUserCantEdit($post-›user-›id ); Я просто хочу более общую функцию.   -  person SkarXa    schedule 08.04.2015
comment
Я просмотрел защиту CSRF, но она сохраняет токен в сеансе и проверяет, находится ли он в отправленной форме, а не в том, что html был изменен.   -  person SkarXa    schedule 08.04.2015
comment
Я использую jacopo/laravel-authentication-acl, но зарегистрированный пользователь также может быть пользователем с плохими намерениями.   -  person SkarXa    schedule 08.04.2015
comment
Ну, вы не всегда можете защитить себя от этого, но вы можете сделать это: установите переменную сеанса, равную идентификатору модели, когда запрашивается метод edit, затем извлеките эту переменную из сеанса при отправке формы, find() модель с этим идентификатором и обновите ее. Таким образом, вам даже не нужно будет хранить идентификатор в URL-адресе или в скрытом поле. Звучит как хорошее упражнение для промежуточного программного обеспечения!   -  person kalatabe    schedule 08.04.2015


Ответы (2)


Ответ Лимонте верен, чтобы обеспечить возможность редактировать сообщения других людей - и вы всегда должны это делать. Чтобы ответить на вторую половину вашего вопроса:

Я устанавливаю question_id как скрытое поле и хочу проверить, не манипулируют ли им.

Проблема в том, что вы никогда не можете доверять данным, предоставленным клиентом вашей системе. Вы должны всегда предполагать, что он был подделан.

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

{{ Form::hidden('question_id', Crypt::encrypt($question_id)) }}

Затем в вашем контроллере

$question_id = Crypt::decrypt(Input::get('question_id'));

Просто убедитесь, что вы установили случайный ключ шифрования приложения в файле конфигурации app.php.

person Laurence    schedule 08.04.2015
comment
Я добавлю зашифрованный route_id во все свои формы и поставлю фильтр, чтобы проверять его при каждом запросе. - person SkarXa; 08.04.2015
comment
@Laurence, я тоже пытаюсь реализовать это в своем проекте, но, немного подумав, я пришел к этому: шифровать только поле id не так уж хорошо. Потому что я могу перейти к пользователям с идентификатором X, проверить зашифрованный идентификатор в форме, а после этого перейти к ролям пользователей и поставить тот же зашифрованный идентификатор X, и он будет действительным, если роль с идентификатором X существует. Чтобы решить эту проблему, для каждой модели должен быть уникальный идентификатор, поэтому мы можем просто добавить шифрование перед именем модели поля идентификатора или именем таблицы базы данных. - person AlexIL; 12.10.2018
comment
Как использовать Crypt::encrypt в ‹form› HTML вместо использования {{ Form }} ? - person kevind; 29.05.2020

Чтобы защитить маршрут, вы должны проверить разрешение в PostController@update.

В начале метода проверьте, может ли пользователь редактировать данный пост:

public function update($postId)
{
    $post = Post::findOrFail($postId);

    if ($post->user_id !== Auth::id()) {
        abort(403, 'Unauthorized action.');
    }

    // validate, update record, etc.
}
person Limon Monte    schedule 08.04.2015
comment
Я делаю это, но мне нужен общий способ сделать это для всех моих маршрутов редактирования, также я не могу защитить скрытые поля таким образом. - person SkarXa; 08.04.2015
comment
Я не знаю, есть ли способ сделать это для всех ваших маршрутов редактирования. Вы можете использовать фильтр, но у вас будут другие маршруты, где параметры названы по-другому, и вы будете работать с другими отношениями. В итоге у вас будет 1 фильтр для каждого контроллера. - person user1669496; 08.04.2015
comment
Я думаю, что скрытый ввод в форму с хэшированным идентификатором и проверка совпадения идентификатора из маршрута и хэшированного могут работать - person SkarXa; 08.04.2015
comment
это Auth::id(), github.com/illuminate/auth/blob/master/Guard .php#L176 - person Limon Monte; 08.04.2015
comment
@limonte - лол - круто - я не знал, что такое существует. Узнавайте что-то новое каждый день! - person Laurence; 08.04.2015