#3189: Improve username validation

This commit is contained in:
Outfluencer 2021-09-25 08:07:58 +10:00 committed by md_5
parent 1823f86dbb
commit 3008d7ef2f
No known key found for this signature in database
GPG Key ID: E8E901AC7C617C11
4 changed files with 57 additions and 5 deletions

View File

@ -7,6 +7,7 @@ import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Locale;
import java.util.UUID;
/**
@ -68,6 +69,17 @@ public class Util
return String.format( "0x%02X", i );
}
/**
* Formats an char as a unicode value.
*
* @param c the character to format
* @return the unicode representation of the character
*/
public static String unicode(char c)
{
return "\\u" + String.format( "%04x", (int) c ).toUpperCase( Locale.ROOT );
}
/**
* Constructs a pretty one line version of a {@link Throwable}. Useful for
* debugging.

View File

@ -62,6 +62,7 @@ import net.md_5.bungee.protocol.packet.PingPacket;
import net.md_5.bungee.protocol.packet.PluginMessage;
import net.md_5.bungee.protocol.packet.StatusRequest;
import net.md_5.bungee.protocol.packet.StatusResponse;
import net.md_5.bungee.util.AllowedCharacters;
import net.md_5.bungee.util.BoundedArrayList;
import net.md_5.bungee.util.BufUtil;
import net.md_5.bungee.util.QuietException;
@ -352,13 +353,13 @@ public class InitialHandler extends PacketHandler implements PendingConnection
public void handle(LoginRequest loginRequest) throws Exception
{
Preconditions.checkState( thisState == State.USERNAME, "Not expecting USERNAME" );
this.loginRequest = loginRequest;
if ( getName().contains( " " ) )
if ( !AllowedCharacters.isValidName( loginRequest.getData(), onlineMode ) )
{
disconnect( bungee.getTranslation( "name_invalid" ) );
return;
}
this.loginRequest = loginRequest;
int limit = BungeeCord.getInstance().config.getPlayerLimit();
if ( limit > 0 && bungee.getOnlineCount() >= limit )

View File

@ -32,6 +32,7 @@ import net.md_5.bungee.protocol.packet.PlayerListItem;
import net.md_5.bungee.protocol.packet.PluginMessage;
import net.md_5.bungee.protocol.packet.TabCompleteRequest;
import net.md_5.bungee.protocol.packet.TabCompleteResponse;
import net.md_5.bungee.util.AllowedCharacters;
public class UpstreamBridge extends PacketHandler
{
@ -147,10 +148,9 @@ public class UpstreamBridge extends PacketHandler
for ( int index = 0, length = chat.getMessage().length(); index < length; index++ )
{
char c = chat.getMessage().charAt( index );
// Section symbol, control sequences, and delete
if ( c == '\u00A7' || c < ' ' || c == 127 )
if ( !AllowedCharacters.isChatAllowedCharacter( c ) )
{
con.disconnect( bungee.getTranslation( "illegal_chat_characters", String.format( "\\u%04x", (int) c ) ) );
con.disconnect( bungee.getTranslation( "illegal_chat_characters", Util.unicode( c ) ) );
throw CancelSendSignal.INSTANCE;
}
}

View File

@ -0,0 +1,39 @@
package net.md_5.bungee.util;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class AllowedCharacters
{
public static boolean isChatAllowedCharacter(char character)
{
// Section symbols, control sequences, and deletes are not allowed
return character != '\u00A7' && character >= ' ' && character != 127;
}
private static boolean isNameAllowedCharacter(char c, boolean onlineMode)
{
if ( onlineMode )
{
return ( c >= 'a' && c <= 'z' ) || ( c >= '0' && c <= '9' ) || ( c >= 'A' && c <= 'Z' ) || c == '_';
} else
{
// Don't allow spaces, Yaml config doesn't support them
return isChatAllowedCharacter( c ) && c != ' ';
}
}
public static boolean isValidName(String name, boolean onlineMode)
{
for ( int index = 0, len = name.length(); index < len; index++ )
{
if ( !isNameAllowedCharacter( name.charAt( index ), onlineMode ) )
{
return false;
}
}
return true;
}
}