Module: Glib::Params::Allowlist
- Extended by:
- ActiveSupport::Concern
- Defined in:
- app/controllers/concerns/glib/params/allowlist.rb
Defined Under Namespace
Classes: UnrecognizedValue
Instance Method Summary collapse
-
#glib_allowlist_symbol_param(value, allowed_symbols, default:) ⇒ Object
Resolve a stringly-typed request param (or any boundary string) to one symbol drawn from a closed allow-list (+allowed_symbols+), returning
defaultwhen the value is missing, blank, or not recognised.
Instance Method Details
#glib_allowlist_symbol_param(value, allowed_symbols, default:) ⇒ Object
Resolve a stringly-typed request param (or any boundary string) to one
symbol drawn from a closed allow-list (+allowed_symbols+), returning
default when the value is missing, blank, or not recognised.
This is the symbol-DoS-safe replacement for params[:x].to_sym. A bare
.to_sym on a raw value mints a symbol for every distinct string a client
sends, including values you intend to reject on the next line, the classic
symbol-DoS vector. This only ever returns a symbol already present in
allowed_symbols (or default), so attacker input can never create a new
symbol regardless of what is sent.
Degrade-vs-raise is decided by the REQUEST METHOD:
- GET/HEAD: unrecognised values quietly degrade to
default— crawlers and bots probe read endpoints with garbage, and a filter page must not 500 on?mode=garbage. - Mutating requests (POST/PATCH/PUT/DELETE): a PRESENT-but-unrecognised
value raises UnrecognizedValue (see above) — this is how a forgotten
allow-list entry announces itself instead of hiding.
Blank/missing values fall through to
defaultquietly on EVERY method (forms legitimately post no value; no symbol's string form is blank).
allowed_symbols may also contain strings (e.g. a Rails enum's .keys)
— the matched entry is symbolized on the way out, so the return value is
ALWAYS a symbol (or default). That to_sym runs only on the
developer-controlled list entry, never on value, so the DoS-safety
above is unaffected.
38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'app/controllers/concerns/glib/params/allowlist.rb', line 38 def glib_allowlist_symbol_param(value, allowed_symbols, default:) match = allowed_symbols.find { |symbol| symbol.to_s == value.to_s }&.to_sym return match if match if value.present? && !request.get? && !request.head? raise UnrecognizedValue, "Unrecognised #{request.request_method} param value #{value.to_s.truncate(80).inspect} " \ "(allowed: #{allowed_symbols.map(&:to_sym).inspect})" end default end |