Skip to content

Add a permission-based packet limiter bypass defaulting to operators - #14340

Closed
BA-Capple wants to merge 1 commit into
PaperMC:mainfrom
BA-Capple:feat/packet-limiter-bypass
Closed

BA-Capple wants to merge 1 commit into
PaperMC:mainfrom
BA-Capple:feat/packet-limiter-bypass

Conversation

@BA-Capple

Copy link
Copy Markdown

Add a permission-based packet limiter bypass defaulting to operators

Motivation

When an OP or trusted player performs an authorized paste with a schematic tool, the client may send many packets in a short time, triggering Paper's all-packets packet limiter and causing a disconnect. Raising the global threshold is not appropriate because it would weaken packet-rate protection for every connection. Limiting the exemption to explicitly trusted players keeps existing protections for ordinary connections and reduces the opportunity for unauthorized players to abuse the exemption.

Behavior

Implemented through the permission node paper.packet-limiter.bypass.

  • Defaults to PermissionDefault.OP, so it is granted to operators by default.
  • Not operator-only: non-OP players can be explicitly granted, and operators can be explicitly denied.
  • Uses the effective Bukkit permission rather than an isOp() check.
  • Bypass only covers Paper's packet limiter all-packets limit and packet-specific overrides.
  • No new config options; the feature itself has no external permission-plugin dependency.

Implementation

  • Permission state is read on the server thread; the network thread only reads a per-PLAY-listener volatile cached boolean.
  • The cache is refreshed each listener tick; new PLAY listeners initialize to false (fail-closed).
  • LOGIN, CONFIG, HANDSHAKE, and STATUS do not receive bypass.
  • When a player disconnects, is removed from the world, or switches from PLAY to CONFIG, the old PLAY listener's bypass is permanently disabled.

Security Boundaries

This bypass only targets Paper's packet limiter and does not remove other protections. server.properties rate-limit, codec/schema validation, command/chat/recipe spam limiters, connection throttling, and other protections still run under their own rules where applicable. Skipped decoder exceptions still increment receivedPackets, so the independent server.properties rate-limit can still observe that traffic. PLAY state is not an additional authentication mechanism; being granted the permission does not mean unlimited traffic is guaranteed to be safe.

Validation

Local source patch rebuild and application, NormalTestSuite, full Gradle build, and Paperclip build completed and passed. All 13 feature-specific tests passed:

  • ConnectionPacketLimiterTest: 4 tests
  • ConnectionPacketLimiterIntegrationTest: 6 tests
  • PaperPermissionsTest: 3 tests

All with failures=0, errors=0, skipped=0.

Coverage includes real channelRead0() for all-packets KICK, packet override DROP/KICK, and differences with and without bypass, as well as full listener tick() for permission grant, revocation, and fail-closed behavior after disconnect. gitleaks scanned the single feature commit in origin/main..HEAD and reported no findings. Codex and an Astra subagent read-only reviews found no confirmed runtime defects.

Live testing

Paperclip started successfully on Java 25 with Minecraft 26.3. The test server bound to 127.0.0.1:25566 with online-mode=true.

For a stable, repeatable comparison, all-packets.max-packet-rate was temporarily lowered from 500 to 20, with the action left as KICK. To avoid interference from the separate command spam limiter, test-only spam exclusions were configured for /fill and /setblock.

  • As a non-OP, the test player was explicitly disconnected with Kicked for exceeding packet rate limit when pasting with a real client and the actual schematic tool.
  • After granting the same player OP and waiting for the permission cache to refresh, the same kind of paste was performed; a large number of /fill, /setblock, and /summon commands were processed successfully and the player stayed online.
  • The console then confirmed via list that the player was still online.

This experiment validated the default OP permission path and used a controlled threshold, not the default configuration. Explicit non-OP grant and explicit OP deny are currently covered by automated permission tests and have not yet been tested live with LuckPerms.

Not yet performed: LuckPerms integration, Folia compatibility testing, or production deployment testing.

AI Involvement Disclosure

Codex assisted with codebase investigation, implementation, test writing, and local verification. Codex and an Astra subagent performed read-only code and security reviews. The submitter is responsible for the final commit and maintainer communication.

@BA-Capple
BA-Capple requested a review from a team as a code owner October 3, 2026 08:19
@NonSwag

NonSwag commented Oct 3, 2026

Copy link
Copy Markdown
Contributor

I get why this is something one would want, but personally I think this is something plugins should take care of.
I am pretty certain that there are plugins that add compatibility for such operations in a much more effective manner.

@BA-Capple

BA-Capple commented Oct 3, 2026 •

Copy link
Copy Markdown
Author

I agree that tool-specific compatibility is often better handled by plugins, especially if they can avoid generating the packet burst in the first place.
This PR is intended to solve a slightly different problem: providing a per-player trust boundary for Paper's own all-packets limiter. The limiter runs in Connection before normal Bukkit/Paper plugin-level packet handling, so ordinary plugin handling cannot simply cancel the resulting kick afterwards.
I found several plugins that provide permission-based bypasses for their own packet limiters, but I haven't found one that provides a per-player bypass for Paper's native all-packets limiter itself. If you know of one, I'd be interested in comparing its approach.

@Warriorrrr

Copy link
Copy Markdown
Member

I don't think there should be any permission to bypass the packet limiter, and also think this is the wrong approach to fix the problem you're were describing. Allowing the packet limiter to be bypassed by ops to be able to spam command packets to paste a schematic is too niche a use case and isn't worth doing 20 permission checks every tick for every player.

The need to bypass it means you're already doing something weird, and that there are probably better solutions. Using a plugin like worldedit to paste the schematic in is what we mainly recommend to people that come in and ask about this in paper-help on the discord. This'll be much faster and more accurate than your current approach, there even seem to be a couple of projects aimed at converting a litematic into a schematic file that worldedit understands if you're working with one of those.

If that fails, you can also paste the schematic in a singleplayer world, move the world files to a paper server & move it to your main server using world edit. Or finally, either temporarily raise/remove the packet limit if your server is a private one, or configure your mod to not exceed the packet limit.

tl;dr: not necessary, better alternatives exist

@BA-Capple BA-Capple closed this Oct 4, 2026
@BA-Capple
BA-Capple deleted the feat/packet-limiter-bypass branch October 4, 2026 11:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Closed

Development

Successfully merging this pull request may close these issues.

3 participants