Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge branch 'master' into benchmark

  • Loading branch information...
commit afb4c3a414ac991fcb25036967cbd1db9e31a53d 2 parents 4c3ea23 + 9146de5
@presidentbeef authored
View
9 CHANGES
@@ -1,8 +1,13 @@
-# Unreleased
+# 2.4.0
+ * Detect Rails LTS versions
+ * Reduce false positives for SQL injection in string building
+ * More accurate user input marking for SQL injection warnings
+ * Detect SQL injection in `delete_all`/`destroy_all`
+ * Detect SQL injection raw SQL queries using `connection`
* Parse exact versions from Gemfile.lock for all gems
* Ignore generators
- * Update to RubyParser 3.3.0
+ * Update to RubyParser 3.4.0
* Fix false positives when SQL methods are not called on AR models (Aaron Bedra)
* Add check for uses of OpenSSL::SSL::VERIFY_NONE (Aaron Bedra)
* No longer raise exceptions if a class name cannot be determined
View
2  brakeman-min.gemspec
@@ -14,7 +14,7 @@ Gem::Specification.new do |s|
s.license = "MIT"
s.cert_chain = ['brakeman-public_cert.pem']
s.signing_key = gem_priv_key if File.exist? gem_priv_key and $0 =~ /gem\z/
- s.add_dependency "ruby_parser", "~>3.2.2"
+ s.add_dependency "ruby_parser", "~>3.4.0"
s.add_dependency "ruby2ruby", "~>2.0.5"
s.add_dependency "multi_json", "~>1.2"
end
View
2  brakeman.gemspec
@@ -14,7 +14,7 @@ Gem::Specification.new do |s|
s.license = "MIT"
s.cert_chain = ['brakeman-public_cert.pem']
s.signing_key = gem_priv_key if File.exist? gem_priv_key and $0 =~ /gem\z/
- s.add_dependency "ruby_parser", "~>3.3.0"
+ s.add_dependency "ruby_parser", "~>3.4.0"
s.add_dependency "ruby2ruby", "~>2.0.5"
s.add_dependency "terminal-table", "~>1.4"
s.add_dependency "fastercsv", "~>1.5"
View
13 lib/brakeman/checks/base_check.rb
@@ -452,10 +452,11 @@ def include_target? exp, target
#Returns true if low_version <= RAILS_VERSION <= high_version
#
#If the Rails version is unknown, returns false.
- def version_between? low_version, high_version
- return false unless tracker.config[:rails_version]
+ def version_between? low_version, high_version, current_version = nil
+ current_version ||= tracker.config[:rails_version]
+ return false unless current_version
- version = tracker.config[:rails_version].split(".").map! { |n| n.to_i }
+ version = current_version.split(".").map! { |n| n.to_i }
low_version = low_version.split(".").map! { |n| n.to_i }
high_version = high_version.split(".").map! { |n| n.to_i }
@@ -478,6 +479,12 @@ def version_between? low_version, high_version
true
end
+ def lts_version? version
+ tracker.config[:gems] and
+ tracker.config[:gems][:'railslts-version'] and
+ version_between? version, "2.3.18.99", tracker.config[:gems][:'railslts-version']
+ end
+
def gemfile_or_environment
if @app_tree.exists?("Gemfile")
"Gemfile"
View
2  lib/brakeman/checks/check_number_to_currency.rb
@@ -6,6 +6,8 @@ class Brakeman::CheckNumberToCurrency < Brakeman::BaseCheck
@description = "Checks for number_to_currency XSS vulnerability in certain versions"
def run_check
+ return if lts_version? '2.3.18.6'
+
if (version_between? "2.0.0", "3.2.15" or version_between? "4.0.0", "4.0.1")
check_number_to_currency_usage
View
154 lib/brakeman/checks/check_sql.rb
@@ -16,20 +16,32 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
def run_check
@rails_version = tracker.config[:rails_version]
- @sql_targets = [:all, :average, :calculate, :count, :count_by_sql, :exists?,
+ @sql_targets = [:all, :average, :calculate, :count, :count_by_sql, :exists?, :delete_all, :destroy_all,
:find, :find_by_sql, :first, :last, :maximum, :minimum, :pluck, :sum, :update_all]
@sql_targets.concat [:from, :group, :having, :joins, :lock, :order, :reorder, :select, :where] if tracker.options[:rails3]
+ @connection_calls = [:delete, :execute, :insert, :select_all, :select_one,
+ :select_rows, :select_value, :select_values]
+
+ if tracker.options[:rails3]
+ @connection_calls.concat [:exec_delete, :exec_insert, :exec_query, :exec_update]
+ else
+ @connection_calls.concat [:add_limit!, :add_offset_limit!, :add_lock!]
+ end
+
Brakeman.debug "Finding possible SQL calls on models"
calls = tracker.find_call :targets => active_record_models.keys,
:methods => @sql_targets,
:chained => true
Brakeman.debug "Finding possible SQL calls with no target"
- calls.concat tracker.find_call(:target => nil, :method => @sql_targets)
+ calls.concat tracker.find_call(:target => nil, :methods => @sql_targets)
Brakeman.debug "Finding possible SQL calls using constantized()"
- calls.concat tracker.find_call(:method => @sql_targets).select { |result| constantize_call? result }
+ calls.concat tracker.find_call(:methods => @sql_targets).select { |result| constantize_call? result }
+
+ connect_targets = active_record_models.keys + [nil, :"ActiveRecord::Base"]
+ calls.concat tracker.find_call(:targets => connect_targets, :methods => @connection_calls, :chained => true).select { |result| connect_call? result }
Brakeman.debug "Finding calls to named_scope or scope"
calls.concat find_scope_calls
@@ -136,13 +148,14 @@ def process_result result
return if duplicate?(result) or result[:call].original_line
return if result[:target].nil? && !active_record_models.include?(result[:location][:class])
+
call = result[:call]
method = call.method
dangerous_value = case method
when :find
check_find_arguments call.second_arg
- when :exists?
+ when :exists?, :delete_all, :destroy_all
check_find_arguments call.first_arg
when :named_scope, :scope
check_scope_arguments call
@@ -172,6 +185,8 @@ def process_result result
unsafe_sql? call.first_arg
when :update_all
check_update_all_arguments call.args
+ when *@connection_calls
+ check_by_sql_arguments call.first_arg
else
Brakeman.debug "Unhandled SQL method: #{method}"
end
@@ -341,12 +356,46 @@ def check_hash_keys exp
#unless safe_value? explicitly returns true.
def check_string_interp arg
arg.each do |exp|
- return exp.value if node_type?(exp, :string_eval, :evstr) and not safe_value?(exp.value)
+ if dangerous = unsafe_string_interp?(exp)
+ return dangerous
+ end
end
nil
end
+ #Returns value if interpolated value is not something safe
+ def unsafe_string_interp? exp
+ if node_type? exp, :string_eval, :evstr
+ value = exp.value
+ else
+ value = exp
+ end
+
+ if not sexp? value
+ nil
+ elsif call? value and value.method == :to_s
+ unsafe_string_interp? value.target
+ else
+ case value.node_type
+ when :or
+ unsafe_string_interp?(value.lhs) || unsafe_string_interp?(value.rhs)
+ when :string_interp, :dstr
+ if dangerous = check_string_interp(value)
+ return dangerous
+ end
+ else
+ if safe_value? value
+ nil
+ elsif string_building? value
+ check_for_string_building value
+ else
+ value
+ end
+ end
+ end
+ end
+
#Checks the given expression for unsafe SQL values. If an unsafe value is
#found, returns that value (may be the given _exp_ or a subexpression).
#
@@ -442,14 +491,47 @@ def check_for_string_building exp
target = exp.target
method = exp.method
+ arg = exp.first_arg
+
+ if STRING_METHODS.include? method
+ if string? target
+ check_string_arg arg
+ elsif string? arg
+ check_string_arg target
+ elsif call? target
+ check_for_string_building target
+ elsif node_type? target, :string_interp, :dstr or
+ node_type? arg, :string_interp, :dstr
+
+ check_string_arg target and
+ check_string_arg arg
+ end
+ else
+ nil
+ end
+ end
- if string? target or string? exp.first_arg
- return exp if STRING_METHODS.include? method
- elsif STRING_METHODS.include? method and call? target
- return unsafe_sql? target
+ def check_string_arg exp
+ if safe_value? exp
+ nil
+ elsif string_building? exp
+ check_for_string_building exp
+ elsif node_type? exp, :string_interp, :dstr
+ check_string_interp exp
+ elsif call? exp and exp.method == :to_s
+ check_string_arg exp.target
+ else
+ exp
end
+ end
- nil
+ def string_building? exp
+ return false unless call? exp and STRING_METHODS.include? exp.method
+
+ node_type? exp.target, :str, :dstr, :string_interp or
+ node_type? exp.first_arg, :str, :dstr, :string_interp or
+ string_building? exp.target or
+ string_building? exp.first_arg
end
IGNORE_METHODS_IN_SQL = Set[:id, :merge_conditions, :table_name, :to_i, :to_f,
@@ -465,7 +547,13 @@ def safe_value? exp
when :str, :lit, :const, :colon2, :nil, :true, :false
true
when :call
- IGNORE_METHODS_IN_SQL.include? exp.method
+ if exp.method == :to_s
+ safe_value? exp.target
+ else
+ IGNORE_METHODS_IN_SQL.include? exp.method or
+ quote_call? exp or
+ exp.method.to_s.end_with? "_id"
+ end
when :if
safe_value? exp.then_clause and safe_value? exp.else_clause
when :block, :rlist
@@ -477,6 +565,16 @@ def safe_value? exp
end
end
+ QUOTE_METHODS = [:quote, :quote_column_name, :quoted_date, :quote_string, :quote_table_name]
+
+ def quote_call? exp
+ if call? exp.target
+ exp.target.method == :connection and QUOTE_METHODS.include? exp.method
+ elsif exp.target.nil?
+ exp.method == :quote_value
+ end
+ end
+
#Check call for string building
def check_call exp
return unless call? exp
@@ -522,6 +620,24 @@ def constantize_call? result
call? call.target and call.target.method == :constantize
end
+ SELF_CLASS = s(:call, s(:self), :class)
+
+ def connect_call? result
+ call = result[:call]
+ target = call.target
+
+ if call? target and target.method == :connection
+ target = target.target
+ klass = class_name(target)
+
+ target.nil? or
+ target == SELF_CLASS or
+ node_type? target, :self or
+ klass == :"ActiveRecord::Base" or
+ active_record_models.include? klass
+ end
+ end
+
def upgrade_version? versions
versions.each do |low, high, upgrade|
return upgrade if version_between? low, high
@@ -530,8 +646,8 @@ def upgrade_version? versions
false
end
-def check_rails_versions_against_cve_issues
- [
+ def check_rails_versions_against_cve_issues
+ issues = [
{
:cve => "CVE-2012-2660",
:versions => [%w[2.0.0 2.3.14 2.3.17], %w[3.0.0 3.0.12 3.0.13], %w[3.1.0 3.1.4 3.1.5], %w[3.2.0 3.2.3 3.2.4]],
@@ -557,12 +673,18 @@ 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"
},
- {
+
+ ]
+
+ unless lts_version? '2.3.18.6'
+ issues << {
: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|
+ }
+ end
+
+ issues.each do |cve_issue|
cve_warning_for cve_issue[:versions], cve_issue[:cve], cve_issue[:url]
end
end
View
1  lib/brakeman/checks/check_translate_bug.rb
@@ -7,6 +7,7 @@ class Brakeman::CheckTranslateBug < Brakeman::BaseCheck
@description = "Report XSS vulnerability in translate helper"
def run_check
+ return if lts_version? '2.3.18.6'
if (version_between?('2.3.0', '2.3.99') and tracker.config[:escape_html]) or
version_between?('3.0.0', '3.0.10') or
version_between?('3.1.0', '3.1.1')
View
2  lib/brakeman/version.rb
@@ -1,3 +1,3 @@
module Brakeman
- Version = "2.3.1"
+ Version = "2.4.0"
end
View
17 test/apps/rails2/app/models/user.rb
@@ -21,4 +21,21 @@ def test_merge_conditions
User.find(:all, :conditions => self.merge_conditions(some_conditions))
find(:all, :conditions => User.merge_conditions(some_conditions))
end
+
+ def self.some_method(value)
+ results = ActiveRecord::Base.connection.execute(%Q(SELECT
+ id
+ FROM
+ table t
+ WHERE
+ t.something = '#{value}'))
+ end
+
+ def self.test_sanitized_sql input
+ self.connection.select_all("select * from cool_table where stuff = " + self.sanitize_sql(input))
+ end
+
+ def more_sanitized_sql
+ self.connection.execute("DELETE FROM cool_table WHERE cool_id=" + quote_value(self.cool_id) + " AND my_id=" + quote_value(self.id))
+ end
end
View
15 test/apps/rails3.1/app/models/user.rb
@@ -27,4 +27,19 @@ class User < ActiveRecord::Base
belongs_to :account
attr_accessible :admin, :as => :admin
+
+ def self.sql_stuff parent_id
+ condition = parent_id.blank? ? " IS NULL" : " = #{parent_id}"
+ self.connection.select_values("SELECT max(id) FROM content_pages WHERE parent_content_page_id #{condition}")[0].to_i
+ self.connection.select_values("SELECT max(id) FROM content_pages WHERE child_content_page_id #{child_id}")[0].to_i
+
+ # Should not warn
+ User.where("#{table_name}.visibility = ?" +
+ " OR (#{table_name}.visibility = ? AND #{table_name}.id IN (" +
+ "SELECT DISTINCT a.id FROM #{table_name} a" +
+ " INNER JOIN #{User.table_name} m ON m.id = mr.member_id AND m.user_id = ?" +
+ " WHERE a.project_id IS NULL OR a.project_id = m.project_id))" +
+ " OR #{table_name}.user_id = ?",
+ stuff, stuff, user.id, user.id)
+ end
end
View
17 test/apps/rails3/app/controllers/other_controller.rb
@@ -52,4 +52,21 @@ def test_command_injection_locals
def test_mass_assign_with_strong_params
Bill.create(params[:charge])
end
+
+ def test_sql_deletes
+ User.delete_all("name = #{params[:name]}")
+ User.destroy_all("human = #{User.current.humanity}")
+ end
+
+ def test_sql_to_s status
+ column = "#{product_action_type_key.to_s}_count"
+ # Should warn about "product_action_type_key", not "product_action_type_key.to_s"
+ Product.where(id: product_id).update_all ["#{column} = #{column} + ?", delta]
+ # Should not warn
+ Product.where("id = #{id.to_s}")
+ # Should warn about "status" not "status.to_s"
+ Product.find(:all, :conditions => "product_status_id = " + status.to_s)
+ # Show not warn
+ Product.find(:all, :conditions => "id = " + Product.first.id.to_s)
+ end
end
View
14 test/apps/rails4/app/controllers/friendly_controller.rb
@@ -39,4 +39,18 @@ def permit_after_usage
User.new(params)
params.permit!
end
+
+ def sql_with_exec
+ User.connection.select_values <<-SQL
+ SELECT id FROM collection_items
+ WHERE id > #{last_collection_item.id}
+ AND collection_id IN (#{destinations.map { |d| d.id}.join(',')})"
+ SQL
+
+ Account.connection.select_rows("select thing.id, count(*) from things_stuff toc
+ join things dotoc on (toc.id=dotoc.toc_id)
+ join things do on (dotoc.data_object_id=do.id)
+ join thing_entries dohe on do.id = dohe.data_object_id
+ where do.published=#{params[:published]} and dohe.visibility_id=#{something.id} group by toc.id")
+ end
end
View
17 test/apps/rails4/app/models/account.rb
@@ -1,3 +1,20 @@
class Account < ActiveRecord::Base
attr_accessible :name, :account_id, :admin
+
+ def sql_it_up_yeah
+ connection.exec_update "UPDATE `purchases` SET type = '#{self.type}' WHERE id = '#{self.id}'"
+
+ sql = "UPDATE #{self.class.table_name} SET latest_version = #{version} where id = #{self.id}"
+ self.class.connection.execute sql
+ end
+
+ def self.more_sql_connection
+ self.connection.exec_query "UPDATE `purchases` SET type = '#{self.type}' WHERE id = '#{self.id}'"
+ end
+
+ def safe_sql_should_not_warn
+ self.class.connection.execute "DESCRIBE #{self.business_object.table_name}"
+ connection.select_one "SELECT * FROM somewhere WHERE x=#{connection.quote(params[:x])}"
+ connection.execute "DELETE FROM stuff WHERE id=#{self.id}"
+ end
end
View
6 test/apps/rails_with_xss_plugin/app/controllers/users_controller.rb
@@ -129,4 +129,10 @@ def results
def to_json
end
+
+ def delete_them_all
+ if User.connection.select_value("SELECT * from users WHERE name='#{params[:name]}'").nil? #should warn
+ User.connection.execute("TRUNCATE users") #shouldn't warn
+ end
+ end
end
View
11 test/tests/brakeman.rb
@@ -41,6 +41,11 @@ def version_between? version, low, high
@check.send(:version_between?, low, high)
end
+ def lts_version? version, low
+ @tracker.config = { :gems => { :"railslts-version" => version } }
+ @check.send(:lts_version?, low)
+ end
+
def test_version_between
assert version_between?("2.3.8", "2.3.0", "2.3.8")
assert version_between?("2.3.8", "2.3.0", "2.3.14")
@@ -61,6 +66,12 @@ def test_version_between_pre_release
assert version_between?("3.2.9.rc2", "3.2.5", "4.0.0")
end
+ def test_lts_version
+ @tracker.config = { :rails_version => "2.3.18" }
+ assert lts_version? '2.3.18.6', '2.3.18.6'
+ assert !lts_version?('2.3.18.1', '2.3.18.6')
+ assert !lts_version?(nil, '2.3.18.6')
+ end
end
class ConfigTests < Test::Unit::TestCase
View
44 test/tests/rails2.rb
@@ -12,13 +12,13 @@ def expected
:controller => 1,
:model => 3,
:template => 45,
- :generic => 48 }
+ :generic => 49 }
else
@expected ||= {
:controller => 1,
:model => 3,
:template => 45,
- :generic => 49 }
+ :generic => 50 }
end
end
@@ -308,6 +308,30 @@ def test_sql_user_input_multiline
:relative_path => "app/controllers/home_controller.rb"
end
+ def test_sql_injection_false_positive_quote_value
+ assert_no_warning :type => :warning,
+ :warning_code => 0,
+ :fingerprint => "6ea8fe3abe8eac86e5ecb790b53fb064b1152b2574b14d9354a40d07269a952e",
+ :warning_type => "SQL Injection",
+ :line => 30,
+ :message => /^Possible\ SQL\ injection/,
+ :confidence => 1,
+ :relative_path => "app/models/user.rb",
+ :user_input => s(:call, s(:call, s(:str, "DELETE FROM cool_table WHERE cool_id="), :+, s(:call, nil, :quote_value, s(:call, s(:self), :cool_id))), :+, s(:str, " AND my_id="))
+ end
+
+ def test_sql_injection_sanitize_sql
+ assert_no_warning :type => :warning,
+ :warning_code => 0,
+ :fingerprint => "7481ff666ae949b8442400cf516615ce8b04b87f7e11e33e29d4ad1303d24dd0",
+ :warning_type => "SQL Injection",
+ :line => 26,
+ :message => /^Possible\ SQL\ injection/,
+ :confidence => 1,
+ :relative_path => "app/models/user.rb",
+ :user_input => s(:call, s(:str, "select * from cool_table where stuff = "), :+, s(:call, s(:self), :sanitize_sql, s(:lvar, :input)))
+ end
+
def test_csrf_protection
assert_warning :type => :controller,
:warning_type => "Cross-Site Request Forgery",
@@ -611,6 +635,18 @@ def test_sql_injection_merge_conditions
:file => /user\.rb/,
:relative_path => "app/models/user.rb"
end
+
+ def test_sql_injection_active_record_base_connection
+ assert_warning :type => :warning,
+ :warning_code => 0,
+ :fingerprint => "37885d589fc5c41553dcc38b36b506c2e508d1f37ce040eb6dca92a958f858fb",
+ :warning_type => "SQL Injection",
+ :line => 26,
+ :message => /^Possible\ SQL\ injection/,
+ :confidence => 1,
+ :relative_path => "app/models/user.rb",
+ :user_input => s(:lvar, :value)
+ end
def test_escape_once
results = find :type => :template,
@@ -1252,13 +1288,13 @@ def expected
:controller => 1,
:model => 4,
:template => 45,
- :generic => 48 }
+ :generic => 49 }
else
@expected ||= {
:controller => 1,
:model => 4,
:template => 45,
- :generic => 49 }
+ :generic => 50 }
end
end
View
52 test/tests/rails3.rb
@@ -16,7 +16,7 @@ def expected
:controller => 1,
:model => 8,
:template => 38,
- :generic => 66
+ :generic => 70
}
if RUBY_PLATFORM == 'java'
@@ -671,6 +671,56 @@ def test_sqli_in_unusual_model_name
:file => /underline_model\.rb/
end
+ def test_sql_injection_delete_all
+ assert_warning :type => :warning,
+ :warning_code => 0,
+ :fingerprint => "6ae0b599e368b7658cfe3772ab0823d68247796b3718eaa6c1228897d633e0a2",
+ :warning_type => "SQL Injection",
+ :line => 57,
+ :message => /^Possible\ SQL\ injection/,
+ :confidence => 0,
+ :relative_path => "app/controllers/other_controller.rb",
+ :user_input => s(:call, s(:params), :[], s(:lit, :name))
+ end
+
+ def test_sql_injection_destroy_all
+ assert_warning :type => :warning,
+ :warning_code => 0,
+ :fingerprint => "0631b0564dfe4bb760c250e1de7f0678dd28e5be5c54841fa8581ac3bf2ffaaf",
+ :warning_type => "SQL Injection",
+ :line => 58,
+ :message => /^Possible\ SQL\ injection/,
+ :confidence => 0,
+ :relative_path => "app/controllers/other_controller.rb",
+ :user_input => s(:call, s(:call, s(:const, :User), :current), :humanity)
+ end
+
+ def test_sql_injection_to_s_value
+ assert_warning :type => :warning,
+ :warning_code => 0,
+ :fingerprint => "92eae7165aea8653ce37be36b5a843114fd7d6ce61f272db03239dfdaa151ee8",
+ :warning_type => "SQL Injection",
+ :line => 64,
+ :message => /^Possible\ SQL\ injection/,
+ :confidence => 1,
+ :relative_path => "app/controllers/other_controller.rb",
+ :user_input => s(:call, nil, :product_action_type_key)
+
+ assert_warning :type => :warning,
+ :warning_code => 0,
+ :fingerprint => "6066950e19a729359e867b882323ef75334791bdceac75a16f586fc53f3318a0",
+ :warning_type => "SQL Injection",
+ :line => 68,
+ :message => /^Possible\ SQL\ injection/,
+ :confidence => 1,
+ :relative_path => "app/controllers/other_controller.rb",
+ :user_input => s(:lvar, :status)
+
+ assert_no_warning :type => :warning,
+ :warning_code => 0,
+ :fingerprint => "c36f33e3b004e081622f1829be288ebdad673a7bf04922eb1d2b9a3d701362a1"
+ end
+
def test_escape_once
results = find :type => :template,
:warning_type => "Cross Site Scripting",
View
27 test/tests/rails31.rb
@@ -15,7 +15,7 @@ def expected
:model => 3,
:template => 23,
:controller => 4,
- :generic => 77 }
+ :generic => 78 }
end
def test_without_protection
@@ -954,6 +954,31 @@ def test_sql_injection_in_pluck
:file => /users_controller\.rb/
end
+
+ def test_sql_injection_with_interpolated_value
+ assert_warning :type => :warning,
+ :warning_code => 0,
+ :fingerprint => "fd5cc1e0538e8a08b47e85cb7a9a699358908d8049daaaa5609539aa8aa03278",
+ :warning_type => "SQL Injection",
+ :line => 33,
+ :message => /^Possible\ SQL\ injection/,
+ :confidence => 1,
+ :relative_path => "app/models/user.rb",
+ :user_input => s(:lvar, :parent_id)
+ end
+
+ def test_sql_injection_with_id_call
+ assert_no_warning :type => :warning,
+ :warning_code => 0,
+ :fingerprint => "b9ade31073676589cf3b6a88de30105f67cc8170e87f2c2fd1c972f50ad2a3b3",
+ :warning_type => "SQL Injection",
+ :line => 34,
+ :message => /^Possible\ SQL\ injection/,
+ :confidence => 1,
+ :relative_path => "app/models/user.rb",
+ :user_input => s(:call, nil, :child_id)
+ end
+
def test_validates_format
assert_warning :type => :model,
:warning_type => "Format Validation",
View
62 test/tests/rails4.rb
@@ -15,7 +15,7 @@ def expected
:controller => 0,
:model => 1,
:template => 1,
- :generic => 13
+ :generic => 18
}
end
@@ -144,6 +144,66 @@ def test_try_and_send_collapsing_with_sqli
:user_input => s(:call, s(:params), :[], s(:lit, :query))
end
+ def test_sql_injection_connection_execute
+ assert_warning :type => :warning,
+ :warning_code => 0,
+ :fingerprint => "4efbd2d2fc76d30296c8aa66368ddaf337b4c677778f36cddfa2290da2ec514b",
+ :warning_type => "SQL Injection",
+ :line => 8,
+ :message => /^Possible\ SQL\ injection/,
+ :confidence => 1,
+ :relative_path => "app/models/account.rb",
+ :user_input => s(:call, nil, :version)
+ end
+
+ def test_sql_injection_select_rows
+ assert_warning :type => :warning,
+ :warning_code => 0,
+ :fingerprint => "2e3c08dfb1e17f7d2e6ee5d142223477b85d27e6aa88d2d06cf0a00d04ed2d5c",
+ :warning_type => "SQL Injection",
+ :line => 50,
+ :message => /^Possible\ SQL\ injection/,
+ :confidence => 0,
+ :relative_path => "app/controllers/friendly_controller.rb",
+ :user_input => s(:call, s(:params), :[], s(:lit, :published))
+ end
+
+ def test_sql_injection_select_values
+ assert_warning :type => :warning,
+ :warning_code => 0,
+ :fingerprint => "3538776239f624a1101afe68b2e894424e8ae3f68222a6eec9fb4421d01cc557",
+ :warning_type => "SQL Injection",
+ :line => 46,
+ :message => /^Possible\ SQL\ injection/,
+ :confidence => 1,
+ :relative_path => "app/controllers/friendly_controller.rb",
+ :user_input => s(:call, s(:call_with_block, s(:call, s(:call, nil, :destinations), :map), s(:args, :d), s(:call, s(:lvar, :d), :id)), :join, s(:str, ","))
+ end
+
+ def test_sql_injection_exec_query
+ assert_warning :type => :warning,
+ :warning_code => 0,
+ :fingerprint => "59be915e75d6eb88def8fccebae1f9930bb6e50b2e598c7f04bf98c7a3235219",
+ :warning_type => "SQL Injection",
+ :line => 12,
+ :message => /^Possible\ SQL\ injection/,
+ :confidence => 1,
+ :relative_path => "app/models/account.rb",
+ :user_input => s(:call, s(:self), :type)
+ end
+
+ def test_sql_injection_exec_update
+ assert_warning :type => :warning,
+ :warning_code => 0,
+ :fingerprint => "29fac7fc616f19edf59cc230f7a86292d6c69234b5879868eaf1d954f033974f",
+ :warning_type => "SQL Injection",
+ :line => 5,
+ :message => /^Possible\ SQL\ injection/,
+ :confidence => 1,
+ :relative_path => "app/models/account.rb",
+ :user_input => s(:call, s(:self), :type)
+ end
+
def test_i18n_xss_CVE_2013_4491_workaround
assert_no_warning :type => :warning,
:warning_code => 63,
View
13 test/tests/rails_with_xss_plugin.rb
@@ -11,7 +11,7 @@ def expected
:controller => 1,
:model => 3,
:template => 2,
- :generic => 22 }
+ :generic => 23 }
end
def report
@@ -210,6 +210,17 @@ def test_sql_injection_17
:file => /results\.html\.erb/
end
+ def test_sql_injection_select_value
+ assert_warning :type => :warning,
+ :warning_code => 0,
+ :fingerprint => "e725c387439202f28c1983bf225323d93b5891695c91b9389740e2da3d74855e",
+ :warning_type => "SQL Injection",
+ :line => 134,
+ :message => /^Possible\ SQL\ injection/,
+ :confidence => 0,
+ :relative_path => "app/controllers/users_controller.rb",
+ :user_input => s(:call, s(:params), :[], s(:lit, :name))
+ end
def test_cross_site_request_forgery_18
assert_warning :type => :controller,
View
15 test/tests/rescanner.rb
@@ -252,4 +252,19 @@ def test_gemfile_rails_version_change
assert_new 1
assert_fixed 0
end
+
+ def test_gemfile_lock_rails_lts
+ gemfile = "Gemfile.lock"
+
+ before_rescan_of gemfile, "rails_with_xss_plugin" do
+ append gemfile, "railslts-version (2.3.18.6)"
+ end
+
+ #@original is actually modified
+ assert @original.config[:gems][:"railslts-version"], "2.3.18.6"
+ assert_reindex :none
+ assert_changes
+ assert_new 0
+ assert_fixed 3
+ end
end
View
4 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 98, Report.lines.to_a.count
- else
assert_equal 99, Report.lines.to_a.count
+ else
+ assert_equal 100, Report.lines.to_a.count
end
end
end
Please sign in to comment.
Something went wrong with that request. Please try again.