Почему резка хэша params представляет проблему безопасности при массовом присвоении?
Официальным способом предотвращения угроз безопасности с массовым присвоением является attr_accessible. Однако некоторые программисты считают, что это не работа для модели (или, по крайней мере, не только для модели). Простейший способ сделать это в контроллере - это отрезать хэши params:
@user = User.update_attributes(params[:user].slice(:name))
Однако в документации указано:
Обратите внимание, что вместо харша абзаца Hash # except или Hash # для дезинфекции атрибутов не обеспечит достаточной защиты.
Почему? Почему белый список параметров не обеспечивает достаточной защиты?
ОБНОВЛЕНИЕ: Rails 4.0 будет поставлять сильные параметры, уточненный выбор параметров, поэтому я думаю, что целая нарезка была не так уж плоха в конце концов.
Ответы
Ответ 1
Проблема с срезом и за исключением контроллера может возникать в комбинации с accept_nested_attributes_for
в вашей модели. Если вы используете вложенные атрибуты, вам нужно будет срезать параметры во всех местах, где вы обновляете их в контроллере, что не всегда является самой легкой задачей, особенно с глубоко вложенными сценариями. С помощью attr_accesible
у вас нет этой проблемы.
Ответ 2
Как и в случае с Rails 4, нарезка параметров будет предпочтительным методом защиты от массового присвоения. Основная команда Rails уже разработала плагин для решения этой проблемы сейчас, и они работают над интеграцией поддержки вложенных атрибутов и подписанных форм. Определенно, что-то проверить: http://weblog.rubyonrails.org/2012/3/21/strong-parameters/
Ответ 3
Интересный смысл от DHH при разрезании в контроллере против белого списка:
https://gist.github.com/1975644
class PostsController < ActionController::Base
def create
Post.create(post_params)
end
def update
Post.find(params[:id]).update_attributes!(post_params)
end
private
def post_params
params[:post].slice(:title, :content)
end
end
Комментарий, подтверждающий необходимость управления этим в контроллере:
https://gist.github.com/1975644#gistcomment-88369
Я лично применяю оба - attr_accessible со срезом, чтобы гарантировать, что ничего неожиданного не пройдет. Никогда не полагайтесь только на черный список!
Ответ 4
Просто удаление имени: из хэша params работает, чтобы предотвратить установку этого атрибута для этого действия. Он работает только для действий, которые вы помните, защищая.
Однако эта практика не защищает вас от злоупотреблений, используя все методы, автоматически добавленные для ассоциаций.
class User < ActiveRecord::Base
has_many :comments
end
оставит вас уязвимыми для тех, кто устанавливает атрибут comments_ids
, даже если вы удаляете атрибут comments
из параметров.
Так как для ассоциаций добавлено множество методов, и поскольку они могут измениться в будущем, наилучшей практикой является защита ваших атрибутов на модели с помощью attr_accessible
. Это наиболее эффективно остановит эти атаки.
Ответ 5
@tokland Ваш последний комментарий некорректен. Если ваш веб-сайт не имеет браузера в качестве единственной точки входа, в которую входят данные и исчезает.
Если ваш webapp имеет API или взаимодействует с другой защитой API на уровне контроллера, он оставляет за ним дыры, и все данные из других источников не подвергаются дезинфекции или проверке. Я рекомендую сохранять вещи такими, какие они есть, включив защиту массового присвоения в application.rb и продвигая ActiveSupport FormHelpers, чтобы работать как стиль Django/Python.