fix(modtool): bound staff supplied messages

This commit is contained in:
simoleo89
2026-06-15 19:54:34 +02:00
parent 36a06647f0
commit 8ba9132e7e
11 changed files with 115 additions and 11 deletions
@@ -11,10 +11,17 @@ public class ModToolAlertEvent extends MessageHandler {
@Override
public void handle() throws Exception {
if (this.client.getHabbo().hasPermission(Permission.ACC_SUPPORTTOOL)) {
Habbo alertedUser = Emulator.getGameEnvironment().getHabboManager().getHabbo(this.packet.readInt());
int userId = this.packet.readInt();
String message = ModToolInputGuard.normalize(this.packet.readString());
if (!ModToolInputGuard.isSafeMessage(message)) {
return;
}
Habbo alertedUser = Emulator.getGameEnvironment().getHabboManager().getHabbo(userId);
if (alertedUser != null)
Emulator.getGameEnvironment().getModToolManager().alert(this.client.getHabbo(), alertedUser, this.packet.readString(), SupportUserAlertedReason.ALERT);
Emulator.getGameEnvironment().getModToolManager().alert(this.client.getHabbo(), alertedUser, message, SupportUserAlertedReason.ALERT);
} else {
ScripterManager.scripterDetected(this.client, Emulator.getTexts().getValue("scripter.warning.modtools.kick").replace("%username%", this.client.getHabbo().getHabboInfo().getUsername()));
}
@@ -0,0 +1,16 @@
package com.eu.habbo.messages.incoming.modtool;
final class ModToolInputGuard {
static final int MAX_MESSAGE_LENGTH = 1000;
private ModToolInputGuard() {
}
static String normalize(String value) {
return value == null ? "" : value.trim();
}
static boolean isSafeMessage(String value) {
return value != null && !value.isEmpty() && value.length() <= MAX_MESSAGE_LENGTH;
}
}
@@ -18,6 +18,13 @@ public class ModToolKickEvent extends MessageHandler {
return;
}
Emulator.getGameEnvironment().getModToolManager().kick(this.client.getHabbo(), Emulator.getGameEnvironment().getHabboManager().getHabbo(this.packet.readInt()), this.packet.readString());
int userId = this.packet.readInt();
String message = ModToolInputGuard.normalize(this.packet.readString());
if (!ModToolInputGuard.isSafeMessage(message)) {
return;
}
Emulator.getGameEnvironment().getModToolManager().kick(this.client.getHabbo(), Emulator.getGameEnvironment().getHabboManager().getHabbo(userId), message);
}
}
@@ -11,10 +11,15 @@ public class ModToolRoomAlertEvent extends MessageHandler {
public void handle() throws Exception {
if (this.client.getHabbo().hasPermission(Permission.ACC_SUPPORTTOOL)) {
this.packet.readInt();
String message = ModToolInputGuard.normalize(this.packet.readString());
if (!ModToolInputGuard.isSafeMessage(message)) {
return;
}
Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom();
if (room != null) {
room.alert(this.packet.readString());
room.alert(message);
}
} else {
ScripterManager.scripterDetected(this.client, Emulator.getTexts().getValue("scripter.warning.roomalert").replace("%username%", this.client.getHabbo().getHabboInfo().getUsername()));
@@ -21,9 +21,13 @@ public class ModToolSanctionAlertEvent extends MessageHandler {
@Override
public void handle() throws Exception {
int userId = this.packet.readInt();
String message = this.packet.readString();
String message = ModToolInputGuard.normalize(this.packet.readString());
int cfhTopic = this.packet.readInt();
if (!ModToolInputGuard.isSafeMessage(message)) {
return;
}
if (this.client.getHabbo().hasPermission(Permission.ACC_SUPPORTTOOL)) {
Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(userId);
@@ -30,13 +30,17 @@ public class ModToolSanctionBanEvent extends MessageHandler {
@Override
public void handle() throws Exception {
int userId = this.packet.readInt();
String message = this.packet.readString();
String message = ModToolInputGuard.normalize(this.packet.readString());
int cfhTopic = this.packet.readInt();
int banType = this.packet.readInt();
this.packet.readBoolean();
int duration = 0;
if (!ModToolInputGuard.isSafeMessage(message)) {
return;
}
switch (banType) {
case BAN_18_HOURS:
duration = 18 * 60 * 60;
@@ -79,4 +83,4 @@ public class ModToolSanctionBanEvent extends MessageHandler {
ScripterManager.scripterDetected(this.client, Emulator.getTexts().getValue("scripter.warning.modtools.ban").replace("%username%", this.client.getHabbo().getHabboInfo().getUsername()));
}
}
}
}
@@ -23,9 +23,13 @@ public class ModToolSanctionMuteEvent extends MessageHandler {
@Override
public void handle() throws Exception {
int userId = this.packet.readInt();
String message = this.packet.readString();
String message = ModToolInputGuard.normalize(this.packet.readString());
int cfhTopic = this.packet.readInt();
if (!ModToolInputGuard.isSafeMessage(message)) {
return;
}
if (this.client.getHabbo().hasPermission(Permission.ACC_SUPPORTTOOL)) {
Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(userId);
@@ -21,10 +21,14 @@ public class ModToolSanctionTradeLockEvent extends MessageHandler {
@Override
public void handle() throws Exception {
int userId = this.packet.readInt();
String message = this.packet.readString();
String message = ModToolInputGuard.normalize(this.packet.readString());
int duration = this.packet.readInt();
int cfhTopic = this.packet.readInt();
if (!ModToolInputGuard.isSafeMessage(message)) {
return;
}
if (this.client.getHabbo().hasPermission(Permission.ACC_SUPPORTTOOL)) {
Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(userId);
@@ -16,10 +16,17 @@ public class ModToolWarnEvent extends MessageHandler {
@Override
public void handle() throws Exception {
if (this.client.getHabbo().hasPermission(Permission.ACC_SUPPORTTOOL)) {
Habbo alertedUser = Emulator.getGameEnvironment().getHabboManager().getHabbo(this.packet.readInt());
int userId = this.packet.readInt();
String message = ModToolInputGuard.normalize(this.packet.readString());
if (!ModToolInputGuard.isSafeMessage(message)) {
return;
}
Habbo alertedUser = Emulator.getGameEnvironment().getHabboManager().getHabbo(userId);
if (alertedUser != null)
Emulator.getGameEnvironment().getModToolManager().alert(this.client.getHabbo(), alertedUser, this.packet.readString(), SupportUserAlertedReason.CAUTION);
Emulator.getGameEnvironment().getModToolManager().alert(this.client.getHabbo(), alertedUser, message, SupportUserAlertedReason.CAUTION);
} else {
ScripterManager.scripterDetected(this.client, Emulator.getTexts().getValue("scripter.warning.modtools.kick").replace("%username%", this.client.getHabbo().getHabboInfo().getUsername()));
}
@@ -0,0 +1,23 @@
package com.eu.habbo.messages.incoming.modtool;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
class ModToolInputGuardTest {
@Test
void normalizesNullableMessages() {
assertEquals("", ModToolInputGuard.normalize(null));
assertEquals("warn", ModToolInputGuard.normalize(" warn "));
}
@Test
void staffMessagesMustBeNonEmptyAndBounded() {
assertFalse(ModToolInputGuard.isSafeMessage(null));
assertFalse(ModToolInputGuard.isSafeMessage(""));
assertTrue(ModToolInputGuard.isSafeMessage("a".repeat(ModToolInputGuard.MAX_MESSAGE_LENGTH)));
assertFalse(ModToolInputGuard.isSafeMessage("a".repeat(ModToolInputGuard.MAX_MESSAGE_LENGTH + 1)));
}
}
@@ -86,4 +86,27 @@ class ModToolPermissionContractTest {
assertTrue(defaultSanction.contains("if (issue == null)"),
"default sanctions must tolerate stale or missing ticket ids");
}
@Test
void staffSuppliedModToolMessagesAreBounded() throws Exception {
Path base = Path.of("src/main/java/com/eu/habbo/messages/incoming/modtool");
for (String handler : List.of(
"ModToolAlertEvent.java",
"ModToolWarnEvent.java",
"ModToolKickEvent.java",
"ModToolRoomAlertEvent.java",
"ModToolSanctionAlertEvent.java",
"ModToolSanctionBanEvent.java",
"ModToolSanctionMuteEvent.java",
"ModToolSanctionTradeLockEvent.java"
)) {
String source = Files.readString(base.resolve(handler));
assertTrue(source.contains("ModToolInputGuard.normalize"),
handler + " must normalize staff-supplied text before use");
assertTrue(source.contains("ModToolInputGuard.isSafeMessage"),
handler + " must reject empty or oversized staff-supplied text");
}
}
}