@Throttle guards its rate-limit logic with if (player?.clientID). On RageMP the first player to connect has clientID: 0, which is falsy, so the entire rate-limit block is skipped.
There is no error and no warning. The handler runs unthrottled. The first player effectively has no rate limit on any @Throttle-decorated method until they reconnect with a non-zero ID.
This is the same root cause as the @Guard bug #61 but the impact is a silent security regression rather than a visible failure.
Steps to reproduce
-
Define a throttled handler:
@Command('spam')
@Throttle(1, 5000) // 1 call per 5s
spamCommand(player: Player) {
player.send('ran')
}
-
Start a fresh RageMP server.
-
Join as the first player (clientID === 0).
-
Spam /spam repeatedly.
Expected
Calls beyond the limit are blocked with a SecurityError.
Actual
Every call goes through. The rate limiter is never consulted.
@Throttleguards its rate-limit logic withif (player?.clientID). On RageMP the first player to connect hasclientID: 0, which is falsy, so the entire rate-limit block is skipped.There is no error and no warning. The handler runs unthrottled. The first player effectively has no rate limit on any
@Throttle-decorated method until they reconnect with a non-zero ID.This is the same root cause as the
@Guardbug #61 but the impact is a silent security regression rather than a visible failure.Steps to reproduce
Define a throttled handler:
Start a fresh RageMP server.
Join as the first player (
clientID === 0).Spam
/spamrepeatedly.Expected
Calls beyond the limit are blocked with a
SecurityError.Actual
Every call goes through. The rate limiter is never consulted.