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.