Assume the following setup in a typical rails application:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 # work_order.rb class WorkOrder < ActiveRecord::Base has_many :line_items accepts_nested_attributes_for :line_items end #line_item.rb class LineItem < ActiveRecord::Base belongs_to :work_order end # work_orders_controller.rb class WorkOrdersController < ApplicationController # .... standard code here ..... private def work_order_params params.require(:work_order) .permit(date, #.. various Work Order properties line_items_attributes: [ # various attrs here, i.e. qty, cost :work_order_id ]) end end
Note the inclusion of
work_order_id in the line_item_attributes array. All
a potential attacker has to do is insert a hidden html input tag into the edit form of a
work_order similar to this:
<input type="hidden" name="work_order[labor_items_attributes][work_order_id]" value="509">
When they submit the form, the labor item will then be assigned to the work order with id ‘509’. Whoops.
The kicker to all this is that you don’t actually need to include the ‘work_order_id’ for everything to work correctly, Rails knows1 that the line item you are creating is for ‘this’ work order.
This may not seem like a big deal in this context, and in truth it’s probably
not. However, substitute a
LineItem, and imagine that an
AuthorizedFriend has special privileges
Users content, where that content is pictures, payment methods
etc. See the problem?
Be careful what parameters you are allowing! Even though rails ‘does’ a lot of security for you, that doesn’t mean you can just forget about security altogether when designing and developing software applications.
How does rails know this? Good question! stay tuned for a blog post on this very subject… ↩