Skip to content

Fix Elasticsearch BadRequest from non-Hash search param in profile pages#4334

Open
gumclaw wants to merge 2 commits intomainfrom
gc-fix-es-search-string-bad-request
Open

Fix Elasticsearch BadRequest from non-Hash search param in profile pages#4334
gumclaw wants to merge 2 commits intomainfrom
gc-fix-es-search-string-bad-request

Conversation

@gumclaw
Copy link
Copy Markdown
Contributor

@gumclaw gumclaw commented Apr 6, 2026

What

Only append params[:search] to the ES bool.must array when it's a Hash.

Why

The search_options method in Product::Searchable appends params[:search] directly to the ES must clause. When a user visits a profile page with ?search=some_string, this string gets injected into must, which expects objects. Elasticsearch returns a 400: parsing_exception: query malformed, must start with start_object.

The search param is designed for internal use (passing a pre-built ES query hash). String values from URL params should be ignored.

Fixes https://gumroad-to.sentry.io/issues/7366918596/

Impact

  • Sentry events: total
  • Users affected: ~
  • Estimated support tickets: <1/month
  • First seen:

@binary-koan
Copy link
Copy Markdown
Contributor

@gumclaw can we prevent the controller from passing the search query param to the method in the first place?

@gumclaw
Copy link
Copy Markdown
Contributor Author

gumclaw commented Apr 7, 2026

Good call — yeah, already sanitizes tags, filetypes, size, and offer_code, so it makes sense to strip non-Hash search values there too. That way we catch it at the entry point rather than deep in the ES query builder.

Something like adding this to format_search_params!:

params.delete(:search) unless params[:search].is_a?(Hash)

Then the is_a?(Hash) guard in search_options becomes redundant and we can revert that line back to the original if params[:search].

I'll update the PR.

@gumclaw gumclaw force-pushed the gc-fix-es-search-string-bad-request branch from 526b033 to 2fb38c0 Compare April 8, 2026 14:19
gumclaw added 2 commits April 8, 2026 15:26
The search_options method appends params[:search] directly to the
ES bool.must array. When a URL query parameter like ?search=string
arrives, this injects a string into must, which expects objects.

Only append params[:search] when it's a Hash (the intended internal
use case). String values from URL params are now ignored.

Fixes https://gumroad-to.sentry.io/issues/7366918596/
Strip non-Hash search params at the controller level in
format_search_params! instead of guarding in the ES query builder.
This is consistent with how tags, filetypes, and size are already
sanitized in the same method.
@gumclaw gumclaw force-pushed the gc-fix-es-search-string-bad-request branch from 2fb38c0 to ef5306c Compare April 8, 2026 19:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants