sinaptia waves

Using strong_params beyond mass assignments

Nazareno Moresco
Aug 3rd, 2023

If you’ve been using Ruby on Rails for some time, you may instantly identify the issue with the following code snippet:

class AnyController < ApplicationController
  def create
    AnyModel.create!(params)
  end
end

Yes, you’ve got it - it’s missing the use of strong parameters! Strong parameters are a security feature provided by Rails to limit the parameters for mass assignment until they’ve been explicitly allowed.

Here’s how the improved code should look:

class AnyController < ApplicationController
  def create
    AnyModel.create!(create_params)
  end

  private

  def create_params
    params.permit(:name, :age, associated_attributes: [:id, :name, :category])
  end
end

However, I’d like to propose a broader perspective: the use of strong parameters should extend beyond mass assignments.

Consider the following code snippet:

class AnyController < ApplicationController
  def create
    boolean_records = OtherModel.where(boolean: params[:boolean])

    # continues...
  end
end

Here, we might naturally assume that params[:boolean] will always hold a single value, such as true, false, or at worst, a truthy or falsy value. However, it could also contain an array of booleans, like [true, false], leading to unpredictable execution paths.

To ensure that the boolean remains a scalar value, we can use strong parameters like so:

class AnyController < ApplicationController
  def create
    boolean_records = OtherModel.where(boolean: permitted_params[:boolean])

    # continues...
  end

  private

  def permitted_params
    params.permit(:boolean)
  end
end

The key takeaway here is that the use of strong parameters is a simple yet powerful way of ensuring that we’re dealing with scalar values or nested attributes. Not using them could lead to unexpected outcomes that potentially disrupt the functionality of an endpoint, or, in rare cases, introduce security vulnerabilities.