Как это останавливает массовое назначение? - PullRequest
6 голосов
/ 21 июня 2011

Я хотел начать использовать attr_accessible с моими моделями, чтобы решить проблему с массовым назначением. Я понимаю, как это работает, и исследовал столько, сколько мог.

Чего я не понимаю, так это разницы между использованием update_attributes (params [: my_form]) или create (params [: my_form]) и настройкой полей по одному? Разве оба не так уязвимы?

В чем разница между НЕ иметь attr_accessible и делать это ...

@model_object = ModelObject.new
@model_object.create(params[:model_object_params])

И имея attr_accessible и делая это ...

@model_object = ModelObject.new
@model_object.field1 = params[:model_object_params][:field1]
@model_object.field2 = params[:model_object_params][:field2]
@model_object.field3 = params[:model_object_params][:field3]
@model_object.save!

Разве оба этих метода создания записи не так уязвимы? Хакер / взломщик может отправить URL-адрес обоим этим методам, и оба будут делать одно и то же, верно?

Или использование attr_accessible и обновление полей по одному делают что-то другое или как-то безопаснее?

Там, где все эти методы, которые я нахожу для использования attr_accessible, не имеют никакого смысла для меня. Похоже, делать то же самое двумя разными способами. Чего мне не хватает?

Спасибо.

Ответы [ 4 ]

7 голосов
/ 21 июня 2011

То, как вы это делаете, не мешает «массовому назначению».

«Массовое присвоение» - это термин, используемый, когда Rails обрабатывает присвоение значений атрибутам в модели. Обычно это делается в контроллере, используя имена и значения в params.

Когда вы делаете назначение себя, это также «массовое назначение», в некотором смысле; но у вас есть хороший контроль над тем, что назначать, а что нет в этом случае. Таким образом, чтобы сохранить запись этого стандартного кода назначения, Rails предоставляет attr_accesible - тот же элемент управления, меньше кода.

Чтобы увидеть, как это используется:

Предположим, что модель ActivityLog имеет атрибут с именем user_ip_address.

Теперь user_ip_address является атрибутом в модели, и может быть назначен массовым назначением или "самопрокатным массовым назначением".

Но в обоих случаях это неправильно - вы не хотите, чтобы пользовательский ввод устанавливал значение для этого атрибута.

Вместо этого вы всегда хотите узнать фактический IP-адрес пользователя и присвоить это значение (игнорируя любые значение в params). Таким образом, вы исключаете user_ip_address из attr_accessible и вместо этого назначаете его самостоятельно.

attr_accessible :all_attributes_except_user_ip_address

@al = ActivityLog.new(params[:model_object_params])
@al.user_ip_address = get_origin_user_ip_address
@al.save

Для любой информации, которую пользователь не может изменить, используйте attr_accessible и исключите ее из списка.

3 голосов
/ 21 июня 2011

Короткий ответ: он останавливает неявную установку field4.

Разница в том, что без attr_accessible хакер может обновить поле, которое отсутствует в вашей форме. С attr_accessible это невозможно.

например. если в вашей пользовательской модели есть поле is_admin, хакер может попытаться создать нового администратора, написав:

params[:user][:is_admin] = true

Если установлено attr_accessible (и, очевидно, оно не должно содержать is_admin), это невозможно.

О вашем примере: если ваша модель имеет только field1, field2 и field3 и нет других столбцов базы данных, которые вы хотите защитить, вам не нужно использовать attr_accessible. Надеюсь, это прояснит.

Просто помните:

без каких-либо мер предосторожности Model.new (params [: model]) позволяет злоумышленники, чтобы установить любой столбец базы данных значение.

Источник: http://guides.rubyonrails.org/security.html#mass-assignment

2 голосов
/ 21 июня 2011

Массовое задание - это не то, что вы мешаете, а то, что вы контролируете. Это хорошая функция, которая делает вещи проще и чище, но без какой-либо способности контролировать то, что устанавливается с помощью массового назначения, это потенциальная дыра в безопасности. attr_accessible, как уже упоминалось, обеспечивает этот контроль.

2 голосов
/ 21 июня 2011

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

Attr_accessible предназначен для ограничения «поверхности» вашей модели тем, что вы намереваетесь принять, и тщательно проверьте,Таким образом, вы можете автоматически игнорировать внедренный параметр, такой как: role => "admin", если вы добавите эту функцию в вашу модель

user.update_attributes(params[:user])

Поскольку атрибут role не указан в attr_accessible, попытка пользователястать администратором бесполезно.

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

...