Chapter 6 of the Rails Tutorial, 2nd Edition is out ("Modeling users")
news.railstutorial.org
news.railstutorial.org
Another step that isn’t strictly necessary at this stage—but is a really good idea nevertheless—is to tell Rails which attributes of the model are accessible, i.e., which attributes can be modified by outside users (such as users submitting requests with web browsers).
That's not what attr_accessible means --- the real meaning of attr_accessible is subtly different in a way that leads people to make mistakes. attr_accessible means attributes can be modified automatically based on user input. End-user web browser requests can modify things that aren't in attr_accessible --- you just have to write the code to let them.
The error this leads to is overly-permissive attr_accessible statements, because people fall into a trap of believing anything that might be changed as a direct result of a user request must be in the attr_accessible statement.
i.e., which attributes can be modified automatically by outside users
The detailed meaning is then deferred to later in the tutorial, when the effects of attr_accessible are illustrated with concrete examples of mass assignment.
Instead, I've been using ActiveSupport's Hash#slice method in my controllers.
In practice, all it does it prevent you from writing `MyModel.new(:foo => bar)` and force you to write `m = MyModel.new; m.foo = bar` This is simply annoying at the repl.
Validation applies always the same (or when some predicates are satisfied), but restriction on changing fields can vary by view or via permissions (ie. only admins can flip that bit!)
The security concern comes up when you bring "params" into the picture. You don't want to ever do: MyModel.new(params) for fear of params[:is_admin] == true.
A better solution would be to automatically mark the values in `params` as tainted and throw an error on mass-assignment of tainted values. This way you can still use mass assignment for non-user-input (like in tests or at the repl). You could have an `safe_attrs` to disable tainted value filtering for some known-safe attributes.
AR::Base#update_attributes is a bad interface, from a security perspective. But it's vital to the programmer experience of Rails development. There's no good fix for the problem; AR models don't even list their attributes, let alone express a coherent strategy for defending them. I'll take the little wins I can get.
http://jonathanleighton.com/articles/2011/mass-assignment-se...
class AccountsController < ApplicationController
include ActiveModel::MassAssignmentSecurity
attr_accessible :first_name, :last_name
...
http://api.rubyonrails.org/classes/ActiveModel/MassAssignmen... explicitly states: Note that using Hash#except or Hash#slice in place of attr_accessible to sanitize attributes won’t provide sufficient protection.I agree with you, though. Model-level attr_accessible, if nothing else, is flatly annoying. I feel inconvenienced by a measure that's supposed to protect against malicious users. And I feel like the terrorists have already won. I'm no MVC guru, but it makes sense to me that the Controller would deal with what amounts to the params that are on their way to the model. Why should the model have to worry about mass assignment?
(Anyway, I just grepped our code and there is only ONE usage of slice in a controller anyway, the rest are explicit, non-mass assignments)
http://news.railstutorial.org/ruby-on-rails-tutorial-second-...
The biggest changes are:
* A full update to Rails 3.2, including coverage of the
asset pipeline
* A complete rewrite of the authentication & authorization
system, taking advantage of the new has_secure_password method
* A revised test suite using the latest techniques in
RSpec programmingPutting that behind us, I hope you're not planning to post on HN every week or two when a new chapter is released. I think your last post and perhaps one when the book is completed would be sufficient.