Skip to content

Commit

Permalink
Added unsafe_build_and_create
Browse files Browse the repository at this point in the history
  • Loading branch information
mhartl committed Apr 27, 2009
1 parent f5fcdec commit 146da1c
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 3 deletions.
21 changes: 19 additions & 2 deletions README.markdown
@@ -1,4 +1,4 @@
# FindMassAssignment
# Find Mass Assignment

## A Rails plugin to find likely mass assignment vulnerabilities

Expand All @@ -12,7 +12,7 @@ Install this plugin as follows:

For more information, see my [brief review of mass assignment](http://blog.insoshi.com/2008/09/21/mass-assignment-in-rails-applications/) and my discussion of [how to fix mass assignment vulnerabilities in Rails](http://blog.insoshi.com/2008/09/21/finding-and-fixing-mass-assignment-problems-in-rails-applications/).

# Example
## Example

Suppose line 17 of the Users controller is

Expand All @@ -27,6 +27,23 @@ but the User model *doesn't* define <tt>attr_accessible</tt>. Then we get the o

This indicates that the User model has a likely mass assignment vulnerability.

# Unsafe attribute updates

It is often useful to override <tt>attr\_accessible</tt>, especially at the console and in tests, so the plugin also adds an assortment of helper methods to Active Record:

* unsafe\_new
* unsafe\_build
* unsafe\_create/unsafe\_create!
* unsafe\_update\_attributes/unsafe\_update\_attributes!

These work just like their safe counterparts, except they bypass attr\_accessible. For example,

<pre>
Person.unsafe_new(:admin => true)
</pre>

works even if <tt>admin</tt> isn't attr\_accessible.

# Copyright

Copyright (c) 2008 Michael Hartl, released under the MIT license
2 changes: 1 addition & 1 deletion init.rb
@@ -1 +1 @@
# Include hook code here
require File.join(File.dirname(__FILE__), "lib", "unsafe_build_and_create")
63 changes: 63 additions & 0 deletions lib/unsafe_build_and_create.rb
@@ -0,0 +1,63 @@
class ActiveRecord::Base

# Build and create records unsafely, bypassing attr_accessible.
# These methods are especially useful in tests and in the console.
# Inspired in part by http://pastie.textmate.org/104042

class << self

# Make a new record unsafely.
# This replaces new/build. For example,
# User.unsafe_new(:admin => true)
# works even if 'admin' isn't attr_accessible.
def unsafe_new(attrs = {})
record = new
record.unsafe_attributes = attrs
record
end

# Allow an unsafe build.
# For example,
# @blog.posts.unsafe_build(:published => true)
# works even if 'published' isn't attr_accessible.
alias_method :unsafe_build, :unsafe_new

# Create a record unsafely.
# For example,
# User.unsafe_create(:admin => true)
# works even if 'admin' isn't attr_accessible.
def unsafe_create(attrs)
record = unsafe_build(attrs)
record.save
record
end

# Same as unsafe_create, but raises an exception on error
# The analogy to create/create! is exact.
def unsafe_create!(attrs)
unsafe_build(attrs).save!
end
end

# Update attributes unsafely.
# For example,
# @user.unsafe_update_attributes(:admin => true)
# works even if 'admin' isn't attr_accessible.
def unsafe_update_attributes(attrs)
self.unsafe_attributes = attrs
save
end

# Same as unsafe_update_attributes, but raises an exception on error
def unsafe_update_attributes!(attrs)
self.unsafe_attributes = attrs
save!
end

# Set attributes unsafely, bypassing attr_accessible.
def unsafe_attributes=(attrs)
attrs.each do |k, v|
send("#{k}=", v)
end
end
end

0 comments on commit 146da1c

Please sign in to comment.