parse-community / parse-community/parse-server

Rate limit Redis keys are not scoped to the configured route

Open
#10,624 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

type:bug
Dominant language
JavaScript
Stars
21.4k
Forks
4.8k
Avg merge
7h 45m
Merged PRs (30d)
11

Description

New Issue Checklist
  • This is not a security vulnerability; it is a rate-limit isolation bug.
  • I searched the existing issues but did not find this behavior reported.
Issue Description

When configuring more than one rateLimit rule with redisUrl, rate-limit state is not scoped to the configured route, nor to the individual rule/window.

Steps to reproduce

Configure two rules with the same Redis instance:

rateLimit: [
  {
    requestPath: '/functions/a',
    requestMethods: ['POST'],
    requestTimeWindow: 30 * 24 * 60 * 60 * 1000,
    requestCount: 10,
    zone: 'user',
    redisUrl: 'redis://localhost:6379'
  },
  {
    requestPath: '/functions/b',
    requestMethods: ['POST'],
    requestTimeWindow: 60 * 60 * 1000,
    requestCount: 5,
    zone: 'user',
    redisUrl: 'redis://localhost:6379'
  }
]

For the same authenticated user:

  1. Call POST /functions/a. This creates Redis key rl:<userId> with a 30-day TTL.
  2. Call POST /functions/b. It increments that same key despite using a different path and rate-limit rule.
  3. The second rule applies its max: 5 to the shared hit count, while retaining the 30-day TTL.

Reverse the order and the shared key expires after one hour instead.

Actual Outcome

requestPath is used only to select the middleware. The key generator returns only the app ID, session token, user ID, or IP address.

With Redis, each RedisStore is constructed without a prefix, so rate-limit-redis uses its default rl: prefix for every configured rule. Different endpoints therefore share rl:<userId>.

This also means that rules with different windowMs values share a TTL. rate-limit-redis sets the TTL only when the key is first created (unless expiry reset is enabled), so the effective window depends on which endpoint is called first. Multiple limits for the same endpoint cannot be composed safely either.

Expected Outcome

Each independent rate-limit rule should use its own Redis key namespace. At a minimum, Redis keys should be scoped by requestPath, method, and zone. To safely support multiple limits on the same endpoint, the namespace should also distinguish the configured window and count (or Parse Server should expose a rule identifier).

One possible fix would be to pass a deterministic prefix to RedisStore based on the rule identity, for example a compact hash of:

{ requestPath, requestMethods, zone, requestTimeWindow, requestCount }

followed by the existing user/session/IP key.

Environment
  • Parse Server version: 9.9.0 (HULAB fork based on Parse Server 9.9.0)
  • Operating system: Amazon Linux 2023
  • Local or remote host: AWS Elastic Beanstalk
  • Database: MongoDB (not involved)
  • Client SDK: not involved; reproducible with HTTP requests
Logs

No server error is emitted. The collision is visible directly in Redis as the same rl:<userId> key being incremented by both routes.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at the rate-limit middleware's RedisStore construction and key generator, where the issue reports that requestPath is only used for middleware selection and each store uses the default rl: prefix. Trace how rule configuration reaches Redis and add focused coverage for separate routes, windows, and multiple limits; done means independent rules no longer share keys or TTLs.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, redis
Domain
backend, databases
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.