Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 118 lines (72 sloc) 4.228 kb
97e8705 @dcunning initial version to keep your controllers secure by default
dcunning authored
1 # ParamAccessible
2
3 [![Build Status](https://secure.travis-ci.org/topdan/param_accessible.png)](https://secure.travis-ci.org/topdan/param_accessible.png)
4
5 Provides a method to help protect your Ruby on Rails controllers from malicious or accidentally destructive user parameters. It is independent, but heavily influenced by param_protected.
6
7 Make all your controllers secure by default as well as provide readable messages to users when a security breach was prevented.
8
9 For more information on the design considerations please visit: https://www.topdan.com/ruby-on-rails/params-accessible.html
10
11 ## Installation
12
13 Add this line to your application's Gemfile:
14
15 gem 'param_accessible'
16
17 And then execute:
18
19 $ bundle
20
21 Or install it yourself as:
22
23 $ gem install param_accessible
24
25 ## Usage
26
a15d603 @dcunning numbers are blocking the code tags
dcunning authored
27 This gem does not add any functionality by default. To activate it create a before_filter in any ActionController::Base subclass. We only use the filter for create and update actions because those are the normally only the only harmful ones:
019f9e6 @dcunning more usage and better examples
dcunning authored
28
29 before_filter :ensure_params_are_accessible, :only => [:create, :update]
30
a15d603 @dcunning numbers are blocking the code tags
dcunning authored
31 Now let's expose the most common rails parameters: controller, action, format, and id
019f9e6 @dcunning more usage and better examples
dcunning authored
32
33 param_accessible :controller, :action, :format, :id
34
a15d603 @dcunning numbers are blocking the code tags
dcunning authored
35 We also want to make sure only admins can change a user's "is_admin" and "is_active" attributes:
019f9e6 @dcunning more usage and better examples
dcunning authored
36
37 param_accessible :user => [:is_admin, :is_active], :if => :is_admin?
38
a15d603 @dcunning numbers are blocking the code tags
dcunning authored
39 Rinse and repeat for all your controllers and you're Rails Application will be much safer.
019f9e6 @dcunning more usage and better examples
dcunning authored
40
41 ## Example
42
43 Making create and update actions secure by default for all your application's controllers, exposing common parameters, and providing a readable error message to the user when there is a problem.
44
97e8705 @dcunning initial version to keep your controllers secure by default
dcunning authored
45 class ApplicationController < ActionController::Base
46
47 # make all your controllers secure by default
48 before_filter :ensure_params_are_accessible, :only => [:create, :update]
49
50 # expose the common rails parameters
51 param_accessible :controller, :action, :format, :id
52
76d5031 @dcunning typos
dcunning authored
53 # this error is thrown when the user submits an inaccessible param
97e8705 @dcunning initial version to keep your controllers secure by default
dcunning authored
54 rescue_from ParamAccessible::Error, :with => :handle_param_not_accessible
55
56 protected
57
58 def handle_param_not_accessible e
76d5031 @dcunning typos
dcunning authored
59 flash[:error] = "You gave me some invalid parameters: #{e.inaccessible_params.join(', ')}"
97e8705 @dcunning initial version to keep your controllers secure by default
dcunning authored
60 redirect_to :back
61 end
62
63 end
019f9e6 @dcunning more usage and better examples
dcunning authored
64
65 Inheriting from the class above, we now need to specify our accessible parameters for the create and update actions.
66
76d5031 @dcunning typos
dcunning authored
67 class UsersController < ApplicationController
97e8705 @dcunning initial version to keep your controllers secure by default
dcunning authored
68
69 # these attributes are available for everyone
019f9e6 @dcunning more usage and better examples
dcunning authored
70 param_accessible :user => [:name, :email, :password, :password_confirmation]
97e8705 @dcunning initial version to keep your controllers secure by default
dcunning authored
71
72 # these attributes are only available if the controller instance method is_admin? is true
019f9e6 @dcunning more usage and better examples
dcunning authored
73 param_accessible :user => [:is_admin, :is_locked_out], :if => :is_admin?
97e8705 @dcunning initial version to keep your controllers secure by default
dcunning authored
74
75 def update
76 @user = User.find(params[:id])
77
78 # this is now safe!
79 if @user.update_attributes(params[:user])
80 ...
81 else
82 ...
83 end
84 end
85 end
019f9e6 @dcunning more usage and better examples
dcunning authored
86
87 Showcase a helper module for handling errors and some more options.
88
97e8705 @dcunning initial version to keep your controllers secure by default
dcunning authored
89 class DemoController < ApplicationController
90
91 # rescue_from ParamAccessible::Error and respond with a 406 Not Acceptable status
92 # with an HTML, JSON, XML, or JS explanation of which parameters were invalid
93 include ParamAccessible::NotAcceptableHelper
94
95 param_accessible :foo, :if => :is_admin
96 param_accessible :bar, :unless => :logged_in?
97 param_accessible :baz, :only => :show
98 param_accessible :nut, :except => :index
99
100 end
019f9e6 @dcunning more usage and better examples
dcunning authored
101
102 Using Rails' skip_before_filter to make a controller insecure again
103
97e8705 @dcunning initial version to keep your controllers secure by default
dcunning authored
104 class InsecureController < ApplicationController
105
106 # skip the filter ApplicationController set up to avoid the accessible parameter checks
107 skip_before_filter :ensure_params_are_accessible
108
109 end
110
111 ## Contributing
112
113 1. Fork it
114 2. Create your feature branch (`git checkout -b my-new-feature`)
115 3. Commit your changes (`git commit -am 'Added some feature'`)
116 4. Push to the branch (`git push origin my-new-feature`)
117 5. Create new Pull Request
Something went wrong with that request. Please try again.