A Rails Security Flaw – Destroying The Audit Trail
Recently Rails 2.3 was released, with a number of new features.
One of these was the ability to set the created_at/updated_at time-stamped columns manually. Now, why anybody would want to do this currently escapes me – but that aside, those columns are now attr_accessible.
This means that anybody can set them by manually editing the forms on your site, so you can’t trust them to be correct. Your audit trail is no longer valid.
Now, you may argue that it’s a simple matter of setting those columns to attr_protected in the models. However, how many people do you think will remember to do that? Especially when you’re upgrading pre 2.3 apps.
I’ve talked to the Rails core about this issue, but they’re reluctant to make created_at/updated_at attr_protected by default due to api compatibility problems.
In any case, you can fix it yourself by putting the following script in config/initializers:
See also:
- No similar posts
About the author
-
Comments (6)
-
Responses (0)
Like you, I find it incomprehensible that anyone would actually consider it a feature to be able to easily update created_at/updated_at fields. The whole point of them is that they audit this stuff automatically. It should be hard to change them.
Even if we can’t persuade the core team to back out this boneheaded misfeature, at least we can patch it ourselves. Good work.
Paul Battley
April 16, 2009
at 11:10 am
Definitely opens up a audit problem. I’m starting to find I like Datamapper more and more.
Julian Burgess
April 16, 2009
at 2:20 pm
Hi,
Thanks for this. I’ve got an app that will allow me to export a given customer and all associated records from our live db and import them into our dev db via xml and hit major issues recreating records from xml due to protected attrs but setting the default to an empty array did the trick and means i don’t have to whitelist every attribute in 50 models..
Cheers
Mark Duncan
April 17, 2009
at 10:40 am
Hey Alex,
I did a little digging and as far as I can see you’ve always been able to set created_at/on. It’s only the updated_at/on that have been ‘read-only’. This[1] is the commit to rails that provides the ability to set both created_* and updated_*. I’ve written up how I came to this conclusion[2] and welcome feedback.
Cheers,
Chris
[1] http://github.com/rails/rails/commit/63aac338332a06d3c9e28dde7954679703ec7620
[2] http://chrisroos.co.uk/blog/2009-04-19-rails-2-3-and-the-ability-to-update-created_at-created_on-updated_at-and-updated_on-timestamps
Chris Roos
April 19, 2009
at 2:17 pm
Thanks for the tip. It seems like this change has the potential to cause plenty of problems. I’m including your fix in all my projects.
Justin Ball
April 30, 2009
at 3:15 am
How do I include the script in config/initializers. Do i just copy and paste the script in a self-named.rb file and just place it there or I append it to a particular file.
I am using Rails 2.3.2, and I have the following file in my config/initializers folder: backtrace_silencers, inflections, mime_types, new_rails_defaults, and session_stores. All of them are *.rb files. Please enlighten me.
ChixoRiko
August 11, 2009
at 1:38 pm