Как это останавливает массовое назначение?

Я хотел начать использовать 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, которые я нахожу, не имеют для меня никакого смысла. Кажется, что одно и то же делается двумя разными способами. Что мне не хватает?

Спасибо.


person dsmorey    schedule 21.06.2011    source источник


Ответы (4)


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

«Массовое назначение» — это термин, используемый, когда 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 и исключите ее из списка.

person Zabba    schedule 21.06.2011
comment
О, я вижу, то, что я делаю, предотвращает установку таких вещей, как поля created_by или Creator_id, но без более точного контроля поля, которые отправляются и которые я назначаю, могут по-прежнему содержать вредоносные данные. Вот к чему это привело меня орехи. во всех этих примерах каждое поле просто назначалось вручную, а не путем передачи хэша параметров. Теперь вижу, спасибо. - person dsmorey; 21.06.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

person Mischa    schedule 21.06.2011

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

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

user.update_attributes(params[:user])

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

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

person Brad Langhorst    schedule 21.06.2011

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

person Tim Sullivan    schedule 21.06.2011