ruby.rails.security.brakeman.check-unscoped-find.check-unscoped-find
semgrep
Author
unknown
Download Count*
License
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
Short Link: https://sg.run/dPbP