Skip to content
Centriu
Centriu Loop

Rate Limit Fail-Closed Automation: A Limiter That Could Not See Was Letting Everything Through

Centriu Loop's own rate limiter previously contained two separate, independent situations where it defaulted to allowing a request through with no limit applied at all, confirmed directly from the prior code's own logic. First: whenever the limiter could not determine an identifier — an IP address, a user id — to measure a request against at all, it returned an unconditional "allowed," reasoning that with nothing to attribute the request to, there was nothing to check against a threshold. Second: whenever the limiter's own underlying database query, responsible for counting how many recent attempts had already occurred, failed for any reason, the failure was silently absorbed by a plain `count ?? 0` fallback — meaning a broken count was treated as a count of exactly zero, which is always comfortably under any real threshold, letting the request through as if the limiter had genuinely checked and found nothing concerning. Both situations share the same underlying shape: they are the two moments where a rate limiter's own confidence in what it is measuring is at its lowest, and the prior code responded to both by imposing no restriction whatsoever, rather than by treating reduced confidence as a reason for MORE caution, not less. The fix reverses both defaults to explicitly deny the request in either situation, and additionally hardens how a caller's IP address is determined in the first place — trusting only a specific header set exclusively by Centriu's own reverse proxy, rather than a client-suppliable one a caller could set to any arbitrary value.
Blind spots let everything pass
Now denies when it cannot see
Rate limit monitoring and request throttling screen
A limiter that could not see was letting everything through.

A rate limiter's own uncertainty should tighten a limit, not remove it

A rate limiter's entire function depends on two things being reliably true: knowing who a request should be attributed to, and knowing accurately how many recent attempts that same attribution has already produced. Whenever either of those two things becomes uncertain — the identifier cannot be determined, or the count itself could not be retrieved — a limiter has, in the moment of genuine uncertainty, LESS basis for confidence that a request is legitimate, not more. A design that responds to exactly that uncertainty by removing the limit entirely gets the direction of the correct response backward: the situations where a limiter knows the least about what it is looking at are precisely the situations where erring toward caution matters most, because they are also the situations most likely to be produced deliberately by whoever is trying to defeat the limiter in the first place.

How the underlying problem shows up before you fix it

A rate-limiting function requires an identifier (an IP address, a user id, a session token) to measure a request against a threshold, and when that identifier cannot be determined at all, the function returns "allowed" rather than treating the absence as a reason to refuse.

A function counting recent attempts against a database or external service uses a fallback value (commonly `result ?? 0`) whenever the underlying query fails — meaning a genuine query FAILURE and a genuine count of ZERO produce the identical downstream behavior, when they represent completely different situations.

The identifier used to attribute a request (commonly a client IP address) is read from a header a client can, in some configurations, set directly on its own outgoing request, rather than exclusively from a header the receiving infrastructure itself sets and that a client cannot override.

Both failure modes are invisible during ordinary, healthy operation — a system with a reliably-present identifier and a reliably-working count query never exercises either fallback path at all, meaning both gaps can persist for a long time with zero visible symptom.

The two situations that trigger a fail-open default (an unidentifiable caller, a failed measurement) are also, structurally, the two situations most likely to correlate with an actual attempt to defeat the limiter — making a fail-open default in exactly these two spots more consequential than a fail-open default chosen elsewhere might be.

Why "we could not measure this" is easy to code as "let it through"

Handling a missing identifier or a failed measurement by explicitly refusing the request requires a deliberate, additional branch of logic — a specific decision that uncertainty should be treated as a reason for caution. Handling the identical situation by falling through to a default that happens to allow the request requires no such deliberate decision at all; it is frequently just what already happens when a piece of code has nothing concrete to act on, or when a fallback value like `?? 0` is used purely for type-safety convenience rather than as a considered security decision. The gap opens specifically because the EASIEST way to write code that tolerates a missing identifier or a failed query, without crashing outright, happens to also be the LEAST safe way to handle the identical situation from a security standpoint — and nothing about writing the easier version produces any visible symptom to signal that a more deliberate choice was actually needed.

How Centriu Loop closed two separate fail-open paths in the same limiter

