ruby.rails.security.brakeman.check-unscoped-find.check-unscoped-find

profile photo of semgrepsemgrep
Author
unknown
Download Count*

Found an unscoped find(...) with user-controllable input. If the ActiveRecord model being searched against is sensitive, this may lead to Insecure Direct Object Reference (IDOR) behavior and allow users to read arbitrary records. Scope the find to the current user, e.g. current_user.accounts.find(params[:id]).

Run Locally

Run in CI

Defintion

rules:
  - id: check-unscoped-find
    mode: taint
    pattern-sources:
      - pattern-either:
          - pattern: |
              cookies[...]
          - patterns:
              - pattern: |
                  cookies. ... .$PROPERTY[...]
              - metavariable-regex:
                  metavariable: $PROPERTY
                  regex: (?!signed|encrypted)
          - pattern: |
              params[...]
          - pattern: |
              request.env[...]
    pattern-sinks:
      - patterns:
          - pattern-either:
              - pattern: $MODEL.find(...)
              - pattern: $MODEL.find_by_id(...)
              - pattern: $MODEL.find_by_id!(...)
          - metavariable-regex:
              metavariable: $MODEL
              regex: "[A-Z]\\S+"
    message: Found an unscoped `find(...)` with user-controllable input. If the
      ActiveRecord model being searched against is sensitive, this may lead to
      Insecure Direct Object Reference (IDOR) behavior and allow users to read
      arbitrary records. Scope the find to the current user, e.g.
      `current_user.accounts.find(params[:id])`.
    languages:
      - ruby
    severity: WARNING
    metadata:
      source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_unscoped_find.rb
      category: security
      cwe:
        - "CWE-639: Authorization Bypass Through User-Controlled Key"
      owasp:
        - A05:2017 - Broken Access Control
        - A01:2021 - Broken Access Control
      technology:
        - ruby
        - rails
      references:
        - https://brakemanscanner.org/docs/warning_types/unscoped_find/
        - https://github.com/presidentbeef/brakeman/blob/main/test/apps/rails3.1/app/controllers/users_controller.rb
      subcategory:
        - vuln
      likelihood: MEDIUM
      impact: HIGH
      confidence: MEDIUM
      license: Commons Clause License Condition v1.0[LGPL-2.1-only]
      vulnerability_class:
        - Improper Authorization

Examples

check-unscoped-find.rb

class GroupsController < ApplicationController

  def show
    #ruleid: check-unscoped-find
    @user = User.find(params[:id])

    respond_to do |format|
      format.html # show.html.erb
      format.json { render :json => @user }
    end
  end

  def show_ok
    #ok: check-unscoped-find
    @user = User.find(session[:id])

    respond_to do |format|
      format.html # show.html.erb
      format.json { render :json => @user }
    end
  end

  def show_ok2
    #ok: check-unscoped-find
    current_user = User.find(session[:id])
    #ok: check-unscoped-find
    current_user.accounts.find(param[:id])

    respond_to do |format|
      format.html # show.html.erb
      format.json { render :json => @user }
    end
  end

  def get
    #ruleid: check-unscoped-find
    @some_record = SomeRecord.find_by_id!(params[:id])

    respond_to do |format|
      format.html # show.html.erb
      format.json { render :json => @user }
    end
  end

end