ruby.rails.security.brakeman.check-validation-regex.check-validation-regex

profile photo of semgrepsemgrep
Author
unknown
Download Count*

$V Found an incorrectly-bounded regex passed to validates_format_of or validate ... format => .... Ruby regex behavior is multiline by default and lines should be terminated by \A for beginning of line and \Z for end of line, respectively.

Run Locally

Run in CI

Defintion

rules:
  - id: check-validation-regex
    mode: search
    patterns:
      - pattern-either:
          - pattern: |
              validates ..., :format => <... $V ...>,...
          - pattern: |
              validates_format_of ..., :with => <... $V ...>,...
      - metavariable-regex:
          metavariable: $V
          regex: /(.{2}(?<!\\A)[^\/]+|[^\/]+(?<!\\[Zz]))\/
    message: $V Found an incorrectly-bounded regex passed to `validates_format_of`
      or `validate ... format => ...`. Ruby regex behavior is multiline by
      default and lines should be terminated by `\A` for beginning of line and
      `\Z` for end of line, respectively.
    languages:
      - ruby
    severity: ERROR
    metadata:
      source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_validation_regex.rb
      category: security
      cwe:
        - "CWE-185: Incorrect Regular Expression"
      owasp:
        - A05:2017 - Broken Access Control
        - A01:2021 - Broken Access Control
      technology:
        - ruby
        - rails
      references:
        - https://brakemanscanner.org/docs/warning_types/format_validation/
        - https://github.com/presidentbeef/brakeman/blob/aef6253a8b7bcb97116f2af1ed2a561a6ae35bd5/test/apps/rails3/app/models/account.rb
        - https://github.com/presidentbeef/brakeman/blob/main/test/apps/rails3.1/app/models/account.rb
      subcategory:
        - vuln
      impact: MEDIUM
      likelihood: MEDIUM
      confidence: MEDIUM
      license: Commons Clause License Condition v1.0[LGPL-2.1-only]
      vulnerability_class:
        - Improper Validation

Examples

check-validation-regex.rb

class Account < ActiveRecord::Base
  #ruleid: check-validation-regex
  validates :username, :length => 6..20, :format => /([a-z][0-9])+/i
  #ruleid: check-validation-regex
  validates :phone, :format => { :with => /(\d{3})-(\d{3})-(\d{4})/, :on => :create }, :presence => true 
  #ruleid: check-validation-regex
  validates :first_name, :format => /\w+/
  serialize :cc_info #safe from CVE-2013-0277
  attr_accessible :blah_admin_blah
end

class Account < ActiveRecord::Base
  #ruleid: check-validation-regex
  validates_format_of :name, :with => /^[a-zA-Z]+$/
  #ruleid: check-validation-regex
  validates_format_of :blah, :with => /\A[a-zA-Z]+$/
  #ruleid: check-validation-regex
  validates_format_of :blah2, :with => /^[a-zA-Z]+\Z/
  #ruleid: check-validation-regex
  validates_format_of :something, :with => /[a-zA-Z]\z/
  #ok: check-validation-regex
  validates_format_of :good_valid, :with => /\A[a-zA-Z]\z/ #No warning
  #ok: check-validation-regex
  validates_format_of :not_bad, :with => /\A[a-zA-Z]\Z/ #No warning

  def mass_assign_it
    Account.new(params[:account_info]).some_other_method
  end

  def test_class_eval
    #Should not raise a warning
    User.class_eval do
      attr_reader :some_private_thing
    end
  end
end