Centriu Loop's own rate-limiting function checks a request's recent activity against a configured threshold before allowing an action like opening a balance session or recording a movement to proceed. Two separate, genuinely distinct situations inside that function previously defaulted to allowing the request through with no limit applied, confirmed directly from the prior code's own logic.

The first triggered whenever the function could not determine an identifier — typically a caller's IP address — to measure the request against at all. The prior code's own response, in that case, was to return an unconditional `allowed: true`, on the reasoning that with no identifier to attribute the request to, there was nothing meaningful left to check against a threshold. The fix reverses this outright: a missing identifier now returns an explicit, unconditional denial, on the equally direct reasoning that a limiter with no way to attribute a request has, if anything, LESS basis to trust it, not a reason to skip checking it altogether.

The second, entirely separate situation lived inside the function actually counting how many recent attempts had already occurred, most often as a database query. The prior code read the query's own result with a plain `count ?? 0` fallback — meaning that if the underlying query FAILED for any reason (a database hiccup, a network timeout, a genuine outage), the resulting `undefined` was silently converted to a count of exactly zero, a value that is always comfortably under any real threshold. A request arriving during exactly the moment the limiter's own measurement infrastructure was struggling would therefore be treated identically to a request the limiter had genuinely checked and found no concerning recent activity for — the two situations are completely different in what they actually tell you, and the prior code could not distinguish between them at all. The fix wraps the counting call in an explicit error boundary and returns an unconditional denial specifically when that call fails, rather than allowing an untrustworthy zero to stand in for a genuine measurement.

