I am a Java programmer mostly, and it's actually amazing that we don't have to worry about a lot of security concerns that php or even rails developers have to worry about. We have to worry about them, but I think our job is actually a lot easier. You just use Java (already bi开发者_如何学Cg bonus points there) and use Spring with Spring security... and you're basically done. Java and servlets are actually really good in this respect.
Now that I'm working in Rails, I think the biggest security concerns that I am the most scared of are parameters - both in the ones that are coming from the controllers (since they dynamic hashes, unlike in SpringMVC) and having to include more hidden values in forms.
But that got me thinking - you really have to be careful what you accept when you create new models or even update models. If you just blindly pass in parameters to your models, bad things can happen. In fact, things like the user role and stuff could be changed if you're not too careful.
It's almost like I want to write the setter code by hand to make sure it's not overwriting something that it shouldn't. And even if there's a framework mechanism to handle this... I would still want to test every risky model attribute just to be extra sure that it won't get overwritten on a create and on an update.
As much as Java gets a bad rep about productivity, it feels like it handles this stuff a lot better.
Anyway, my question is - what is the best resource/tips/advice for dealing with common security pitfalls/concerns/gotchas using rails - especially geared towards a Java/Spring developer who got used to working in a more stateful environment.
Even better, what would be a good checklist to go through every once in awhile?
And last, what tests would you recommend to make sure things are solid?
At least for your concern about assigning data to your model objects without proper checking, look into the attr_accessible
declaration; it allows only specified attributes to be assigned via the bulk assignment:
user = User.new(params[:user])
user.approved = params[:user][:approved]
user.role = params[:user][:role]
You might find the entire 27th chapter of the Ruby on Rails 3rd edition book useful. (I haven't updated my 4th Edition book yet, not sure which chapter to recommend from the newer book. :)
I don't use ActiveRecord (I use DataMapper), but as a rule, I never do mass-assignment and I always expressly pass only the attributes I want to change. Rails 3 defaults to escaping all content in your views, unless you expressly output that data raw into into the .erb.
Also, it really bugs me that ActiveRecord doesn't help you out very much if you need to drop down to using SQL for something. You have to escape input yourself, which can expose you to the risk of human error allowing arbitrary SQL to be executed in your queries. DataMapper's underlying DataObjects connection supports prepared statements out of the box and in fact, it would actually require more work to avoid using them.
Rails 3 does have CSRF protection turn on by default too. It also makes session cookies HTTP-only by default, which makes them harder to steal via JavaScript.
I actually think, aside from Rails encouraging the use of mass-assignment, you're pretty well-covered for security.
精彩评论