Model attribute used in regex Open
!email.blank? && !email.match( /#{domain}\z/i )
- Read upRead up
- Exclude checks
Denial of Service (DoS) is any attack which causes a service to become unavailable for legitimate clients.
For issues that Brakeman detects, this typically arises in the form of memory leaks.
Symbol DoS
Since Symbols are not garbage collected in Ruby versions prior to 2.2.0, creation of large numbers of Symbols could lead to a server running out of memory.
Brakeman checks for instances of user input which is converted to a Symbol. When this is not restricted, an attacker could create an unlimited number of Symbols.
The best approach is to simply never convert user-controlled input to a Symbol. If this cannot be avoided, use a whitelist of acceptable values.
For example:
valid_values = ["valid", "values", "here"]
if valid_values.include? params[:value]
symbolized = params[:value].to_sym
end
Regex DoS
Regular expressions can be used for DoS if the pattern and input requires exponential time to process.
Brakeman will warn about dynamic regular expressions which may be controlled by an attacker. The attacker can create an "evil regex" and then supply input which causes the server to use a large amount of resources.
It is recommended to avoid interpolating user input into regular expressions.
Class has too many lines. [339/250] Open
class Customer < ActiveRecord::Base
require_dependency 'customer/roles'
require_dependency 'customer/search'
require_dependency 'customer/special_customers'
- Read upRead up
- Exclude checks
This cop checks if the length a class exceeds some maximum value. Comment lines can optionally be ignored. The maximum allowed length is configurable.
Class Customer
has 47 methods (exceeds 20 allowed). Consider refactoring. Open
class Customer < ActiveRecord::Base
require_dependency 'customer/roles'
require_dependency 'customer/search'
require_dependency 'customer/special_customers'
File customer.rb
has 340 lines of code (exceeds 250 allowed). Consider refactoring. Open
class Customer < ActiveRecord::Base
require_dependency 'customer/roles'
require_dependency 'customer/search'
require_dependency 'customer/special_customers'
Cyclomatic complexity for update_email_subscription is too high. [14/6] Open
def update_email_subscription
return unless (e_blacklist_changed? || email_changed? || first_name_changed? || last_name_changed?)
email_list = EmailList.new or return
if e_blacklist # opting out of email
# do nothing, EXCEPT in the case where customer is transitioning from opt-in to opt-out,
- Read upRead up
- Exclude checks
This cop checks that the cyclomatic complexity of methods is not higher than the configured maximum. The cyclomatic complexity is the number of linearly independent paths through a method. The algorithm counts decision points and adds one.
An if statement (or unless or ?:) increases the complexity by one. An else branch does not, since it doesn't add a decision point. The && operator (or keyword and) can be converted to a nested if statement, and ||/or is shorthand for a sequence of ifs, so they also add one. Loops can be said to have an exit condition, so they add one.
Cyclomatic complexity for valid_as_guest_checkout? is too high. [8/6] Open
def valid_as_guest_checkout?
if (first_name.blank? || last_name.blank? || email.blank? || street.blank? || city.blank? || state.blank? || zip.blank?)
errors.add :base, "Please provide your email address for order confirmation, and your credit card billing name and address."
false
else
- Read upRead up
- Exclude checks
This cop checks that the cyclomatic complexity of methods is not higher than the configured maximum. The cyclomatic complexity is the number of linearly independent paths through a method. The algorithm counts decision points and adds one.
An if statement (or unless or ?:) increases the complexity by one. An else branch does not, since it doesn't add a decision point. The && operator (or keyword and) can be converted to a nested if statement, and ||/or is shorthand for a sequence of ifs, so they also add one. Loops can be said to have an exit condition, so they add one.
Cyclomatic complexity for valid_as_gift_recipient? is too high. [7/6] Open
def valid_as_gift_recipient?
# must have first and last name, mailing addr, and at least one
# phone or email
valid = true
if (first_name.blank? || last_name.blank?)
- Read upRead up
- Exclude checks
This cop checks that the cyclomatic complexity of methods is not higher than the configured maximum. The cyclomatic complexity is the number of linearly independent paths through a method. The algorithm counts decision points and adds one.
An if statement (or unless or ?:) increases the complexity by one. An else branch does not, since it doesn't add a decision point. The && operator (or keyword and) can be converted to a nested if statement, and ||/or is shorthand for a sequence of ifs, so they also add one. Loops can be said to have an exit condition, so they add one.
Method update_email_subscription
has a Cognitive Complexity of 13 (exceeds 5 allowed). Consider refactoring. Open
def update_email_subscription
return unless (e_blacklist_changed? || email_changed? || first_name_changed? || last_name_changed?)
email_list = EmailList.new or return
if e_blacklist # opting out of email
# do nothing, EXCEPT in the case where customer is transitioning from opt-in to opt-out,
- Read upRead up
Cognitive Complexity
Cognitive Complexity is a measure of how difficult a unit of code is to intuitively understand. Unlike Cyclomatic Complexity, which determines how difficult your code will be to test, Cognitive Complexity tells you how difficult your code will be to read and comprehend.
A method's cognitive complexity is based on a few simple rules:
- Code is not considered more complex when it uses shorthand that the language provides for collapsing multiple statements into one
- Code is considered more complex for each "break in the linear flow of the code"
- Code is considered more complex when "flow breaking structures are nested"
Further reading
Consider simplifying this complex logical expression. Open
if (first_name.blank? || last_name.blank? || email.blank? || street.blank? || city.blank? || state.blank? || zip.blank?)
errors.add :base, "Please provide your email address for order confirmation, and your credit card billing name and address."
false
else
# this is a HACK: set created_by_admin to bypass most other validations.
Method to_csv
has a Cognitive Complexity of 9 (exceeds 5 allowed). Consider refactoring. Open
def self.to_csv(custs,opts={})
CSV::Writer.generate(output='') do |csv|
unless opts[:suppress_header]
header = self.csv_header
header += opts[:extra].map(&:humanize) if opts[:extra]
- Read upRead up
Cognitive Complexity
Cognitive Complexity is a measure of how difficult a unit of code is to intuitively understand. Unlike Cyclomatic Complexity, which determines how difficult your code will be to test, Cognitive Complexity tells you how difficult your code will be to read and comprehend.
A method's cognitive complexity is based on a few simple rules:
- Code is not considered more complex when it uses shorthand that the language provides for collapsing multiple statements into one
- Code is considered more complex for each "break in the linear flow of the code"
- Code is considered more complex when "flow breaking structures are nested"
Further reading
Method force_valid_fields
has a Cognitive Complexity of 8 (exceeds 5 allowed). Consider refactoring. Open
def force_valid_fields
if self.force_valid
self.created_by_admin = true # will skip most validations
self.first_name = '_' if first_name.blank?
self.first_name.gsub!(NAME_FORBIDDEN_CHARS, '_')
- Read upRead up
Cognitive Complexity
Cognitive Complexity is a measure of how difficult a unit of code is to intuitively understand. Unlike Cyclomatic Complexity, which determines how difficult your code will be to test, Cognitive Complexity tells you how difficult your code will be to read and comprehend.
A method's cognitive complexity is based on a few simple rules:
- Code is not considered more complex when it uses shorthand that the language provides for collapsing multiple statements into one
- Code is considered more complex for each "break in the linear flow of the code"
- Code is considered more complex when "flow breaking structures are nested"
Further reading
Method to_csv
has a Cognitive Complexity of 8 (exceeds 5 allowed). Consider refactoring. Open
def to_csv
[
(first_name.name_capitalize unless first_name.blank?),
(last_name.name_capitalize unless last_name.blank?),
id,
- Read upRead up
Cognitive Complexity
Cognitive Complexity is a measure of how difficult a unit of code is to intuitively understand. Unlike Cyclomatic Complexity, which determines how difficult your code will be to test, Cognitive Complexity tells you how difficult your code will be to read and comprehend.
A method's cognitive complexity is based on a few simple rules:
- Code is not considered more complex when it uses shorthand that the language provides for collapsing multiple statements into one
- Code is considered more complex for each "break in the linear flow of the code"
- Code is considered more complex when "flow breaking structures are nested"
Further reading
Method authenticate
has a Cognitive Complexity of 6 (exceeds 5 allowed). Consider refactoring. Open
def self.authenticate(email, password)
if (email.blank? || password.blank?)
u = Customer.new
u.errors.add(:login_failed, I18n.t('login.email_or_password_blank'))
return u
- Read upRead up
Cognitive Complexity
Cognitive Complexity is a measure of how difficult a unit of code is to intuitively understand. Unlike Cyclomatic Complexity, which determines how difficult your code will be to test, Cognitive Complexity tells you how difficult your code will be to read and comprehend.
A method's cognitive complexity is based on a few simple rules:
- Code is not considered more complex when it uses shorthand that the language provides for collapsing multiple statements into one
- Code is considered more complex for each "break in the linear flow of the code"
- Code is considered more complex when "flow breaking structures are nested"
Further reading
HACK found Open
# this is a HACK: set created_by_admin to bypass most other validations.
- Exclude checks
end
at 374, 4 is not aligned with self.vouchers.includes(:vouchertype).detect do |f|
at 372, 6. Open
end
- Read upRead up
- Exclude checks
This cop checks whether the end keywords are aligned properly for do end blocks.
Three modes are supported through the EnforcedStyleAlignWith
configuration parameter:
start_of_block
: the end
shall be aligned with the
start of the line where the do
appeared.
start_of_line
: the end
shall be aligned with the
start of the line where the expression started.
either
(which is the default) : the end
is allowed to be in either
location. The autofixer will default to start_of_line
.
Example: EnforcedStyleAlignWith: either (default)
# bad
foo.bar
.each do
baz
end
# good
variable = lambda do |i|
i
end
Example: EnforcedStyleAlignWith: startofblock
# bad
foo.bar
.each do
baz
end
# good
foo.bar
.each do
baz
end
Example: EnforcedStyleAlignWith: startofline
# bad
foo.bar
.each do
baz
end
# good
foo.bar
.each do
baz
end
end
at 382, 4 is not aligned with self.vouchers.includes(:vouchertype).detect do |f|
at 379, 6. Open
end
- Read upRead up
- Exclude checks
This cop checks whether the end keywords are aligned properly for do end blocks.
Three modes are supported through the EnforcedStyleAlignWith
configuration parameter:
start_of_block
: the end
shall be aligned with the
start of the line where the do
appeared.
start_of_line
: the end
shall be aligned with the
start of the line where the expression started.
either
(which is the default) : the end
is allowed to be in either
location. The autofixer will default to start_of_line
.
Example: EnforcedStyleAlignWith: either (default)
# bad
foo.bar
.each do
baz
end
# good
variable = lambda do |i|
i
end
Example: EnforcedStyleAlignWith: startofblock
# bad
foo.bar
.each do
baz
end
# good
foo.bar
.each do
baz
end
Example: EnforcedStyleAlignWith: startofline
# bad
foo.bar
.each do
baz
end
# good
foo.bar
.each do
baz
end
Useless public
access modifier. Open
public
- Read upRead up
- Exclude checks
This cop checks for redundant access modifiers, including those with no
code, those which are repeated, and leading public
modifiers in a
class or module body. Conditionally-defined methods are considered as
always being defined, and thus access modifiers guarding such methods
are not redundant.
Example:
class Foo
public # this is redundant (default access is public)
def method
end
private # this is not redundant (a method is defined)
def method2
end
private # this is redundant (no following methods are defined)
end
Example:
class Foo
# The following is not redundant (conditionally defined methods are
# considered as always defining a method)
private
if condition?
def method
end
end
protected # this is not redundant (method is defined)
define_method(:method2) do
end
protected # this is redundant (repeated from previous modifier)
[1,2,3].each do |i|
define_method("foo#{i}") do
end
end
# The following is redundant (methods defined on the class'
# singleton class are not affected by the public modifier)
public
def self.method3
end
end
Example:
# Lint/UselessAccessModifier:
# ContextCreatingMethods:
# - concerning
require 'active_support/concern'
class Foo
concerning :Bar do
def some_public_method
end
private
def some_private_method
end
end
# this is not redundant because `concerning` created its own context
private
def some_other_private_method
end
end
Example:
# Lint/UselessAccessModifier:
# MethodCreatingMethods:
# - delegate
require 'active_support/core_ext/module/delegation'
class Foo
# this is not redundant because `delegate` creates methods
private
delegate :method_a, to: :method_b
end