diff --git a/lib/brakeman/checks/check_header_dos.rb b/lib/brakeman/checks/check_header_dos.rb new file mode 100644 index 0000000000000000000000000000000000000000..fdda44a61d2005d03f174967e55da1ef83d506a7 --- /dev/null +++ b/lib/brakeman/checks/check_header_dos.rb @@ -0,0 +1,31 @@ +require 'brakeman/checks/base_check' + +class Brakeman::CheckHeaderDoS < Brakeman::BaseCheck + Brakeman::Checks.add self + + @description = "Checks for header DoS (CVE-2013-6414)" + + def run_check + if (version_between? "3.0.0", "3.2.15" or version_between? "4.0.0", "4.0.1") and not has_workaround? + message = "Rails #{tracker.config[:rails_version]} has a denial of service vulnerability (CVE-2013-6414). Upgrade to Rails version " + + if version_between? "3.0.0", "3.2.15" + message << "3.2.16" + else + message << "4.0.2" + end + + warn :warning_type => "Denial of Service", + :warning_code => :CVE_2013_6414, + :message => message, + :confidence => CONFIDENCE[:med], + :file => gemfile_or_environment, + :link_path => "https://groups.google.com/d/msg/ruby-security-ann/A-ebV4WxzKg/KNPTbX8XAQUJ" + end + end + + def has_workaround? + tracker.check_initializers(:ActiveSupport, :on_load).any? and + tracker.check_initializers(:"ActionView::LookupContext::DetailsKey", :class_eval).any? + end +end diff --git a/lib/brakeman/checks/check_i18n_xss.rb b/lib/brakeman/checks/check_i18n_xss.rb new file mode 100644 index 0000000000000000000000000000000000000000..5c31de6ed807f786bdc9d1bd9c6615baf540f446 --- /dev/null +++ b/lib/brakeman/checks/check_i18n_xss.rb @@ -0,0 +1,49 @@ +require 'brakeman/checks/base_check' + +class Brakeman::CheckI18nXSS < Brakeman::BaseCheck + Brakeman::Checks.add self + + @description = "Checks for i18n XSS (CVE-2013-4491)" + + def run_check + if (version_between? "3.0.6", "3.2.15" or version_between? "4.0.0", "4.0.1")# and not has_workaround? + message = "Rails #{tracker.config[:rails_version]} has an XSS vulnerability in i18n (CVE-2013-4491). Upgrade to Rails version " + + i18n_gem = tracker.config[:gems] && tracker.config[:gems][:i18n] + + if version_between? "3.0.6", "3.1.99" and version_before i18n_gem, "0.5.1" + message << "3.2.16 or i18n 0.5.1" + elsif version_between? "3.2.0", "4.0.1" and version_before i18n_gem, "0.6.6" + message << "4.0.2 or i18n 0.6.6" + else + return + end + + warn :warning_type => "Cross Site Scripting", + :warning_code => :CVE_2013_4491, + :message => message, + :confidence => CONFIDENCE[:med], + :file => gemfile_or_environment, + :link_path => "https://groups.google.com/d/msg/ruby-security-ann/pLrh6DUw998/bLFEyIO4k_EJ" + end + end + + def version_before gem_version, target + return true unless gem_version + gem_version.split('.').map(&:to_i).zip(target.split('.').map(&:to_i)).each do |gv, t| + if gv < t + return true + elsif gv > t + return false + end + end + + false + end + + def has_workaround? + tracker.check_initializers(:I18n, :const_defined?).any? do |match| + match.last.first_arg == s(:lit, :MissingTranslation) + end + end +end diff --git a/lib/brakeman/checks/check_number_to_currency.rb b/lib/brakeman/checks/check_number_to_currency.rb new file mode 100644 index 0000000000000000000000000000000000000000..9c90d6ab4eef8405dbaffd90c69b7f7267929a77 --- /dev/null +++ b/lib/brakeman/checks/check_number_to_currency.rb @@ -0,0 +1,55 @@ +require 'brakeman/checks/base_check' + +class Brakeman::CheckNumberToCurrency < Brakeman::BaseCheck + Brakeman::Checks.add self + + @description = "Checks for number_to_currency XSS vulnerability in certain versions" + + def run_check + if (version_between? "2.0.0", "3.2.15" or version_between? "4.0.0", "4.0.1") + check_number_to_currency_usage + + generic_warning unless @found_any + end + end + + def generic_warning + message = "Rails #{tracker.config[:rails_version]} has a vulnerability in number_to_currency (CVE-2013-6415). Upgrade to Rails version " + + if version_between? "2.3.0", "3.2.15" + message << "3.2.16" + else + message << "4.0.2" + end + + warn :warning_type => "Cross Site Scripting", + :warning_code => :CVE_2013_6415, + :message => message, + :confidence => CONFIDENCE[:med], + :file => gemfile_or_environment, + :link_path => "https://groups.google.com/d/topic/rubyonrails-security/8CpI7egxX4E/discussion" + end + + def check_number_to_currency_usage + tracker.find_call(:target => false, :method => :number_to_currency).each do |result| + arg = result[:call].second_arg + next unless arg + + if match = (has_immediate_user_input? arg or has_immediate_model? arg) + match = match.match if match.is_a? Match + @found_any = true + warn_on_number_to_currency result, match + end + end + end + + def warn_on_number_to_currency result, match + warn :result => result, + :warning_type => "Cross Site Scripting", + :warning_code => :CVE_2013_6415_call, + :message => "Currency value in number_to_currency is not safe in Rails #{@tracker.config[:rails_version]}", + :confidence => CONFIDENCE[:high], + :link_path => "https://groups.google.com/d/topic/rubyonrails-security/8CpI7egxX4E/discussion", + :user_input => match + end +end diff --git a/lib/brakeman/checks/check_simple_format.rb b/lib/brakeman/checks/check_simple_format.rb new file mode 100644 index 0000000000000000000000000000000000000000..2d302210db98969c40356321c35c6dee36457460 --- /dev/null +++ b/lib/brakeman/checks/check_simple_format.rb @@ -0,0 +1,60 @@ +require 'brakeman/checks/base_check' + +class Brakeman::CheckSimpleFormat < Brakeman::CheckCrossSiteScripting + Brakeman::Checks.add self + + @description = "Checks for simple_format XSS vulnerability (CVE-2013-6416) in certain versions" + + def run_check + if version_between? "4.0.0", "4.0.1" + @inspect_arguments = true + @ignore_methods = Set[:h, :escapeHTML] + + check_simple_format_usage + generic_warning unless @found_any + end + end + + def generic_warning + message = "Rails #{tracker.config[:rails_version]} has a vulnerability in simple_format (CVE-2013-6416). Upgrade to Rails version 4.0.2" + + warn :warning_type => "Cross Site Scripting", + :warning_code => :CVE_2013_6416, + :message => message, + :confidence => CONFIDENCE[:med], + :file => gemfile_or_environment, + :link_path => "https://groups.google.com/d/msg/ruby-security-ann/5ZI1-H5OoIM/ZNq4FoR2GnIJ" + end + + def check_simple_format_usage + tracker.find_call(:target => false, :method => :simple_format).each do |result| + @matched = false + process_call result[:call] + if @matched + warn_on_simple_format result, @matched + end + end + end + + def process_call exp + @mark = true + actually_process_call exp + exp + end + + def warn_on_simple_format result, match + return if duplicate? result + add_result result + + @found_any = true + + warn :result => result, + :warning_type => "Cross Site Scripting", + :warning_code => :CVE_2013_6416_call, + :message => "Values passed to simple_format are not safe in Rails #{@tracker.config[:rails_version]}", + :confidence => CONFIDENCE[:high], + :file => gemfile_or_environment, + :link_path => "https://groups.google.com/d/msg/ruby-security-ann/5ZI1-H5OoIM/ZNq4FoR2GnIJ", + :user_input => match.match + end +end diff --git a/lib/brakeman/checks/check_sql.rb b/lib/brakeman/checks/check_sql.rb index 81690e526315b8cf9c8cca38a0d82a73d9afcafe..b4e17c2687f38413d17d02026e69ccbbe5aaaa7b 100644 --- a/lib/brakeman/checks/check_sql.rb +++ b/lib/brakeman/checks/check_sql.rb @@ -556,6 +556,11 @@ def check_rails_versions_against_cve_issues :versions => [%w[2.0.0 2.3.15 2.3.16], %w[3.0.0 3.0.18 3.0.19], %w[3.1.0 3.1.9 3.1.10], %w[3.2.0 3.2.10 3.2.11]], :url => "https://groups.google.com/d/topic/rubyonrails-security/c7jT-EeN9eI/discussion" }, + { + :cve => "CVE-2013-6417", + :versions => [%w[2.0.0 3.2.15 3.2.16], %w[4.0.0 4.0.1 4.0.2]], + :url => "https://groups.google.com/d/msg/ruby-security-ann/niK4drpSHT4/g8JW8ZsayRkJ" + }, ].each do |cve_issue| cve_warning_for cve_issue[:versions], cve_issue[:cve], cve_issue[:url] end diff --git a/lib/brakeman/processors/gem_processor.rb b/lib/brakeman/processors/gem_processor.rb index 66625ceb03417702ec44ac9889b9247b65de7ff0..d0471219aee2b687faca1c055073750eaeb6aff5 100644 --- a/lib/brakeman/processors/gem_processor.rb +++ b/lib/brakeman/processors/gem_processor.rb @@ -15,6 +15,7 @@ class Brakeman::GemProcessor < Brakeman::BaseProcessor if gem_lock get_rails_version gem_lock get_json_version gem_lock + get_i18n_version gem_lock elsif @tracker.config[:gems][:rails] =~ /(\d+.\d+.\d+)/ @tracker.config[:rails_version] = $1 end @@ -61,4 +62,8 @@ class Brakeman::GemProcessor < Brakeman::BaseProcessor @tracker.config[:gems][:json] = get_version("json", gem_lock) @tracker.config[:gems][:json_pure] = get_version("json_pure", gem_lock) end + + def get_i18n_version gem_lock + @tracker.config[:gems][:i18n] = get_version("i18n", gem_lock) + end end diff --git a/lib/brakeman/warning_codes.rb b/lib/brakeman/warning_codes.rb index 589272b50f2d679129377b72d949b57c948d2066..f296a0892d62730259fdb508598b615555fc8cb2 100644 --- a/lib/brakeman/warning_codes.rb +++ b/lib/brakeman/warning_codes.rb @@ -62,7 +62,14 @@ module Brakeman::WarningCodes :unsafe_symbol_creation => 59, :dangerous_attr_accessible => 60, :local_request_config => 61, - :detailed_exceptions => 62 + :detailed_exceptions => 62, + :CVE_2013_4491 => 63, + :CVE_2013_6414 => 64, + :CVE_2013_6415 => 65, + :CVE_2013_6415_call => 66, + :CVE_2013_6416 => 67, + :CVE_2013_6416_call => 68, + :CVE_2013_6417 => 69, } def self.code name diff --git a/test/apps/rails3.2/config/initializers/header_dos_protection.rb b/test/apps/rails3.2/config/initializers/header_dos_protection.rb new file mode 100644 index 0000000000000000000000000000000000000000..476dbd7386482409373c0473a1b6fba90d049994 --- /dev/null +++ b/test/apps/rails3.2/config/initializers/header_dos_protection.rb @@ -0,0 +1,19 @@ +# https://groups.google.com/d/msg/ruby-security-ann/A-ebV4WxzKg/KNPTbX8XAQUJ +ActiveSupport.on_load(:action_view) do + ActionView::LookupContext::DetailsKey.class_eval do + class << self + alias :old_get :get + + def get(details) + if details[:formats] + details = details.dup + syms = Set.new Mime::SET.symbols + details[:formats] = details[:formats].select { |v| + syms.include? v + } + end + old_get details + end + end + end +end diff --git a/test/apps/rails4/app/views/users/index.html.erb b/test/apps/rails4/app/views/users/index.html.erb index 6cb6a0ce496e7f39b478eced503e962193eccf36..2e592fdf2a31ed91e6d9de1ca32fece33d59260b 100644 --- a/test/apps/rails4/app/views/users/index.html.erb +++ b/test/apps/rails4/app/views/users/index.html.erb @@ -5,3 +5,7 @@ <%= raw call_something(params).to_json %> <%= raw params[:stuff].to_json %> + +<%= number_to_currency(params[:cost], params[:currency]) %> + +<%= number_to_currency(params[:cost], h(params[:currency])) %> Should not warn diff --git a/test/apps/rails4/config/initializers/i18n.rb b/test/apps/rails4/config/initializers/i18n.rb new file mode 100644 index 0000000000000000000000000000000000000000..d9b10bbad710d5c5a26fb239ae81046ab5fb9860 --- /dev/null +++ b/test/apps/rails4/config/initializers/i18n.rb @@ -0,0 +1,20 @@ +require 'i18n' + +# Override exception handler to more carefully html-escape missing-key results. +class HtmlSafeI18nExceptionHandler + Missing = I18n.const_defined?(:MissingTranslation) ? I18n::MissingTranslation : I18n::MissingTranslationData + + def initialize(original_exception_handler) + @original_exception_handler = original_exception_handler + end + + def call(exception, locale, key, options) + if exception.is_a?(Missing) && options[:rescue_format] == :html + keys = exception.keys.map { |k| Rack::Utils.escape_html k } + key = keys.last.to_s.gsub('_', ' ').gsub(/\b('?[a-z])/) { $1.capitalize } + %(#{key}) + else + @original_exception_handler.call(exception, locale, key, options) + end + end +end diff --git a/test/apps/rails4_with_engines/engines/user_removal/app/views/users/show.html.erb b/test/apps/rails4_with_engines/engines/user_removal/app/views/users/show.html.erb index 277afae5da2eb8942d3570eba7a8a00b12c98c94..64f229bdccdba089024d98d44ea5d322cea535c9 100644 --- a/test/apps/rails4_with_engines/engines/user_removal/app/views/users/show.html.erb +++ b/test/apps/rails4_with_engines/engines/user_removal/app/views/users/show.html.erb @@ -15,6 +15,13 @@ <%= @user_data %>
++ Stuff I like: + <%= simple_format(@user.likes, :class => "likes") %> + <%= simple_format("some string", :color => params[:color]) %> + <%= simple_format("some string", :id => h(params[:color])) %> should not warn +
+ <%= link_to 'Edit', edit_user_path(@user) %> | <%= link_to 'Back', users_path %> diff --git a/test/tests/only_files_option.rb b/test/tests/only_files_option.rb index dd86f6f62d2f0932ee6a790dba12ecb87ab04221..93435b1f56b8c9678d7fd11411d336536010a0f9 100644 --- a/test/tests/only_files_option.rb +++ b/test/tests/only_files_option.rb @@ -11,8 +11,7 @@ class OnlyFilesOptionTests < Test::Unit::TestCase :controller => 0, :model => 0, :template => 1, - :generic => 4 } - + :generic => 8 } if RUBY_PLATFORM == 'java' @expected[:generic] += 1 @@ -53,4 +52,49 @@ class OnlyFilesOptionTests < Test::Unit::TestCase :file => /sanitized\.html\.erb/ end + def test_i18n_xss_CVE_2013_4491 + assert_warning :type => :warning, + :warning_code => 63, + :fingerprint => "de0e11056b9f9af7b8570d5354185cd7e17a18cc61d627555fe4adfff00fb447", + :warning_type => "Cross Site Scripting", + :message => /^Rails\ 3\.2\.9\.rc2\ has\ an\ XSS\ vulnerability/, + :confidence => 1, + :relative_path => "Gemfile" + end + + def test_denial_of_service_CVE_2013_6414 + assert_warning :type => :warning, + :warning_code => 64, + :fingerprint => "a7b00f08e4a18c09388ad017876e3f57d18040ead2816a2091f3301b6f0e5a00", + :warning_type => "Denial of Service", + :line => nil, + :message => /^Rails\ 3\.2\.9\.rc2\ has\ a\ denial\ of\ service\ /, + :confidence => 1, + :relative_path => "Gemfile", + :user_input => nil + end + + def test_number_to_currency_CVE_2013_6415 + assert_warning :type => :warning, + :warning_code => 65, + :fingerprint => "813b00b5c58567fb3f32051578b839cb25fc2d827834a30d4b213a4c126202a2", + :warning_type => "Cross Site Scripting", + :line => nil, + :message => /^Rails\ 3\.2\.9\.rc2 has\ a\ vulnerability\ in\ numbe/, + :confidence => 1, + :relative_path => "Gemfile", + :user_input => nil + end + + def test_sql_injection_CVE_2013_6417 + assert_warning :type => :warning, + :warning_code => 69, + :fingerprint => "e1b66f4311771d714a13be519693c540d7e917511a758827d9b2a0a7f958e40f", + :warning_type => "SQL Injection", + :line => nil, + :message => /^Rails\ 3\.2\.9\.rc2 contains\ a\ SQL\ injection\ vul/, + :confidence => 0, + :relative_path => "Gemfile", + :user_input => nil + end end diff --git a/test/tests/rails2.rb b/test/tests/rails2.rb index 17afc61d7f0532e3502a045cbc47ca4a75b962c2..e402caf1310bf0f7a98775c62161bbb4dc8a05c6 100644 --- a/test/tests/rails2.rb +++ b/test/tests/rails2.rb @@ -12,13 +12,13 @@ class Rails2Tests < Test::Unit::TestCase :controller => 1, :model => 3, :template => 45, - :generic => 46 } + :generic => 48 } else @expected ||= { :controller => 1, :model => 3, :template => 45, - :generic => 47 } + :generic => 49 } end end @@ -955,6 +955,28 @@ class Rails2Tests < Test::Unit::TestCase :relative_path => "config/environment.rb" end + def test_number_to_currency_CVE_2013_6415 + assert_warning :type => :warning, + :warning_code => 65, + :fingerprint => "1822c8179beeb0358b71c545bad0dd824104aed8b995fe0781c1b6e324417a91", + :warning_type => "Cross Site Scripting", + :message => /^Rails\ 2\.3\.11\ has\ a\ vulnerability\ in\ numb/, + :confidence => 1, + :relative_path => "config/environment.rb" + end + + def test_sql_injection_CVE_2013_6417 + assert_warning :type => :warning, + :warning_code => 69, + :fingerprint => "378978cda99add8404dd38db466f6ffa0b824ea8c57270d98869241a240d12a6", + :warning_type => "SQL Injection", + :line => nil, + :message => /^Rails\ 2\.3\.11\ contains\ a\ SQL\ injection\ vu/, + :confidence => 0, + :relative_path => "config/environment.rb", + :user_input => nil + end + def test_to_json assert_warning :type => :template, :warning_type => "Cross Site Scripting", @@ -1230,13 +1252,13 @@ class Rails2WithOptionsTests < Test::Unit::TestCase :controller => 1, :model => 4, :template => 45, - :generic => 46 } + :generic => 48 } else @expected ||= { :controller => 1, :model => 4, :template => 45, - :generic => 47 } + :generic => 49 } end end diff --git a/test/tests/rails3.rb b/test/tests/rails3.rb index 8b90e1c2a42c145d085f4b484d0abd0d7ee95f92..3dff4ddf5eb35d6cd5b59f81116b6dd4f1509d47 100644 --- a/test/tests/rails3.rb +++ b/test/tests/rails3.rb @@ -16,7 +16,7 @@ class Rails3Tests < Test::Unit::TestCase :controller => 1, :model => 8, :template => 38, - :generic => 63 + :generic => 66 } if RUBY_PLATFORM == 'java' @@ -1081,12 +1081,48 @@ class Rails3Tests < Test::Unit::TestCase def test_denial_of_service_CVE_2013_1854 assert_no_warning :type => :warning, + :warning_code => 55, + :fingerprint => "2746b8872d4f46676a8c490a7ac906d23f6b11c9d83b6371ff5895139ec7b43b", :warning_type => "Denial of Service", :message => /^Rails\ 3\.0\.3\ has\ a\ denial\ of\ service\ vul/, :confidence => 1, :file => /Gemfile/ end + def test_denial_of_service_CVE_2013_6414 + assert_warning :type => :warning, + :warning_code => 64, + :fingerprint => "a7b00f08e4a18c09388ad017876e3f57d18040ead2816a2091f3301b6f0e5a00", + :warning_type => "Denial of Service", + :message => /^Rails\ 3\.0\.3\ has\ a\ denial\ of\ service\ vuln/, + :confidence => 1, + :relative_path => "Gemfile" + end + + def test_number_to_currency_CVE_2013_6415 + assert_warning :type => :warning, + :warning_code => 65, + :fingerprint => "813b00b5c58567fb3f32051578b839cb25fc2d827834a30d4b213a4c126202a2", + :warning_type => "Cross Site Scripting", + :line => nil, + :message => /^Rails\ 3\.0\.3\ has\ a\ vulnerability\ in\ numbe/, + :confidence => 1, + :relative_path => "Gemfile", + :user_input => nil + end + + def test_sql_injection_CVE_2013_6417 + assert_warning :type => :warning, + :warning_code => 69, + :fingerprint => "e1b66f4311771d714a13be519693c540d7e917511a758827d9b2a0a7f958e40f", + :warning_type => "SQL Injection", + :line => nil, + :message => /^Rails\ 3\.0\.3\ contains\ a\ SQL\ injection\ vul/, + :confidence => 0, + :relative_path => "Gemfile", + :user_input => nil + end + def test_http_only_session_setting assert_warning :type => :warning, :warning_type => "Session Setting", diff --git a/test/tests/rails31.rb b/test/tests/rails31.rb index c15c03e94c80bead9437e019b24d277cde8ac289..e3aed698cf9e0d74ac60bfc12cc4cf0c48016876 100644 --- a/test/tests/rails31.rb +++ b/test/tests/rails31.rb @@ -15,7 +15,7 @@ class Rails31Tests < Test::Unit::TestCase :model => 3, :template => 23, :controller => 4, - :generic => 74 } + :generic => 77 } end def test_without_protection @@ -802,12 +802,48 @@ class Rails31Tests < Test::Unit::TestCase def test_denial_of_service_CVE_2013_1854 assert_warning :type => :warning, + :warning_code => 55, + :fingerprint => "2746b8872d4f46676a8c490a7ac906d23f6b11c9d83b6371ff5895139ec7b43b", :warning_type => "Denial of Service", :message => /^Rails\ 3\.1\.0\ has\ a\ denial\ of\ service\ vul/, :confidence => 1, :file => /Gemfile/ end + def test_denial_of_service_CVE_2013_6414 + assert_warning :type => :warning, + :warning_code => 64, + :fingerprint => "a7b00f08e4a18c09388ad017876e3f57d18040ead2816a2091f3301b6f0e5a00", + :warning_type => "Denial of Service", + :message => /^Rails\ 3\.1\.0\ has\ a\ denial\ of\ service\ vuln/, + :confidence => 1, + :relative_path => "Gemfile" + end + + def test_number_to_currency_CVE_2013_6415 + assert_warning :type => :warning, + :warning_code => 65, + :fingerprint => "813b00b5c58567fb3f32051578b839cb25fc2d827834a30d4b213a4c126202a2", + :warning_type => "Cross Site Scripting", + :line => nil, + :message => /^Rails\ 3\.1\.0\ has\ a\ vulnerability\ in\ numbe/, + :confidence => 1, + :relative_path => "Gemfile", + :user_input => nil + end + + def test_sql_injection_CVE_2013_6417 + assert_warning :type => :warning, + :warning_code => 69, + :fingerprint => "e1b66f4311771d714a13be519693c540d7e917511a758827d9b2a0a7f958e40f", + :warning_type => "SQL Injection", + :line => nil, + :message => /^Rails\ 3\.1\.0\ contains\ a\ SQL\ injection\ vul/, + :confidence => 0, + :relative_path => "Gemfile", + :user_input => nil + end + def test_to_json_with_overwritten_config assert_warning :type => :template, :warning_type => "Cross Site Scripting", diff --git a/test/tests/rails32.rb b/test/tests/rails32.rb index 5b7d7f0db7d93e4987a633aa5c1aca2e6a071997..769424eb4f29f6ef0cd169c016ad04119d9bce7a 100644 --- a/test/tests/rails32.rb +++ b/test/tests/rails32.rb @@ -11,8 +11,7 @@ class Rails32Tests < Test::Unit::TestCase :controller => 0, :model => 5, :template => 11, - :generic => 7 } - + :generic => 10 } if RUBY_PLATFORM == 'java' @expected[:generic] += 1 @@ -82,12 +81,48 @@ class Rails32Tests < Test::Unit::TestCase def test_denial_of_service_CVE_2013_1854 assert_warning :type => :warning, + :warning_code => 55, + :fingerprint => "2746b8872d4f46676a8c490a7ac906d23f6b11c9d83b6371ff5895139ec7b43b", :warning_type => "Denial of Service", :message => /^Rails\ 3\.2\.9\.rc2\ has\ a\ denial\ of\ service\ vul/, :confidence => 1, :file => /Gemfile/ end + def test_i18n_xss_CVE_2013_4491 + assert_warning :type => :warning, + :warning_code => 63, + :fingerprint => "de0e11056b9f9af7b8570d5354185cd7e17a18cc61d627555fe4adfff00fb447", + :warning_type => "Cross Site Scripting", + :message => /^Rails\ 3\.2\.9\.rc2\ has\ an\ XSS\ vulnerability/, + :confidence => 1, + :relative_path => "Gemfile" + end + + def test_number_to_currency_CVE_2013_6415 + assert_warning :type => :warning, + :warning_code => 65, + :fingerprint => "813b00b5c58567fb3f32051578b839cb25fc2d827834a30d4b213a4c126202a2", + :warning_type => "Cross Site Scripting", + :line => nil, + :message => /^Rails\ 3\.2\.9\.rc2 has\ a\ vulnerability\ in\ numbe/, + :confidence => 1, + :relative_path => "Gemfile", + :user_input => nil + end + + def test_sql_injection_CVE_2013_6417 + assert_warning :type => :warning, + :warning_code => 69, + :fingerprint => "e1b66f4311771d714a13be519693c540d7e917511a758827d9b2a0a7f958e40f", + :warning_type => "SQL Injection", + :line => nil, + :message => /^Rails\ 3\.2\.9\.rc2 contains\ a\ SQL\ injection\ vul/, + :confidence => 0, + :relative_path => "Gemfile", + :user_input => nil + end + def test_redirect_1 assert_warning :type => :warning, :warning_type => "Redirect", diff --git a/test/tests/rails4.rb b/test/tests/rails4.rb index 70207d69d30bad82b983cc9e91f92f798bac1b4d..07168f89ae5aa1236ac722c17bfad43348efd2ca 100644 --- a/test/tests/rails4.rb +++ b/test/tests/rails4.rb @@ -14,8 +14,8 @@ class Rails4Tests < Test::Unit::TestCase @expected ||= { :controller => 0, :model => 0, - :template => 0, - :generic => 5 + :template => 1, + :generic => 9 } end @@ -143,4 +143,60 @@ class Rails4Tests < Test::Unit::TestCase :relative_path => "app/controllers/friendly_controller.rb", :user_input => s(:call, s(:params), :[], s(:lit, :query)) end + + def test_i18n_xss_CVE_2013_4491 + assert_warning :type => :warning, + :warning_code => 63, + :fingerprint => "de0e11056b9f9af7b8570d5354185cd7e17a18cc61d627555fe4adfff00fb447", + :warning_type => "Cross Site Scripting", + :message => /^Rails\ 4\.0\.0\ has\ an\ XSS\ vulnerability\ in\ /, + :confidence => 1, + :relative_path => "Gemfile" + end + + def test_denial_of_service_CVE_2013_6414 + assert_warning :type => :warning, + :warning_code => 64, + :fingerprint => "a7b00f08e4a18c09388ad017876e3f57d18040ead2816a2091f3301b6f0e5a00", + :warning_type => "Denial of Service", + :message => /^Rails\ 4\.0\.0\ has\ a\ denial\ of\ service\ vuln/, + :confidence => 1, + :relative_path => "Gemfile" + end + + def test_number_to_currency_CVE_2013_6415 + assert_warning :type => :template, + :warning_code => 66, + :fingerprint => "0fb96b5f4b3a4dcdc677d126f492441e2f7b46880563a977b1246b30d3c117a0", + :warning_type => "Cross Site Scripting", + :line => 9, + :message => /^Currency\ value\ in\ number_to_currency\ is\ /, + :confidence => 0, + :relative_path => "app/views/users/index.html.erb", + :user_input => s(:call, s(:call, nil, :params), :[], s(:lit, :currency)) + end + + def test_simple_format_xss_CVE_2013_6416 + assert_warning :type => :warning, + :warning_code => 67, + :fingerprint => "e950ee1043d7f66b7f6ce99c2bf0876bd3ce8cb12818b52565b905cdb6004bad", + :warning_type => "Cross Site Scripting", + :line => nil, + :message => /^Rails\ 4\.0\.0 has\ a\ vulnerability\ in/, + :confidence => 1, + :relative_path => "Gemfile", + :user_input => nil + end + + def test_sql_injection_CVE_2013_6417 + assert_warning :type => :warning, + :warning_code => 69, + :fingerprint => "e1b66f4311771d714a13be519693c540d7e917511a758827d9b2a0a7f958e40f", + :warning_type => "SQL Injection", + :line => nil, + :message => /^Rails\ 4\.0\.0 contains\ a\ SQL\ injection\ vul/, + :confidence => 0, + :relative_path => "Gemfile", + :user_input => nil + end end diff --git a/test/tests/rails4_with_engines.rb b/test/tests/rails4_with_engines.rb index 7ddb26787c04e026575af6e8ac3bf5243093a91e..024e06471575609143d2e64fd80b4f55e8816779 100644 --- a/test/tests/rails4_with_engines.rb +++ b/test/tests/rails4_with_engines.rb @@ -10,14 +10,70 @@ class Rails4WithEnginesTests < Test::Unit::TestCase @expected ||= { :controller => 0, :model => 5, - :template => 9, - :generic => 2 } + :template => 11, + :generic => 6 } end def report Rails4WithEngines end + def test_i18n_xss_CVE_2013_4491 + assert_warning :type => :warning, + :warning_code => 63, + :fingerprint => "de0e11056b9f9af7b8570d5354185cd7e17a18cc61d627555fe4adfff00fb447", + :warning_type => "Cross Site Scripting", + :message => /^Rails\ 4\.0\.0\ has\ an\ XSS\ vulnerability\ in\ /, + :confidence => 1, + :relative_path => "Gemfile" + end + + def test_number_to_currency_CVE_2013_6415 + assert_warning :type => :warning, + :warning_code => 65, + :fingerprint => "813b00b5c58567fb3f32051578b839cb25fc2d827834a30d4b213a4c126202a2", + :warning_type => "Cross Site Scripting", + :line => nil, + :message => /^Rails\ 4\.0\.0\ has\ a\ vulnerability\ in\ numbe/, + :confidence => 1, + :relative_path => "Gemfile", + :user_input => nil + end + + def test_xss_simple_format_CVE_2013_6416 + assert_warning :type => :template, + :warning_code => 68, + :fingerprint => "0e340cc916e7487f118dae7cf3e3c1e6763c13455ec84ad56b4d3f520de8b3cb", + :warning_type => "Cross Site Scripting", + :line => 20, + :message => /^Values\ passed\ to\ simple_format\ are\ not\ s/, + :confidence => 0, + :relative_path => "Gemfile", + :user_input => s(:call, s(:call, s(:const, :User), :find, s(:call, s(:params), :[], s(:lit, :id))), :likes) + + assert_warning :type => :template, + :warning_code => 68, + :fingerprint => "33d10865a3c6c1594ecbee5511cde466b474b0e819ef979193159559becfbd4c", + :warning_type => "Cross Site Scripting", + :line => 21, + :message => /^Values\ passed\ to\ simple_format\ are\ not\ s/, + :confidence => 0, + :relative_path => "Gemfile", + :user_input => s(:call, s(:params), :[], s(:lit, :color)) + end + + def test_sql_injection_CVE_2013_6417 + assert_warning :type => :warning, + :warning_code => 69, + :fingerprint => "e1b66f4311771d714a13be519693c540d7e917511a758827d9b2a0a7f958e40f", + :warning_type => "SQL Injection", + :line => nil, + :message => /^Rails\ 4\.0\.0\ contains\ a\ SQL\ injection\ vul/, + :confidence => 0, + :relative_path => "Gemfile", + :user_input => nil + end + def test_redirect_1 assert_warning :type => :generic, :warning_code => 18, diff --git a/test/tests/rails_with_xss_plugin.rb b/test/tests/rails_with_xss_plugin.rb index dfa3e6cfe8c58bc96df2482463614a0bf9f818e9..8a487bcfe439518632615b8b068ae1d304666b5c 100644 --- a/test/tests/rails_with_xss_plugin.rb +++ b/test/tests/rails_with_xss_plugin.rb @@ -11,7 +11,7 @@ class RailsWithXssPluginTests < Test::Unit::TestCase :controller => 1, :model => 3, :template => 2, - :generic => 20 } + :generic => 22 } end def report @@ -334,4 +334,28 @@ class RailsWithXssPluginTests < Test::Unit::TestCase :confidence => 1, :file => /Gemfile/ end + + def test_sql_injection_CVE_2013_6417 + assert_warning :type => :warning, + :warning_code => 69, + :fingerprint => "e1b66f4311771d714a13be519693c540d7e917511a758827d9b2a0a7f958e40f", + :warning_type => "SQL Injection", + :line => nil, + :message => /^Rails\ 2\.3\.14\ contains\ a\ SQL\ injection\ vu/, + :confidence => 0, + :relative_path => "Gemfile", + :user_input => nil + end + + def test_number_to_currency_CVE_2013_6415 + assert_warning :type => :warning, + :warning_code => 65, + :fingerprint => "813b00b5c58567fb3f32051578b839cb25fc2d827834a30d4b213a4c126202a2", + :warning_type => "Cross Site Scripting", + :line => nil, + :message => /^Rails\ 2\.3\.14\ has\ a\ vulnerability\ in\ numb/, + :confidence => 1, + :relative_path => "Gemfile", + :user_input => nil + end end diff --git a/test/tests/tabs_output.rb b/test/tests/tabs_output.rb index dfbef704ab9960275de65f5e1a2e15c911f72faa..a74964b2f670325167e8f6af02c37fb7f3f5cf16 100644 --- a/test/tests/tabs_output.rb +++ b/test/tests/tabs_output.rb @@ -3,9 +3,9 @@ class TestTabsOutput < Test::Unit::TestCase def test_reported_warnings if Brakeman::Scanner::RUBY_1_9 - assert_equal Report.lines.to_a.count, 96 + assert_equal 98, Report.lines.to_a.count else - assert_equal Report.lines.to_a.count, 97 + assert_equal 99, Report.lines.to_a.count end end end