提交 22b0c47c 编写于 作者: J Justin

Merge pull request #502 from presidentbeef/add_check_for_cve_2014_0130

Add check for CVE-2014-0130
...@@ -9,33 +9,78 @@ class Brakeman::CheckDefaultRoutes < Brakeman::BaseCheck ...@@ -9,33 +9,78 @@ class Brakeman::CheckDefaultRoutes < Brakeman::BaseCheck
#Checks for :allow_all_actions globally and for individual routes #Checks for :allow_all_actions globally and for individual routes
#if it is not enabled globally. #if it is not enabled globally.
def run_check def run_check
if tracker.routes[:allow_all_actions] check_for_default_routes
check_for_action_globs
check_for_cve_2014_0130
end
def check_for_default_routes
if allow_all_actions?
#Default routes are enabled globally #Default routes are enabled globally
warn :warning_type => "Default Routes", warn :warning_type => "Default Routes",
:warning_code => :all_default_routes, :warning_code => :all_default_routes,
:message => "All public methods in controllers are available as actions in routes.rb", :message => "All public methods in controllers are available as actions in routes.rb",
:line => tracker.routes[:allow_all_actions].line, :line => tracker.routes[:allow_all_actions].line,
:confidence => CONFIDENCE[:high], :confidence => CONFIDENCE[:high],
:file => "#{tracker.options[:app_path]}/config/routes.rb" :file => "#{tracker.options[:app_path]}/config/routes.rb"
else #Report each controller separately end
Brakeman.debug "Checking each controller for default routes" end
tracker.routes.each do |name, actions| def check_for_action_globs
if actions.is_a? Array and actions[0] == :allow_all_actions return if allow_all_actions?
if actions[1].is_a? Hash and actions[1][:allow_verb] Brakeman.debug "Checking each controller for default routes"
verb = actions[1][:allow_verb]
else tracker.routes.each do |name, actions|
verb = "any" if actions.is_a? Array and actions[0] == :allow_all_actions
end @actions_allowed_on_controller = true
warn :controller => name, if actions[1].is_a? Hash and actions[1][:allow_verb]
:warning_type => "Default Routes", verb = actions[1][:allow_verb]
:warning_code => :controller_default_routes, else
:message => "Any public method in #{name} can be used as an action for #{verb} requests.", verb = "any"
:line => actions[2],
:confidence => CONFIDENCE[:med],
:file => "#{tracker.options[:app_path]}/config/routes.rb"
end end
warn :controller => name,
:warning_type => "Default Routes",
:warning_code => :controller_default_routes,
:message => "Any public method in #{name} can be used as an action for #{verb} requests.",
:line => actions[2],
:confidence => CONFIDENCE[:med],
:file => "#{tracker.options[:app_path]}/config/routes.rb"
end end
end end
end end
def check_for_cve_2014_0130
case
when lts_version?("2.3.18.9")
#TODO: Should support LTS 3.0.20 too
return
when version_between?("2.0.0", "2.3.18")
upgrade = "3.2.18"
when version_between?("3.0.0", "3.2.17")
upgrade = "3.2.18"
when version_between?("4.0.0", "4.0.4")
upgrade = "4.0.5"
when version_between?("4.1.0", "4.1.0")
upgrade = "4.1.1"
else
return
end
if allow_all_actions? or @actions_allowed_on_controller
confidence = CONFIDENCE[:high]
else
confidence = CONFIDENCE[:med]
end
warn :warning_type => "Remote Code Execution",
:warning_code => :CVE_2014_0130,
:message => "Rails #{tracker.config[:rails_version]} with globbing routes is vulnerable to directory traversal and remote code execution. Patch or upgrade to #{upgrade}",
:confidence => confidence,
:file => "#{tracker.options[:app_path]}/config/routes.rb",
:link => "http://matasano.com/research/AnatomyOfRailsVuln-CVE-2014-0130.pdf"
end
def allow_all_actions?
tracker.routes[:allow_all_actions]
end
end end
...@@ -76,7 +76,8 @@ module Brakeman::WarningCodes ...@@ -76,7 +76,8 @@ module Brakeman::WarningCodes
:CVE_2014_0081 => 73, :CVE_2014_0081 => 73,
:CVE_2014_0081_call => 74, :CVE_2014_0081_call => 74,
:CVE_2014_0082 => 75, :CVE_2014_0082 => 75,
:regex_dos => 76 :regex_dos => 76,
:CVE_2014_0130 => 77,
} }
def self.code name def self.code name
......
...@@ -3,9 +3,9 @@ class TestMarkdownOutput < Test::Unit::TestCase ...@@ -3,9 +3,9 @@ class TestMarkdownOutput < Test::Unit::TestCase
def test_reported_warnings def test_reported_warnings
if Brakeman::Scanner::RUBY_1_9 if Brakeman::Scanner::RUBY_1_9
assert_equal 167, Report.lines.to_a.count
else
assert_equal 168, Report.lines.to_a.count assert_equal 168, Report.lines.to_a.count
else
assert_equal 169, Report.lines.to_a.count
end end
end end
end end
...@@ -11,7 +11,7 @@ class OnlyFilesOptionTests < Test::Unit::TestCase ...@@ -11,7 +11,7 @@ class OnlyFilesOptionTests < Test::Unit::TestCase
:controller => 8, :controller => 8,
:model => 0, :model => 0,
:template => 1, :template => 1,
:generic => 8 } :generic => 9 }
if RUBY_PLATFORM == 'java' if RUBY_PLATFORM == 'java'
@expected[:generic] += 1 @expected[:generic] += 1
...@@ -97,4 +97,16 @@ class OnlyFilesOptionTests < Test::Unit::TestCase ...@@ -97,4 +97,16 @@ class OnlyFilesOptionTests < Test::Unit::TestCase
:relative_path => "Gemfile", :relative_path => "Gemfile",
:user_input => nil :user_input => nil
end end
def test_remote_code_execution_CVE_2014_0130
assert_warning :type => :warning,
:warning_code => 77,
:fingerprint => "93393e44a0232d348e4db62276b18321b4cbc9051b702d43ba2fd3287175283c",
:warning_type => "Remote Code Execution",
:line => nil,
:message => /^Rails\ 3\.2\.9\.rc2\ with\ globbing\ routes\ is\ /,
:confidence => 0,
:relative_path => "config/routes.rb",
:user_input => nil
end
end end
...@@ -17,13 +17,13 @@ class Rails2Tests < Test::Unit::TestCase ...@@ -17,13 +17,13 @@ class Rails2Tests < Test::Unit::TestCase
:controller => 1, :controller => 1,
:model => 3, :model => 3,
:template => 47, :template => 47,
:generic => 54 } :generic => 55 }
else else
@expected ||= { @expected ||= {
:controller => 1, :controller => 1,
:model => 3, :model => 3,
:template => 47, :template => 47,
:generic => 55 } :generic => 56 }
end end
end end
...@@ -1020,6 +1020,18 @@ class Rails2Tests < Test::Unit::TestCase ...@@ -1020,6 +1020,18 @@ class Rails2Tests < Test::Unit::TestCase
:user_input => nil :user_input => nil
end end
def test_remote_code_execution_CVE_2014_0130
assert_warning :type => :warning,
:warning_code => 77,
:fingerprint => "93393e44a0232d348e4db62276b18321b4cbc9051b702d43ba2fd3287175283c",
:warning_type => "Remote Code Execution",
:line => nil,
:message => /^Rails\ 2\.3\.11\ with\ globbing\ routes\ is\ vul/,
:confidence => 0,
:relative_path => "config/routes.rb",
:user_input => nil
end
def test_to_json def test_to_json
assert_warning :type => :template, assert_warning :type => :template,
:warning_type => "Cross Site Scripting", :warning_type => "Cross Site Scripting",
...@@ -1373,13 +1385,13 @@ class Rails2WithOptionsTests < Test::Unit::TestCase ...@@ -1373,13 +1385,13 @@ class Rails2WithOptionsTests < Test::Unit::TestCase
:controller => 1, :controller => 1,
:model => 4, :model => 4,
:template => 47, :template => 47,
:generic => 54 } :generic => 55 }
else else
@expected ||= { @expected ||= {
:controller => 1, :controller => 1,
:model => 4, :model => 4,
:template => 47, :template => 47,
:generic => 55 } :generic => 56 }
end end
end end
......
...@@ -16,7 +16,7 @@ class Rails3Tests < Test::Unit::TestCase ...@@ -16,7 +16,7 @@ class Rails3Tests < Test::Unit::TestCase
:controller => 1, :controller => 1,
:model => 8, :model => 8,
:template => 38, :template => 38,
:generic => 71 :generic => 72
} }
if RUBY_PLATFORM == 'java' if RUBY_PLATFORM == 'java'
...@@ -1185,6 +1185,18 @@ class Rails3Tests < Test::Unit::TestCase ...@@ -1185,6 +1185,18 @@ class Rails3Tests < Test::Unit::TestCase
:user_input => nil :user_input => nil
end end
def test_remote_code_execution_CVE_2014_0130
assert_warning :type => :warning,
:warning_code => 77,
:fingerprint => "93393e44a0232d348e4db62276b18321b4cbc9051b702d43ba2fd3287175283c",
:warning_type => "Remote Code Execution",
:line => nil,
:message => /^Rails\ 3\.0\.3\ with\ globbing\ routes\ is\ vuln/,
:confidence => 0,
:relative_path => "config/routes.rb",
:user_input => nil
end
def test_http_only_session_setting def test_http_only_session_setting
assert_warning :type => :warning, assert_warning :type => :warning,
:warning_type => "Session Setting", :warning_type => "Session Setting",
......
...@@ -15,7 +15,7 @@ class Rails31Tests < Test::Unit::TestCase ...@@ -15,7 +15,7 @@ class Rails31Tests < Test::Unit::TestCase
:model => 3, :model => 3,
:template => 23, :template => 23,
:controller => 4, :controller => 4,
:generic => 78 } :generic => 79 }
end end
def test_without_protection def test_without_protection
...@@ -844,6 +844,18 @@ class Rails31Tests < Test::Unit::TestCase ...@@ -844,6 +844,18 @@ class Rails31Tests < Test::Unit::TestCase
:user_input => nil :user_input => nil
end end
def test_remote_code_execution_CVE_2014_0130
assert_warning :type => :warning,
:warning_code => 77,
:fingerprint => "e833fd152ab95bf7481aada185323d97cd04c3e2322b90f3698632f4c4c04441",
:warning_type => "Remote Code Execution",
:line => nil,
:message => /^Rails\ 3\.1\.0\ with\ globbing\ routes\ is\ vuln/,
:confidence => 1,
:relative_path => "config/routes.rb",
:user_input => nil
end
def test_to_json_with_overwritten_config def test_to_json_with_overwritten_config
assert_warning :type => :template, assert_warning :type => :template,
:warning_type => "Cross Site Scripting", :warning_type => "Cross Site Scripting",
......
...@@ -16,7 +16,7 @@ class Rails32Tests < Test::Unit::TestCase ...@@ -16,7 +16,7 @@ class Rails32Tests < Test::Unit::TestCase
:controller => 8, :controller => 8,
:model => 5, :model => 5,
:template => 11, :template => 11,
:generic => 16 } :generic => 17 }
if RUBY_PLATFORM == 'java' if RUBY_PLATFORM == 'java'
@expected[:generic] += 1 @expected[:generic] += 1
...@@ -140,6 +140,18 @@ class Rails32Tests < Test::Unit::TestCase ...@@ -140,6 +140,18 @@ class Rails32Tests < Test::Unit::TestCase
:user_input => nil :user_input => nil
end end
def test_remote_code_execution_CVE_2014_0130
assert_warning :type => :warning,
:warning_code => 77,
:fingerprint => "93393e44a0232d348e4db62276b18321b4cbc9051b702d43ba2fd3287175283c",
:warning_type => "Remote Code Execution",
:line => nil,
:message => /^Rails\ 3\.2\.9\.rc2\ with\ globbing\ routes\ is\ /,
:confidence => 0,
:relative_path => "config/routes.rb",
:user_input => nil
end
def test_redirect_1 def test_redirect_1
assert_warning :type => :warning, assert_warning :type => :warning,
:warning_type => "Redirect", :warning_type => "Redirect",
......
...@@ -15,7 +15,7 @@ class Rails4Tests < Test::Unit::TestCase ...@@ -15,7 +15,7 @@ class Rails4Tests < Test::Unit::TestCase
:controller => 0, :controller => 0,
:model => 1, :model => 1,
:template => 2, :template => 2,
:generic => 25 :generic => 26
} }
end end
...@@ -428,6 +428,18 @@ class Rails4Tests < Test::Unit::TestCase ...@@ -428,6 +428,18 @@ class Rails4Tests < Test::Unit::TestCase
:user_input => nil :user_input => nil
end end
def test_remote_code_execution_CVE_2014_0130
assert_warning :type => :warning,
:warning_code => 77,
:fingerprint => "e833fd152ab95bf7481aada185323d97cd04c3e2322b90f3698632f4c4c04441",
:warning_type => "Remote Code Execution",
:line => nil,
:message => /^Rails\ 4\.0\.0\ with\ globbing\ routes\ is\ vuln/,
:confidence => 1,
:relative_path => "config/routes.rb",
:user_input => nil
end
def test_mass_assignment_with_permit! def test_mass_assignment_with_permit!
assert_warning :type => :warning, assert_warning :type => :warning,
:warning_code => 70, :warning_code => 70,
......
...@@ -11,7 +11,7 @@ class Rails4WithEnginesTests < Test::Unit::TestCase ...@@ -11,7 +11,7 @@ class Rails4WithEnginesTests < Test::Unit::TestCase
:controller => 0, :controller => 0,
:model => 5, :model => 5,
:template => 11, :template => 11,
:generic => 6 } :generic => 7 }
end end
def report def report
...@@ -74,6 +74,18 @@ class Rails4WithEnginesTests < Test::Unit::TestCase ...@@ -74,6 +74,18 @@ class Rails4WithEnginesTests < Test::Unit::TestCase
:user_input => nil :user_input => nil
end end
def test_remote_code_execution_CVE_2014_0130
assert_warning :type => :warning,
:warning_code => 77,
:fingerprint => "e833fd152ab95bf7481aada185323d97cd04c3e2322b90f3698632f4c4c04441",
:warning_type => "Remote Code Execution",
:line => nil,
:message => /^Rails\ 4\.0\.0\ with\ globbing\ routes\ is\ vuln/,
:confidence => 1,
:relative_path => "config/routes.rb",
:user_input => nil
end
def test_redirect_1 def test_redirect_1
assert_warning :type => :generic, assert_warning :type => :generic,
:warning_code => 18, :warning_code => 18,
......
...@@ -47,4 +47,19 @@ class RailsLTSTests < Test::Unit::TestCase ...@@ -47,4 +47,19 @@ class RailsLTSTests < Test::Unit::TestCase
assert_new 0 assert_new 0
assert_fixed 4 # 2 + CVE-2012-1099 + CVE_2014_0081 assert_fixed 4 # 2 + CVE-2012-1099 + CVE_2014_0081
end end
def test_rails_lts_CVE_2014_0130
gemfile = "Gemfile.lock"
before_rescan_of gemfile, "rails_with_xss_plugin" do
append gemfile, "railslts-version (2.3.18.9)"
end
#@original is actually modified
assert @original.config[:gems][:"railslts-version"], "2.3.18.9"
assert_reindex :none
assert_changes
assert_new 0
assert_fixed 5
end
end end
...@@ -11,7 +11,7 @@ class RailsWithXssPluginTests < Test::Unit::TestCase ...@@ -11,7 +11,7 @@ class RailsWithXssPluginTests < Test::Unit::TestCase
:controller => 1, :controller => 1,
:model => 3, :model => 3,
:template => 4, :template => 4,
:generic => 23 } :generic => 24 }
end end
def report def report
...@@ -404,4 +404,16 @@ class RailsWithXssPluginTests < Test::Unit::TestCase ...@@ -404,4 +404,16 @@ class RailsWithXssPluginTests < Test::Unit::TestCase
:relative_path => "Gemfile", :relative_path => "Gemfile",
:user_input => nil :user_input => nil
end end
def test_remote_code_execution_CVE_2014_0130
assert_warning :type => :warning,
:warning_code => 77,
:fingerprint => "93393e44a0232d348e4db62276b18321b4cbc9051b702d43ba2fd3287175283c",
:warning_type => "Remote Code Execution",
:line => nil,
:message => /^Rails\ 2\.3\.14\ with\ globbing\ routes\ is\ vul/,
:confidence => 0,
:relative_path => "config/routes.rb",
:user_input => nil
end
end end
...@@ -3,9 +3,9 @@ class TestTabsOutput < Test::Unit::TestCase ...@@ -3,9 +3,9 @@ class TestTabsOutput < Test::Unit::TestCase
def test_reported_warnings def test_reported_warnings
if Brakeman::Scanner::RUBY_1_9 if Brakeman::Scanner::RUBY_1_9
assert_equal 106, Report.lines.to_a.count
else
assert_equal 107, Report.lines.to_a.count assert_equal 107, Report.lines.to_a.count
else
assert_equal 108, Report.lines.to_a.count
end end
end end
end end
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册