You've already forked Arcturus-Morningstar-Extended
mirror of
https://github.com/duckietm/Arcturus-Morningstar-Extended.git
synced 2026-06-19 15:06:19 +00:00
fix(auth): bound session token inputs
This commit is contained in:
+3
-2
@@ -50,6 +50,7 @@ import java.util.Date;
|
||||
@NoAuthMessage
|
||||
public class SecureLoginEvent extends MessageHandler {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(SecureLoginEvent.class);
|
||||
private static final int MAX_SSO_TICKET_LENGTH = 128;
|
||||
|
||||
@Override
|
||||
public int getRatelimit() {
|
||||
@@ -80,9 +81,9 @@ public class SecureLoginEvent extends MessageHandler {
|
||||
return;
|
||||
}
|
||||
|
||||
if (sso.isEmpty()) {
|
||||
if (sso.isEmpty() || sso.length() > MAX_SSO_TICKET_LENGTH) {
|
||||
Emulator.getGameServer().getGameClientManager().disposeClient(this.client);
|
||||
LOGGER.debug("Client is trying to connect without SSO ticket! Closed connection...");
|
||||
LOGGER.debug("Client is trying to connect with missing or invalid SSO ticket! Closed connection...");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -21,6 +21,7 @@ public final class AccessTokenService {
|
||||
private static final SecureRandom RNG = new SecureRandom();
|
||||
private static final Base64.Encoder URL_ENC = Base64.getUrlEncoder().withoutPadding();
|
||||
private static final Base64.Decoder URL_DEC = Base64.getUrlDecoder();
|
||||
private static final int MAX_TOKEN_CHARS = 2048;
|
||||
|
||||
private static volatile String cachedSecret = null;
|
||||
|
||||
@@ -63,7 +64,7 @@ public final class AccessTokenService {
|
||||
}
|
||||
|
||||
public static int verify(String token) {
|
||||
if (token == null || token.isEmpty()) return 0;
|
||||
if (token == null || token.isEmpty() || token.length() > MAX_TOKEN_CHARS) return 0;
|
||||
|
||||
String[] parts = token.split("\\.");
|
||||
if (parts.length != 3) return 0;
|
||||
|
||||
+2
-1
@@ -24,6 +24,7 @@ public final class RememberJwtService {
|
||||
private static final SecureRandom RNG = new SecureRandom();
|
||||
private static final Base64.Encoder URL_ENC = Base64.getUrlEncoder().withoutPadding();
|
||||
private static final Base64.Decoder URL_DEC = Base64.getUrlDecoder();
|
||||
private static final int MAX_TOKEN_CHARS = 2048;
|
||||
|
||||
private static volatile String cachedSecret = null;
|
||||
|
||||
@@ -238,7 +239,7 @@ public final class RememberJwtService {
|
||||
}
|
||||
|
||||
private static ParsedJwt verifyAndParse(String jwt) throws Exception {
|
||||
if (jwt == null || jwt.isEmpty()) throw new IllegalArgumentException("empty");
|
||||
if (jwt == null || jwt.isEmpty() || jwt.length() > MAX_TOKEN_CHARS) throw new IllegalArgumentException("empty");
|
||||
|
||||
String[] parts = jwt.split("\\.");
|
||||
if (parts.length != 3) throw new IllegalArgumentException("not 3 segments");
|
||||
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
package com.eu.habbo.messages.incoming.handshake;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
class SecureLoginGuardContractTest {
|
||||
|
||||
private static String source() throws Exception {
|
||||
return Files.readString(Path.of("src/main/java/com/eu/habbo/messages/incoming/handshake/SecureLoginEvent.java"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void websocketSsoTicketIsLengthBoundedBeforeDatabaseLookup() throws Exception {
|
||||
String source = source();
|
||||
|
||||
int maxConstant = source.indexOf("MAX_SSO_TICKET_LENGTH = 128");
|
||||
int guard = source.indexOf("sso.isEmpty() || sso.length() > MAX_SSO_TICKET_LENGTH");
|
||||
int lookup = source.indexOf("SELECT id FROM users WHERE auth_ticket = ?");
|
||||
|
||||
assertTrue(maxConstant > -1, "Secure login should define the same SSO length cap used by HTTP auth");
|
||||
assertTrue(guard > -1, "Secure login must reject missing or oversized SSO tickets");
|
||||
assertTrue(guard < lookup, "SSO length must be validated before database lookup");
|
||||
}
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
package com.eu.habbo.networking.gameserver.auth;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
class AuthTokenGuardContractTest {
|
||||
|
||||
@Test
|
||||
void accessTokenRejectsOversizedTokensBeforeSplitAndDecode() throws Exception {
|
||||
String source = Files.readString(Path.of("src/main/java/com/eu/habbo/networking/gameserver/auth/AccessTokenService.java"));
|
||||
|
||||
int maxConstant = source.indexOf("MAX_TOKEN_CHARS = 2048");
|
||||
int lengthGuard = source.indexOf("token.length() > MAX_TOKEN_CHARS");
|
||||
int split = source.indexOf("token.split");
|
||||
int decode = source.indexOf("URL_DEC.decode");
|
||||
|
||||
assertTrue(maxConstant > -1, "Access tokens should have a bounded serialized size");
|
||||
assertTrue(lengthGuard > -1, "Access token verification must reject oversized tokens");
|
||||
assertTrue(lengthGuard < split, "Access token length guard must run before split");
|
||||
assertTrue(lengthGuard < decode, "Access token length guard must run before Base64 decode");
|
||||
}
|
||||
|
||||
@Test
|
||||
void rememberTokenRejectsOversizedTokensBeforeSplitAndDecode() throws Exception {
|
||||
String source = Files.readString(Path.of("src/main/java/com/eu/habbo/networking/gameserver/auth/RememberJwtService.java"));
|
||||
|
||||
int maxConstant = source.indexOf("MAX_TOKEN_CHARS = 2048");
|
||||
int lengthGuard = source.indexOf("jwt.length() > MAX_TOKEN_CHARS");
|
||||
int split = source.indexOf("jwt.split");
|
||||
int decode = source.indexOf("URL_DEC.decode");
|
||||
|
||||
assertTrue(maxConstant > -1, "Remember tokens should have a bounded serialized size");
|
||||
assertTrue(lengthGuard > -1, "Remember token verification must reject oversized tokens");
|
||||
assertTrue(lengthGuard < split, "Remember token length guard must run before split");
|
||||
assertTrue(lengthGuard < decode, "Remember token length guard must run before Base64 decode");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user