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][0][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 User
for WorkOrder
, and AuthorizedFriend
for
LineItem
, and imagine that an AuthorizedFriend
has special privileges
with User
s 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… ↩