diff --git a/bans-core/src/main/java/space/arim/libertybans/core/env/AbstractEnvEnforcer.java b/bans-core/src/main/java/space/arim/libertybans/core/env/AbstractEnvEnforcer.java index 4b08306a6..73f9476af 100644 --- a/bans-core/src/main/java/space/arim/libertybans/core/env/AbstractEnvEnforcer.java +++ b/bans-core/src/main/java/space/arim/libertybans/core/env/AbstractEnvEnforcer.java @@ -98,10 +98,10 @@ private CentralisedFuture sendToThoseWithPermissionNoPrefix(String permiss public final void sendPluginMessage(P player, PluginMessage pluginMessage, D data) { if (!sendPluginMessageIfListening(player, pluginMessage, data)) { logger.error( - "Attempted to send plugin message to {}, but the appropriate channel is not accepted. " + - "This suggests you enabled use-plugin-messaging in the config.yml, but the player " + - "is not connected to a network. Please address this critical security flaw immediately. " + - "It leaves your server vulnerable to clients spoofing the plugin messaging channel", + "Attempted to send plugin message to {}, but it could not be sent. " + + "This suggests you enabled 'use-plugin-messaging' but are not using a network. " + + "Please address this critical security flaw immediately. " + + "It leaves your server vulnerable to clients spoofing the plugin messaging channel.", player ); } diff --git a/bans-env/spigot/src/main/java/space/arim/libertybans/env/spigot/SpigotMessageChannel.java b/bans-env/spigot/src/main/java/space/arim/libertybans/env/spigot/SpigotMessageChannel.java index 883286fa3..c2e566d40 100644 --- a/bans-env/spigot/src/main/java/space/arim/libertybans/env/spigot/SpigotMessageChannel.java +++ b/bans-env/spigot/src/main/java/space/arim/libertybans/env/spigot/SpigotMessageChannel.java @@ -53,13 +53,21 @@ public void unregister() { boolean sendPluginMessage(Player player, PluginMessage pluginMessage, D data) { boolean listened = player.getListeningPluginChannels().contains(BUNGEE_CHANNEL); - if (listened) { + // + // 1. The backend server must NOT be in online mode + // 2. The channel must NOT be listened on, strangely enough + // Explanation: getListeningPluginChannels() should never return BungeeCord, because it is a special channel + // Therefore, if this channel IS listened on, that suggests the client is trying to spoof it. + // The anti-spoof check is used for pre-1.13 clients which may register legacy channel names. + // + boolean canSend = !plugin.getServer().getOnlineMode() && !listened; + if (canSend) { player.sendPluginMessage( plugin, BUNGEE_CHANNEL, new PluginMessageAsBytes<>(pluginMessage).generateBytes(data) ); } - return listened; + return canSend; } @Override diff --git a/bans-env/sponge/src/main/java/space/arim/libertybans/env/sponge/SpongeMessageChannel.java b/bans-env/sponge/src/main/java/space/arim/libertybans/env/sponge/SpongeMessageChannel.java index 3149bfe53..f3c55ba92 100644 --- a/bans-env/sponge/src/main/java/space/arim/libertybans/env/sponge/SpongeMessageChannel.java +++ b/bans-env/sponge/src/main/java/space/arim/libertybans/env/sponge/SpongeMessageChannel.java @@ -56,7 +56,12 @@ private RawPlayDataChannel channel() { boolean sendPluginMessage(ServerPlayer player, PluginMessage pluginMessage, D data) { var channel = channel(); boolean supported = channel.isSupportedBy(player.connection()); - if (supported) { + // + // 1. The backend server must NOT be in online mode + // 2. The channel must be supported + // + boolean canSend = !game.server().isOnlineModeEnabled() && supported; + if (canSend) { channel.sendTo(player, (buffer) -> { pluginMessage.writeTo(data, new ChannelBufAsOutput(buffer)); }).exceptionally((ex) -> { @@ -64,7 +69,7 @@ boolean sendPluginMessage(ServerPlayer player, PluginMessage pluginMes return null; }); } - return supported; + return canSend; } @Override