Skip to content

[BUG] maxFilterValues setting is advertised in NIP-11 but never enforced #599

@saniddhyaDubey

Description

@saniddhyaDubey

Describe the bug
The relay defines limits.client.subscription.maxFilterValues (default: 2500) in settings, but this value is never checked anywhere in the codebase. A client can send a filter with 5,000+ values in authors, ids, #e, #p, etc., and the relay passes them straight to PostgreSQL as a WHERE IN (...) clause.

In EventRepository.findByFilters() (src/repositories/event-repository.ts):

builder.whereIn('event_pubkey', currentFilter.authors)

No length validation happens before this call. The setting only exists as a type definition in src/@types/settings.ts - it is never imported or read by any handler or repository.

To Reproduce
Steps to reproduce the behavior:

  1. Start nostream with default settings (maxFilterValues: 2500)
  2. Confirm NIP-11 advertises the limit:
curl -H 'Accept: application/nostr+json' http://localhost:8008

Output includes: "max_event_tags":2500
3. Generate a filter with 5,000 authors and copy to clipboard:

python3 -c "print('[\"REQ\",\"test-bug2\",{\"authors\":['+ ','.join(['\"'+'a'*64+'\"' for _ in range(5000)]) +'],\"kinds\":[1]}]')" | pbcopy
  1. Connect via wscat and paste the filter:
wscat -c ws://localhost:8008
  1. Relay accepts and returns ["EOSE","test-bug2"] - no rejection, no error

Screenshots
Image

  • Top terminal: NIP-11 output from curl with max_event_tags: 2500 highlighted, confirming the relay advertises a limit
  • Bottom terminal: wscat session where a filter with 5,000 authors was accepted and the relay responded with ["EOSE","test-bug2"] - no rejection

System (please complete the following information):

  • OS: macOS (relay running in Docker)
  • Platform: Docker Compose
  • Version: 2.1.1 (d8f62b4)

Additional context

  • grep -rn 'maxFilterValues' src/ --include='*.ts' returns only @types/settings.ts:109 - zero enforcement anywhere
  • Impact: Postgres builds a hash table for the oversized IN clause, spiking CPU and memory. Concurrent requests like this are a straightforward DoS vector.

Metadata

Metadata

Labels

bugSomething isn't working

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions