ruby.lang.security.model-attr-accessible.model-attr-accessible

profile photo of semgrepsemgrep
Author
161
Download Count*

Checks for dangerous permitted attributes that can lead to mass assignment vulnerabilities. Query parameters allowed using permit and attr_accessible are checked for allowance of dangerous attributes admin, banned, role, and account_id. Also checks for usages of params.permit!, which allows everything. Fix: don't allow admin, banned, role, and account_id using permit or attr_accessible.

Run Locally

Run in CI

Defintion

rules:
  - id: model-attr-accessible
    message: "Checks for dangerous permitted attributes that can lead to mass
      assignment vulnerabilities. Query parameters allowed using permit and
      attr_accessible are checked for allowance of dangerous attributes admin,
      banned, role, and account_id. Also checks for usages of params.permit!,
      which allows everything. Fix: don't allow admin, banned, role, and
      account_id using permit or attr_accessible."
    metadata:
      cwe:
        - "CWE-915: Improperly Controlled Modification of Dynamically-Determined
          Object Attributes"
      references:
        - https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_model_attr_accessible.rb
      category: security
      technology:
        - ruby
      owasp:
        - A08:2021 - Software and Data Integrity Failures
      subcategory:
        - audit
      likelihood: LOW
      impact: MEDIUM
      confidence: LOW
      license: Commons Clause License Condition v1.0[LGPL-2.1-only]
      vulnerability_class:
        - Mass Assignment
    languages:
      - ruby
    severity: ERROR
    pattern-either:
      - pattern: |
          ....permit(..., :admin, ...)
      - pattern: |
          ....permit(..., :role, ...)
      - pattern: |
          ....permit(..., :banned, ...)
      - pattern: |
          ....permit(..., :account_id, ...)
      - pattern: |
          attr_accessible ..., :admin, ...
      - pattern: |
          attr_accessible ..., :role, ...
      - pattern: |
          attr_accessible ..., :banned, ...
      - pattern: |
          attr_accessible ..., :account_id, ...
      - pattern: |
          params.permit!

Examples

model-attr-accessible.rb

class Bad_attr_accessible
   include  ActiveModel::MassAssignmentSecurity

   # ruleid: model-attr-accessible
   attr_accessible :name, :admin,
                   :telephone, as: :create_params
   # ruleid: model-attr-accessible
   attr_accessible :name, :banned,
                   as: :create_params
   # ruleid: model-attr-accessible
   attr_accessible :role,
                   :telephone, as: :create_params
   # ruleid: model-attr-accessible
   attr_accessible :name,
                   :account_id, as: :create_params

   # ruleid: model-attr-accessible
   User.new(params.permit(:name, :admin))
   # ruleid: model-attr-accessible
   params_with_conditional_require(ctrl.params).permit(:name, :age, :admin)

   # ruleid: model-attr-accessible
   User.new(params.permit(:role))
   # ruleid: model-attr-accessible
   params_with_conditional_require(ctrl.params).permit(:name, :age, :role)

   # ruleid: model-attr-accessible
   User.new(params.permit(:banned, :name))
   # ruleid: model-attr-accessible
   params_with_conditional_require(ctrl.params).permit(:banned, :name, :age)

   # ruleid: model-attr-accessible
   User.new(params.permit(:address, :account_id, :age))
   # ruleid: model-attr-accessible
   params_with_conditional_require(ctrl.params).permit(:name, :account_id, :age)

   # ruleid: model-attr-accessible
   params.permit!
end

class Ok_attr_accessible
   # ok: model-attr-accessible
   attr_accessible :name, :address, :age,
                   :telephone, as: :create_params
   # ok: model-attr-accessible
   User.new(params.permit(:address, :acc, :age))
   # ok: model-attr-accessible
   params_with_conditional_require(ctrl.params).permit(:name, :address, :age)
end