mhartl-find_mass_assignment 1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/MIT-LICENSE +20 -0
- data/README.markdown +31 -0
- data/Rakefile +22 -0
- data/find_mass_assignment.gemspec +12 -0
- data/lib/find_mass_assignment.rb +90 -0
- data/tasks/find_mass_assignment_tasks.rake +5 -0
- metadata +58 -0
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2008 [name of plugin creator]
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.markdown
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# FindMassAssignment
|
2
|
+
|
3
|
+
## A Rails plugin to find likely mass assignment vulnerabilities
|
4
|
+
|
5
|
+
The <tt>find\_mass\_assignment</tt> Rake task defined by the plugin finds likely mass assignment problems in Rails projects.
|
6
|
+
|
7
|
+
The method is to scan the controllers for likely mass assignment, and then find the corresponding models that *don't* have <tt>attr\_accessible</tt> defined. Any time that happens, it's a potential problem.
|
8
|
+
|
9
|
+
Install this plugin as follows:
|
10
|
+
|
11
|
+
$ script/plugin install git://github.com/mhartl/find_mass_assignment.git
|
12
|
+
|
13
|
+
|
14
|
+
# Example
|
15
|
+
|
16
|
+
Suppose line 17 of the Users controller is
|
17
|
+
|
18
|
+
@user = User.new(params[:user])
|
19
|
+
|
20
|
+
but the User model *doesn't* define <tt>attr_accessible</tt>. Then we get the output
|
21
|
+
|
22
|
+
$ rake find_mass_assignment
|
23
|
+
|
24
|
+
/path/to/app/controllers/users_controller.rb
|
25
|
+
17 @user = User.new(params[:user])
|
26
|
+
|
27
|
+
This indicates that the User model has a likely mass assignment vulnerability.
|
28
|
+
|
29
|
+
# Copyright
|
30
|
+
|
31
|
+
Copyright (c) 2008 Michael Hartl, released under the MIT license
|
data/Rakefile
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'rake/rdoctask'
|
4
|
+
|
5
|
+
desc 'Default: run unit tests.'
|
6
|
+
task :default => :test
|
7
|
+
|
8
|
+
desc 'Test the find_mass_assignment plugin.'
|
9
|
+
Rake::TestTask.new(:test) do |t|
|
10
|
+
t.libs << 'lib'
|
11
|
+
t.pattern = 'test/**/*_test.rb'
|
12
|
+
t.verbose = true
|
13
|
+
end
|
14
|
+
|
15
|
+
desc 'Generate documentation for the find_mass_assignment plugin.'
|
16
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
17
|
+
rdoc.rdoc_dir = 'rdoc'
|
18
|
+
rdoc.title = 'FindMassAssignment'
|
19
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
20
|
+
rdoc.rdoc_files.include('README')
|
21
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
22
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
spec = Gem::Specification.new do |s|
|
2
|
+
s.name = "find_mass_assignment"
|
3
|
+
s.version = "1.0"
|
4
|
+
s.author = "Michael Hartl"
|
5
|
+
s.email = "michael@insoshi.com"
|
6
|
+
s.homepage = "http://insoshi.com/"
|
7
|
+
s.summary = "Find likely mass assignment vulnerabilities"
|
8
|
+
s.files = ["README.markdown", "Rakefile", "find_mass_assignment.gemspec",
|
9
|
+
"lib/find_mass_assignment.rb",
|
10
|
+
"tasks/find_mass_assignment_tasks.rake",
|
11
|
+
"MIT-LICENSE"]
|
12
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'active_support'
|
2
|
+
|
3
|
+
# Find potential mass assignment problems.
|
4
|
+
# The method is to scan the controllers for likely mass assignment,
|
5
|
+
# and then find the corresponding models that *don't* have
|
6
|
+
# attr_accessible defined. Any time that happens, it's a potential problem.
|
7
|
+
|
8
|
+
class String
|
9
|
+
|
10
|
+
@@cache = {}
|
11
|
+
|
12
|
+
# A regex to match likely cases of mass assignment
|
13
|
+
# Examples of matching strings:
|
14
|
+
# "Foo.new( { :bar => 'baz' } )"
|
15
|
+
# "Foo.update_attributes!(params[:foo])"
|
16
|
+
MASS_ASSIGNMENT = /(\w+)\.(new|create|update_attributes|build)!*\(/
|
17
|
+
|
18
|
+
# Return the strings that represent potential mass assignment problems.
|
19
|
+
# The MASS_ASSIGNMENT regex returns, e.g., ['Post', 'new'] because of
|
20
|
+
# the grouping methods; we want the first of the two for each match.
|
21
|
+
# For example, the call to scan might return
|
22
|
+
# [['Post', 'new'], ['Person', 'create']]
|
23
|
+
# We then select the first element of each subarray, returning
|
24
|
+
# ['Post', 'Person']
|
25
|
+
def mass_assignment_models
|
26
|
+
scan(MASS_ASSIGNMENT).map { |problem| problem.first.classify }
|
27
|
+
end
|
28
|
+
|
29
|
+
# Return true if the string has potential mass assignment code.
|
30
|
+
def mass_assignment?
|
31
|
+
self =~ MASS_ASSIGNMENT
|
32
|
+
end
|
33
|
+
|
34
|
+
# Return true if the model defines attr_accessible.
|
35
|
+
# Note that 'attr_accessible' must be preceded by nothing other than
|
36
|
+
# whitespace; this catches cases where attr_accessible is commented out.
|
37
|
+
def attr_accessible?
|
38
|
+
model = "#{RAILS_ROOT}/app/models/#{self.classify}.rb"
|
39
|
+
if File.exist?(model)
|
40
|
+
return @@cache[model] unless @@cache[model].nil?
|
41
|
+
@@cache[model] = File.open(model).read =~ /^\s*attr_accessible/
|
42
|
+
else
|
43
|
+
# If the model file doesn't exist, ignore it by returning true.
|
44
|
+
# This way, problem? is false and the item won't be flagged.
|
45
|
+
true
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# Returnt true if a model does not define attr_accessible.
|
50
|
+
def problem?
|
51
|
+
not attr_accessible?
|
52
|
+
end
|
53
|
+
|
54
|
+
# Return true if a line has a problem model (no attr_accessible).
|
55
|
+
def problem_model?
|
56
|
+
mass_assignment_models.find { |model| model.problem? }
|
57
|
+
end
|
58
|
+
|
59
|
+
# Return true if a controller string has a (likely) mass assignment problem.
|
60
|
+
# This is true if at least one of the controller's lines
|
61
|
+
# (1) Has a likely mass assignment
|
62
|
+
# (2) The corresponding model doesn't define attr_accessible
|
63
|
+
def mass_assignment_problem?
|
64
|
+
File.open(self).find { |l| l.mass_assignment? and l.problem_model? }
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
module MassAssignment
|
69
|
+
|
70
|
+
def self.print_mass_assignment_problems(controller)
|
71
|
+
lines = File.open(controller)
|
72
|
+
lines.each_with_index do |line, number|
|
73
|
+
if line.mass_assignment? and line.problem_model?
|
74
|
+
puts " #{number} #{line}"
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def self.find
|
80
|
+
controllers = Dir.glob("#{RAILS_ROOT}/app/controllers/*_controller.rb")
|
81
|
+
controllers.each do |controller|
|
82
|
+
if controller.mass_assignment_problem?
|
83
|
+
puts "\n#{controller}"
|
84
|
+
print_mass_assignment_problems(controller)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
|
metadata
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mhartl-find_mass_assignment
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: "1.0"
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Michael Hartl
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-10-27 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description:
|
17
|
+
email: michael@insoshi.com
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files: []
|
23
|
+
|
24
|
+
files:
|
25
|
+
- README.markdown
|
26
|
+
- Rakefile
|
27
|
+
- find_mass_assignment.gemspec
|
28
|
+
- lib/find_mass_assignment.rb
|
29
|
+
- tasks/find_mass_assignment_tasks.rake
|
30
|
+
- MIT-LICENSE
|
31
|
+
has_rdoc: false
|
32
|
+
homepage: http://insoshi.com/
|
33
|
+
post_install_message:
|
34
|
+
rdoc_options: []
|
35
|
+
|
36
|
+
require_paths:
|
37
|
+
- lib
|
38
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
39
|
+
requirements:
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: "0"
|
43
|
+
version:
|
44
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ">="
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: "0"
|
49
|
+
version:
|
50
|
+
requirements: []
|
51
|
+
|
52
|
+
rubyforge_project:
|
53
|
+
rubygems_version: 1.2.0
|
54
|
+
signing_key:
|
55
|
+
specification_version: 2
|
56
|
+
summary: Find likely mass assignment vulnerabilities
|
57
|
+
test_files: []
|
58
|
+
|