You've already forked Arcturus-Morningstar-Extended
mirror of
https://github.com/duckietm/Arcturus-Morningstar-Extended.git
synced 2026-06-20 07:26:18 +00:00
fix(rcon): bound alert payloads
This commit is contained in:
@@ -6,6 +6,9 @@ import com.eu.habbo.messages.ServerMessage;
|
|||||||
import com.eu.habbo.messages.outgoing.generic.alerts.GenericAlertComposer;
|
import com.eu.habbo.messages.outgoing.generic.alerts.GenericAlertComposer;
|
||||||
import com.eu.habbo.messages.outgoing.generic.alerts.StaffAlertWithLinkComposer;
|
import com.eu.habbo.messages.outgoing.generic.alerts.StaffAlertWithLinkComposer;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import jakarta.validation.constraints.Pattern;
|
||||||
|
import jakarta.validation.constraints.Size;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@@ -37,9 +40,13 @@ public class HotelAlert extends RCONMessage<HotelAlert.JSONHotelAlert> {
|
|||||||
|
|
||||||
static class JSONHotelAlert {
|
static class JSONHotelAlert {
|
||||||
|
|
||||||
|
@NotBlank(message = "invalid message")
|
||||||
|
@Size(max = 4096, message = "invalid message")
|
||||||
public String message;
|
public String message;
|
||||||
|
|
||||||
|
|
||||||
|
@Size(max = 2048, message = "invalid url")
|
||||||
|
@Pattern(regexp = "^$|https?://.+", message = "invalid url")
|
||||||
public String url = "";
|
public String url = "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,10 @@ import com.eu.habbo.habbohotel.users.Habbo;
|
|||||||
import com.eu.habbo.messages.outgoing.generic.alerts.BubbleAlertComposer;
|
import com.eu.habbo.messages.outgoing.generic.alerts.BubbleAlertComposer;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import gnu.trove.map.hash.THashMap;
|
import gnu.trove.map.hash.THashMap;
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import jakarta.validation.constraints.Pattern;
|
||||||
|
import jakarta.validation.constraints.Positive;
|
||||||
|
import jakarta.validation.constraints.Size;
|
||||||
|
|
||||||
public class ImageAlertUser extends RCONMessage<ImageAlertUser.JSON> {
|
public class ImageAlertUser extends RCONMessage<ImageAlertUser.JSON> {
|
||||||
public ImageAlertUser() {
|
public ImageAlertUser() {
|
||||||
@@ -51,27 +55,39 @@ public class ImageAlertUser extends RCONMessage<ImageAlertUser.JSON> {
|
|||||||
|
|
||||||
static class JSON {
|
static class JSON {
|
||||||
|
|
||||||
|
@Positive(message = "invalid user")
|
||||||
public int user_id;
|
public int user_id;
|
||||||
|
|
||||||
|
|
||||||
|
@NotBlank(message = "invalid bubble")
|
||||||
|
@Size(max = 64, message = "invalid bubble")
|
||||||
|
@Pattern(regexp = "[A-Za-z0-9_.-]+", message = "invalid bubble")
|
||||||
public String bubble_key = "";
|
public String bubble_key = "";
|
||||||
|
|
||||||
|
|
||||||
|
@Size(max = 4096, message = "invalid message")
|
||||||
public String message = "";
|
public String message = "";
|
||||||
|
|
||||||
|
|
||||||
|
@Size(max = 2048, message = "invalid url")
|
||||||
|
@Pattern(regexp = "^$|https?://.+", message = "invalid url")
|
||||||
public String url = "";
|
public String url = "";
|
||||||
|
|
||||||
|
|
||||||
|
@Size(max = 256, message = "invalid url title")
|
||||||
public String url_message = "";
|
public String url_message = "";
|
||||||
|
|
||||||
|
|
||||||
|
@Size(max = 256, message = "invalid title")
|
||||||
public String title = "";
|
public String title = "";
|
||||||
|
|
||||||
|
|
||||||
|
@Size(max = 32, message = "invalid display")
|
||||||
|
@Pattern(regexp = "^$|[A-Za-z0-9_.-]+", message = "invalid display")
|
||||||
public String display_type = "";
|
public String display_type = "";
|
||||||
|
|
||||||
|
|
||||||
|
@Size(max = 2048, message = "invalid image")
|
||||||
public String image = "";
|
public String image = "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6,6 +6,9 @@ import com.eu.habbo.messages.ServerMessage;
|
|||||||
import com.eu.habbo.messages.outgoing.generic.alerts.BubbleAlertComposer;
|
import com.eu.habbo.messages.outgoing.generic.alerts.BubbleAlertComposer;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import gnu.trove.map.hash.THashMap;
|
import gnu.trove.map.hash.THashMap;
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import jakarta.validation.constraints.Pattern;
|
||||||
|
import jakarta.validation.constraints.Size;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@@ -55,24 +58,35 @@ public class ImageHotelAlert extends RCONMessage<ImageHotelAlert.JSON> {
|
|||||||
|
|
||||||
static class JSON {
|
static class JSON {
|
||||||
|
|
||||||
|
@NotBlank(message = "invalid bubble")
|
||||||
|
@Size(max = 64, message = "invalid bubble")
|
||||||
|
@Pattern(regexp = "[A-Za-z0-9_.-]+", message = "invalid bubble")
|
||||||
public String bubble_key = "";
|
public String bubble_key = "";
|
||||||
|
|
||||||
|
|
||||||
|
@Size(max = 4096, message = "invalid message")
|
||||||
public String message = "";
|
public String message = "";
|
||||||
|
|
||||||
|
|
||||||
|
@Size(max = 2048, message = "invalid url")
|
||||||
|
@Pattern(regexp = "^$|https?://.+", message = "invalid url")
|
||||||
public String url = "";
|
public String url = "";
|
||||||
|
|
||||||
|
|
||||||
|
@Size(max = 256, message = "invalid url title")
|
||||||
public String url_message = "";
|
public String url_message = "";
|
||||||
|
|
||||||
|
|
||||||
|
@Size(max = 256, message = "invalid title")
|
||||||
public String title = "";
|
public String title = "";
|
||||||
|
|
||||||
|
|
||||||
|
@Size(max = 32, message = "invalid display")
|
||||||
|
@Pattern(regexp = "^$|[A-Za-z0-9_.-]+", message = "invalid display")
|
||||||
public String display_type = "";
|
public String display_type = "";
|
||||||
|
|
||||||
|
|
||||||
|
@Size(max = 2048, message = "invalid image")
|
||||||
public String image = "";
|
public String image = "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
package com.eu.habbo.messages.rcon;
|
||||||
|
|
||||||
|
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 AlertPayloadGuardTest {
|
||||||
|
@Test
|
||||||
|
void hotelAlertPayloadIsBoundedAndUrlValidated() throws Exception {
|
||||||
|
String source = Files.readString(Path.of("src/main/java/com/eu/habbo/messages/rcon/HotelAlert.java"));
|
||||||
|
|
||||||
|
assertTrue(source.contains("@NotBlank(message = \"invalid message\")"),
|
||||||
|
"HotelAlert must reject blank global alerts");
|
||||||
|
assertTrue(source.contains("@Size(max = 4096"),
|
||||||
|
"HotelAlert must bound global alert text");
|
||||||
|
assertTrue(source.contains("@Pattern(regexp = \"^$|https?://.+\""),
|
||||||
|
"HotelAlert must reject non-http alert links");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void imageHotelAlertPayloadIsBounded() throws Exception {
|
||||||
|
String source = Files.readString(Path.of("src/main/java/com/eu/habbo/messages/rcon/ImageHotelAlert.java"));
|
||||||
|
|
||||||
|
assertTrue(source.contains("@NotBlank(message = \"invalid bubble\")"),
|
||||||
|
"ImageHotelAlert must require a bubble key");
|
||||||
|
assertTrue(source.contains("@Pattern(regexp = \"[A-Za-z0-9_.-]+\""),
|
||||||
|
"ImageHotelAlert bubble keys must be constrained to safe token characters");
|
||||||
|
assertTrue(source.contains("@Size(max = 2048"),
|
||||||
|
"ImageHotelAlert URL/image fields must be bounded");
|
||||||
|
assertTrue(source.contains("@Pattern(regexp = \"^$|https?://.+\""),
|
||||||
|
"ImageHotelAlert must reject non-http links");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void imageUserAlertPayloadIsBoundedAndTargetsValidUsers() throws Exception {
|
||||||
|
String source = Files.readString(Path.of("src/main/java/com/eu/habbo/messages/rcon/ImageAlertUser.java"));
|
||||||
|
|
||||||
|
assertTrue(source.contains("@Positive(message = \"invalid user\")"),
|
||||||
|
"ImageAlertUser must reject invalid target users before execution");
|
||||||
|
assertTrue(source.contains("@NotBlank(message = \"invalid bubble\")"),
|
||||||
|
"ImageAlertUser must require a bubble key");
|
||||||
|
assertTrue(source.contains("@Size(max = 4096"),
|
||||||
|
"ImageAlertUser must bound alert text");
|
||||||
|
assertTrue(source.contains("@Pattern(regexp = \"^$|https?://.+\""),
|
||||||
|
"ImageAlertUser must reject non-http links");
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user