diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/LoginSessionHandler.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/LoginSessionHandler.java index 15ee1b3bf..f8e5ff630 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/LoginSessionHandler.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/LoginSessionHandler.java @@ -43,6 +43,7 @@ import java.util.Arrays; import java.util.Optional; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ThreadLocalRandom; +import java.util.regex.Pattern; import net.kyori.text.Component; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -53,6 +54,7 @@ public class LoginSessionHandler implements MinecraftSessionHandler { private static final Logger logger = LogManager.getLogger(LoginSessionHandler.class); private static final String MOJANG_HASJOINED_URL = "https://sessionserver.mojang.com/session/minecraft/hasJoined?username=%s&serverId=%s&ip=%s"; + private static final Pattern VALID_MINECRAFT_USERNAME = Pattern.compile("^[a-zA-Z0-9_]{1,16}$"); private final VelocityServer server; private final MinecraftConnection inbound; @@ -71,6 +73,21 @@ public class LoginSessionHandler implements MinecraftSessionHandler { @Override public boolean handle(ServerLogin packet) { + // Disallow logins from invalid usernames. + if (server.getConfiguration().isOnlineMode()) { + // In online-mode, follow Mojang's username rules. + if (!VALID_MINECRAFT_USERNAME.matcher(packet.getUsername()).matches()) { + inbound.closeWith(Disconnect.create(VelocityMessages.INVALID_USERNAME)); + return true; + } + } else { + // Offline mode accepts any username, as long as we don't exceed 16 characters. + if (packet.getUsername().length() > 16) { + inbound.closeWith(Disconnect.create(VelocityMessages.INVALID_USERNAME)); + return true; + } + } + this.login = packet; if (inbound.getProtocolVersion().compareTo(MINECRAFT_1_13) >= 0) { playerInfoId = ThreadLocalRandom.current().nextInt(); diff --git a/proxy/src/main/java/com/velocitypowered/proxy/util/VelocityMessages.java b/proxy/src/main/java/com/velocitypowered/proxy/util/VelocityMessages.java index 621003e4c..a6022b0b3 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/util/VelocityMessages.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/util/VelocityMessages.java @@ -14,6 +14,8 @@ public class VelocityMessages { .of("No available servers", TextColor.RED); public static final Component ALREADY_CONNECTED = TextComponent .of("You are already connected to this proxy!", TextColor.RED); + public static final Component INVALID_USERNAME = TextComponent + .of("Trying to login with invalid username", TextColor.RED); private VelocityMessages() { throw new AssertionError();