Skip to content

RateLimiter: windowSeconds=0 leaks opaque div-by-zero error from fixedWindow/tokenBucket #2693

Description

@bpamiri

Summary

wheels.middleware.RateLimiter does not validate windowSeconds > 0 at
construction. When the value is 0, the strategy math divides by it and the
caller sees a generic CFML "You cannot divide by zero" exception instead of a
framework-shaped configuration error.

Confirmed against current main (vendor/wheels/middleware/RateLimiter.cfc)
on BoxLang 1.5.

Reproduction

var rl = new wheels.middleware.RateLimiter(maxRequests = 1, windowSeconds = 0);
rl.handle(request = {cgi: {remote_addr: "192.0.2.1"}}, next = function(req) { return "ok"; });

Result for strategy="fixedWindow" (default) and strategy="tokenBucket":

Application :: You cannot divide by zero.

strategy="slidingWindow" happens to accept windowSeconds=0 because its
arithmetic shape doesn't divide by the window — but a window of zero seconds
is still nonsensical and lets every request through.

Negative values for windowSeconds and maxRequests silently produce
inert behavior rather than a config error.

Why this matters

A developer who fat-fingers the window value gets a JVM-flavored error with
no pointer back to their set(middleware=[...]) line. The framework should
fail at construction time with Wheels.RateLimiter.InvalidConfiguration and
a message naming the bad parameter — the same pattern already used for
strategy, storage, and proxyStrategy.

Proposed fix

In RateLimiter.init(), add the same validation idiom already used for the
string params:

  • windowSeconds <= 0 → throw Wheels.RateLimiter.InvalidConfiguration
  • maxRequests < 0 → throw Wheels.RateLimiter.InvalidConfiguration

maxRequests = 0 is legitimate (block everything, useful for kill-switching).

Plus a regression spec in
vendor/wheels/tests/specs/middleware/RateLimiterSpec.cfc.

Discovered while

Writing the "Skip the Plugin: Building a Rate-Limited API in Wheels 4.0"
blog post and probing edge cases the article should mention. Fix is small
and queued on the same branch (claude/wheels-blog-article-titles-6kPSk).

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions