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:

6 comments
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.
Definitely opens up a audit problem. I’m starting to find I like Datamapper more and more.
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
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’. This1 is the commit to rails that provides the ability to set both created_* and updated_*. I’ve written up how I came to this conclusion2 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
http://github.com/rails/rails/commit/63aac338332a06d3c9e28dde7954679703ec7620
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
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.
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.