Сильные параметры и безопасность

В методе контроллера у меня есть:

@user = current_user
@rel = Relationship.where('user_id = ? and organization_id = ? and fish = ?', @user.id, params[:user][:default_relationship_id], true).first
@user.update_attributes(default_relationship_id: @rel.id)

Я понимаю, что последняя строка небезопасна и требует надежных параметров для предотвращения массового назначения (это означает, что пользователь также может установить любую другую переменную базы данных для этого пользователя). Но как провести рефакторинг, чтобы сделать это безопасным (в данном случае и в более общем случае)?

Если я прав, есть два способа: 1) заменить его сильными параметрами или 2) использовать метод модели.

Объявление 1) Сильные параметры:

@user.update_attributes(update_params)
private
  def update_params
    params.require(:user).permit(:default_relationship_id)
  end

Но как это узнать, чтобы установить default_relationship_id в @rel.id?

Объявление 2) Добавьте его в метод модели:

@user.update_default(@rel.id)     # In controller

def update_default(value)         # In model file
  self.update_attributes(default_relationship_id: value)
end

Но будет ли это действительно безопасным, поскольку это не метод частной модели?

Может ли кто-нибудь объяснить мой вопрос по каждому из двух подходов и, возможно, объяснить, какой подход предпочтительнее?


person Marty    schedule 17.08.2015    source источник
comment
Но у вас нет массового назначения, это ваш пример, вы берете значение id из @rel   -  person Yury Lebedev    schedule 17.08.2015
comment
Как говорит Юрий, вы не используете пользовательский ввод, поэтому у вас нет проблем с массовым назначением.   -  person j-dexx    schedule 17.08.2015
comment
Но @rel основан на вводе пользователем (см. параметры, используемые в этой строке), а @rel используется для определения значения default_relationship_id. Или это не имеет значения, и является ли возможность нежелательного массового присвоения проблемой только в том случае, если вы напрямую обновляете значение на основе пользовательского ввода (вместо косвенного способа в моем примере)?   -  person Marty    schedule 17.08.2015
comment
@rel.id не основано на вводе пользователем напрямую, оно берется из базы данных   -  person Yury Lebedev    schedule 17.08.2015
comment
взгляните на ответ Фредерика Ченга, он объяснил, зачем нужна защита от массового присвоения   -  person Yury Lebedev    schedule 17.08.2015


Ответы (1)


Сильные параметры предназначены для массового назначения, то есть для таких случаев.

some_user.update_attributes(params[:user])

где пользователь мог манипулировать формой, чтобы включить дополнительные значения. То, что вы делаете, не является массовым назначением, поэтому сильные параметры не имеют значения. Кроме того, strong params не проверяет содержимое параметров (за исключением проверки того, что значения являются скалярами).

Вы все равно можете проверить, может ли пользователь установить для своего default_relationship_id это значение, но вам нужно будет реализовать эти проверки самостоятельно. Ни одно из ваших двух предложений не добавляет никакой безопасности (что может быть хорошо, если запрос, заполняющий @rel, будет возвращать только объекты, с которыми пользователю разрешено ассоциироваться)

person Frederick Cheung    schedule 17.08.2015