Class: ActiveRecordSaferLookupQuery::Checker
- Inherits:
-
Object
- Object
- ActiveRecordSaferLookupQuery::Checker
- Defined in:
- lib/active_record_safer_lookup_query/checker.rb
Defined Under Namespace
Constant Summary collapse
- DEFAULT_PATHS =
%w[ app/controllers app/graphql app/api app/forms app/services ].freeze
- DEFAULT_EXCLUDE_PATTERNS =
[ %r{\Aapp/controllers/debug/} ].freeze
- DEFAULT_WHITELIST_FILES =
%w[ .activerecord-safer-lookup-query.yml .activerecord-safer-lookup-query.yaml ].freeze
- IGNORE_MARKER =
/(?:active_record_safer_lookup_query|activerecord_safer_query|global_find_audit|tenant_scope_audit):\s*ignore/- SEVERITY_RANK =
{ 'LOW' => 1, 'MEDIUM' => 2, 'HIGH' => 3 }.freeze
- CONST_RECEIVER =
/(?:::)?[A-Z][A-Za-z0-9_]*(?:::[A-Z][A-Za-z0-9_]*)*/- PLAIN_SCOPE_CHAIN =
/(?:\.[a-z_][A-Za-z0-9_!?]*)*/- MODEL_CHAIN =
/#{CONST_RECEIVER}#{PLAIN_SCOPE_CHAIN}/- EXTERNAL_SOURCE =
/(?:params\s*(?:\[|\.|\.dig)|input\s*(?:\[|\.|\.dig)|args\s*(?:\[|\.|\.dig)|context\s*\[|session\s*\[|cookies\s*\[|request\.|headers\s*\[)/- RISKY_ID_VARIABLE =
/(?:\bid\b|[a-z][a-z0-9_]*(?:_id|_ids|_uuid|_slug|_code)\b)/- NATURAL_KEY =
/(?:email|uid|issuer|code|subdomain|slug|token|account|client_id|external_id)/- NATURAL_KEY_VALUE =
/(?:#{EXTERNAL_SOURCE}|row\b|metadata\b|attributes_hash\b|saml_setting\b|response\b|payload\b|csv\b|id_token\b|token\b|issuer\b|code\b|email\b|uid\b)/- FIND_METHOD =
/(?:find|find_by!?|find_or_initialize_by!?|find_or_create_by!?|create_or_find_by!?)/- DESTRUCTIVE_METHOD =
/(?:destroy_all|delete_all|update_all|delete|destroy)\b/- DIRECT_FIND_START =
/\b#{MODEL_CHAIN}\.(?:friendly\.)?#{FIND_METHOD}\b/- DIRECT_FIND_EXTERNAL_INPUT =
/\b#{MODEL_CHAIN}\.(?:friendly\.)?#{FIND_METHOD}\s*\([^)]*#{EXTERNAL_SOURCE}/- DIRECT_FIND_ID_START =
/\b#{MODEL_CHAIN}\.(?:friendly\.)?find\b/- DIRECT_FIND_ID_VARIABLE =
/\b#{MODEL_CHAIN}\.(?:friendly\.)?find\s*\(\s*#{RISKY_ID_VARIABLE}\s*\)/- WHERE_START =
/\b#{MODEL_CHAIN}\.where\b/- WHERE_CHAIN_START =
/\A\.where\b/- WHERE_EXTERNAL_IDS =
/\b#{MODEL_CHAIN}\.where\s*\([^)]*(?:\bid\b|[a-z_]+_id):\s*[^)]*#{EXTERNAL_SOURCE}/- NATURAL_KEY_LOOKUP_START =
/\b#{MODEL_CHAIN}\.(?:find_by!?|find_or_initialize_by!?|find_or_create_by!?|create_or_find_by!?)\b/- NATURAL_KEY_LOOKUP =
/\b#{MODEL_CHAIN}\.(?:find_by!?|find_or_initialize_by!?|find_or_create_by!?|create_or_find_by!?)\s*\([^)]*#{NATURAL_KEY}:\s*[^)]*#{NATURAL_KEY_VALUE}/- DESTRUCTIVE_EXTERNAL_ID_LOOKUP =
/\b#{MODEL_CHAIN}\.where\s*\([^)]*(?:\bid\b|[a-z_]+_id):[^)]*(?:#{EXTERNAL_SOURCE}|#{RISKY_ID_VARIABLE})[^)]*\).*\.#{DESTRUCTIVE_METHOD}/- DESTRUCTIVE_EXTERNAL_LOOKUP =
/\b#{MODEL_CHAIN}\.where\s*\([^)]*(?:#{EXTERNAL_SOURCE}|#{RISKY_ID_VARIABLE})[^)]*\).*\.#{DESTRUCTIVE_METHOD}/- DRAFT_COURSE_SCOPE =
/\bCourse\.(?:draft|closed|where\s*\([^)]*state:\s*[^)]*(?:draft|closed)|glopla_lms)\b/
Instance Method Summary collapse
- #findings ⇒ Object
-
#initialize(paths: DEFAULT_PATHS, root: Dir.pwd, whitelist_paths: []) ⇒ Checker
constructor
A new instance of Checker.
Constructor Details
#initialize(paths: DEFAULT_PATHS, root: Dir.pwd, whitelist_paths: []) ⇒ Checker
Returns a new instance of Checker.
174 175 176 177 178 |
# File 'lib/active_record_safer_lookup_query/checker.rb', line 174 def initialize(paths: DEFAULT_PATHS, root: Dir.pwd, whitelist_paths: []) @root = Pathname.new(root). @paths = paths.empty? ? DEFAULT_PATHS : paths @whitelist = Whitelist.load(root: @root, paths: whitelist_paths) end |
Instance Method Details
#findings ⇒ Object
180 181 182 183 184 185 |
# File 'lib/active_record_safer_lookup_query/checker.rb', line 180 def findings ruby_files.flat_map { |path| findings_for(path) } .uniq { |finding| [finding.path, finding.line, finding.rule] } .reject { |finding| whitelist.match?(finding) } .sort_by { |finding| [finding.path, finding.line, finding.rule] } end |