A third, related hardening in the same fix narrows exactly which header the function trusts when determining a caller's own IP address in the first place: the function now reads exclusively from a header Centriu's own reverse proxy sets directly (never forwarded or overridable by a client's own request), falling back only to the first entry of a second, less-trusted header when the primary one is genuinely absent — and returning no identifier at all, rather than an empty string, when neither is present, so that the newly fail-closed identifier-missing path is actually reached correctly rather than silently matching an empty value by accident.

What is actually built today

Centriu Loop's rate limiter explicitly denies a request whenever it cannot determine a caller identifier to measure against, rather than allowing it through by default.

The same limiter explicitly denies a request whenever its own underlying counting query fails, rather than silently treating a query failure as equivalent to a genuine count of zero.

A caller's IP address is read exclusively from a header Centriu's own reverse proxy sets directly, with a client-suppliable header consulted only as a documented, lower-priority fallback — never trusted as the primary source of truth.

The function returns no identifier at all, rather than an empty placeholder value, when neither trusted header is genuinely present — ensuring the fail-closed missing-identifier path is reached correctly rather than bypassed by an accidental empty-string match.

A pluggable backend abstraction allows the underlying counting mechanism to be swapped for a different technology in the future, with the identical fail-closed guarantee required of any implementation — the correctness guarantee lives at the interface, not tied to one specific counting technology.

A bouncer who waves everyone through when the guest list will not load (illustrative framing of the actual confirmed mechanism)

Before the fix, a bouncer whose guest-list terminal froze or crashed responded by waving every arrival straight through, reasoning that with no working list to check, there was nothing left to verify against. After the fix, the identical frozen terminal results in nobody being admitted until it is working again — because a broken check is not the same fact as a genuine, checked "clear," and treating the two as identical defeats the entire purpose of having a check in the first place.

What changes operationally

Centriu Loop's rate limiter now explicitly denies a request whenever it cannot identify the caller or whenever its own underlying counting mechanism fails, closing two separate paths where the prior code had silently defaulted to allowing every request through with no limit applied at all.

When this is not the right fit

This automation covers specifically how Centriu Loop's rate limiter behaves under its own uncertainty — a missing identifier or a failed count. It is a distinct layer from this pillar's separate pages on Centriu Loop's session identity verification and permission default-deny fixes, and from wave 66's separate consumer-portal rate-limiter ATOMICITY fix — that page addresses a race condition in how concurrent requests are COUNTED; this page addresses what the SAME broader limiter does when it cannot count or identify a request at all.

Failing open under uncertainty vs. failing closed under uncertainty

Responding to a missing identifier or a failed measurement by allowing the request through avoids ever blocking a legitimate user during an infrastructure hiccup, which is a genuinely real, if narrow, concern. It does so specifically by removing the limiter's own protection during exactly the moments its own confidence is lowest — which, for a control whose entire purpose is resisting deliberate abuse, is the wrong moment to relax. Explicitly denying under the identical uncertainty accepts a narrow, honest cost (a legitimate request occasionally refused during a genuine infrastructure failure, with a clear, explicit error rather than a silent pass-through) in exchange for never leaving the limiter's own blind spot open to whoever might be causing that exact uncertainty on purpose.

Related systems

Main system: Centriu Loop.

What it does NOT do

  • Does not overlap with wave 66's separate consumer-portal rate-limiter page — that page documents a RACE CONDITION in how concurrent requests were counted (fixed with a database-level advisory lock); this page documents what the SAME broader limiter does when it cannot identify a caller or count attempts AT ALL, a different failure mode entirely.
  • Does not change the actual THRESHOLDS this pillar's separate page on Loop's fraud-monitoring rate limits documents — this fix corrects the limiter's behavior under uncertainty, not the specific numeric limits it enforces once it can measure normally.
  • Does not eliminate the possibility of a legitimate request being refused during a genuine infrastructure failure — it deliberately accepts that narrow, explicit cost in exchange for never leaving the limiter's own uncertainty as an open door.
  • Does not overlap with this pillar's separate pages on Centriu Loop's session identity verification or permission default-deny fixes — all three come from the same broader hardening effort, but each addresses a genuinely different layer of the same access-control pipeline.
  • Does not extend this exact backend-swap architecture to any specific alternative counting technology today — the fix introduces the ABSTRACTION that would allow one to be added later, without itself adopting one.

Security and governance

Centriu Loop's rate limiter now explicitly denies a request whenever it cannot identify the caller or whenever its own underlying counting mechanism fails, and reads a caller's IP address exclusively from a header set directly by Centriu's own reverse proxy. Any personal data referenced in rate-limiting or audit records remains subject to Brazil's LGPD (Law No. 13,709/2018). Full detail on access control lives at /governanca and /iso.

Pricing and contracting

Available by monthly subscription, with tiered plans. Values and terms come from the official pricing table at /precos (Centriu's central source — never restated here).

Frequently asked questions

Could a real customer have been blocked by an infrastructure hiccup because of this fix?

Yes, in principle — the fix deliberately accepts a narrow, explicit cost (an occasional legitimate request refused during a genuine, temporary infrastructure failure) in exchange for closing a much larger gap where the limiter offered zero protection during exactly that same uncertainty.

Is this the same finding as wave 66's consumer-portal rate-limiter page?

No — that page documents a race condition in how CONCURRENT requests were counted, fixed with a database-level lock. This page documents what the same broader limiter does when it cannot identify a caller or count attempts AT ALL, a structurally different failure mode.

Why does a missing IP address matter if most requests have one?

Because the situations where an identifier genuinely cannot be determined are also, structurally, among the situations most likely to correlate with a deliberate attempt to defeat the limiter — making a fail-open default in exactly that spot more consequential than it might first appear.

How is the caller's real IP address determined now?

Exclusively from a header set directly by Centriu's own reverse proxy, which a client cannot override — with a second, client-suppliable header consulted only as a documented, lower-priority fallback, never trusted as the primary source.

How was this specific gap actually found?

Confirmed directly by reading the prior code's own logic (`allowed: true` on a missing identifier; `count ?? 0` on a failed query) as part of a broader security hardening pass covering identity, authorization, and rate-limiting together.

What does Centriu Loop cost?

It is sold by subscription with a published starting price — exact current values are on the central pricing page.

See how Centriu Loop's rate limiter behaves when it cannot see clearly

Reach our commercial team directly, or leave your details below — we'll follow up with guidance for your case.

Sources

  1. Centriu Loop — public product page — Centriu, 2026-07-20 · link(primária)
  2. Centriu Loop — public factsheet (API, JSON) — Centriu, 2026-07-21 · link
  3. Law No. 13,709/2018 — Brazil’s General Data Protection Law (LGPD) — Presidência da República (Brazil), 2018-08-14 · link

Last material update on .

By · AI-assisted production, with human review