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 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
+
@@ -0,0 +1,5 @@
1
+ desc "Find potential mass assignment vulnerabilities"
2
+ task :find_mass_assignment do
3
+ require File.join(File.dirname(__FILE__), "../lib/find_mass_assignment.rb")
4
+ MassAssignment.find
5
+ end
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
+