Skip to content

Clamp non-positive page params instead of raising a 500 #2236

Description

@moveson

Problem

Scout error group 91205 (production) has accumulated 7,400+ occurrences (~34/day) of:

ActionView::Template::Error: expected :page >= 1; got -11

on GET /organizations/hardrock/courses/hardrock-100-counter-clockwise/best_efforts?page=-11'%20UNION%20ALL%20SELECT...

The traffic is SQL-injection scanner bots probing the page param. The injection itself accomplishes nothing — to_i reduces the payload to -11 — but pagy raises on a non-positive page during render, so every probe becomes a 500 and a Scout error, burying real errors in noise.

Cause

PreparedParams#page (app/controllers/concerns/prepared_params.rb:54-57) guards zero but not negatives:

defpageresult=params[:page]&.to_i || FIRST_PAGEresult.zero? ? FIRST_PAGE : resultend

"-11' UNION ..."-11, which passes through to CourseBestEffortsDisplaypagy_countless_from_scope(page: page) → pagy raises.

Fix

Clamp to the first page for any value below 1:

result < 1 ? FIRST_PAGE : result

A bot asking for page -11 gets page 1 (a 200), matching the existing zero behavior. Worth a quick sweep for other params[:page] consumers that bypass PreparedParams (e.g. anything calling pagy with a raw param) so all paginated views get the same guard.

🤖 Generated with Claude Code

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions