Validate message timestamps
This commit is contained in:
parent
16a50935ea
commit
8af939d320
|
@ -209,6 +209,11 @@ public class MessageController {
|
|||
@VisibleForTesting
|
||||
static final long MAX_MESSAGE_SIZE = DataSize.kibibytes(256).toBytes();
|
||||
|
||||
// The Signal desktop client (really, JavaScript in general) can handle message timestamps at most 100,000,000 days
|
||||
// past the epoch; please see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date#the_epoch_timestamps_and_invalid_date
|
||||
// for additional details.
|
||||
public static final long MAX_TIMESTAMP = 86_400_000L * 100_000_000L;
|
||||
|
||||
private static final Duration NOTIFY_FOR_REMAINING_MESSAGES_DELAY = Duration.ofMinutes(1);
|
||||
|
||||
public MessageController(
|
||||
|
@ -554,6 +559,10 @@ public class MessageController {
|
|||
|
||||
@Context ContainerRequestContext context) throws RateLimitExceededException {
|
||||
|
||||
if (timestamp < 0 || timestamp > MAX_TIMESTAMP) {
|
||||
throw new BadRequestException("Illegal timestamp");
|
||||
}
|
||||
|
||||
final SpamChecker.SpamCheckResult spamCheck = spamChecker.checkForSpam(context, Optional.empty(), Optional.empty(), Optional.empty());
|
||||
if (spamCheck instanceof final SpamChecker.Spam spam) {
|
||||
return spam.response();
|
||||
|
|
|
@ -9,6 +9,8 @@ import static com.codahale.metrics.MetricRegistry.name;
|
|||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
import jakarta.validation.constraints.Max;
|
||||
import jakarta.validation.constraints.PositiveOrZero;
|
||||
import org.whispersystems.textsecuregcm.controllers.MessageController;
|
||||
|
||||
import io.micrometer.core.instrument.Counter;
|
||||
|
@ -19,8 +21,17 @@ import jakarta.validation.Valid;
|
|||
import jakarta.validation.constraints.AssertTrue;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
|
||||
public record IncomingMessageList(@NotNull @Valid List<@NotNull IncomingMessage> messages,
|
||||
boolean online, boolean urgent, long timestamp) {
|
||||
public record IncomingMessageList(@NotNull
|
||||
@Valid
|
||||
List<@NotNull @Valid IncomingMessage> messages,
|
||||
|
||||
boolean online,
|
||||
|
||||
boolean urgent,
|
||||
|
||||
@PositiveOrZero
|
||||
@Max(MessageController.MAX_TIMESTAMP)
|
||||
long timestamp) {
|
||||
|
||||
private static final Counter REJECT_DUPLICATE_RECIPIENT_COUNTER =
|
||||
Metrics.counter(
|
||||
|
|
|
@ -1095,7 +1095,7 @@ class MessageControllerTest {
|
|||
.request()
|
||||
.header(HeaderUtils.UNIDENTIFIED_ACCESS_KEY, Base64.getEncoder().encodeToString(UNIDENTIFIED_ACCESS_BYTES))
|
||||
.put(Entity.entity(new IncomingMessageList(
|
||||
List.of(new IncomingMessage(1, (byte) 1, 1, new String(contentBytes))), false, true,
|
||||
List.of(new IncomingMessage(1, (byte) 1, 1, Base64.getEncoder().encodeToString(contentBytes))), false, true,
|
||||
System.currentTimeMillis()),
|
||||
MediaType.APPLICATION_JSON_TYPE))) {
|
||||
|
||||
|
@ -1599,7 +1599,7 @@ class MessageControllerTest {
|
|||
|
||||
@ParameterizedTest
|
||||
@CsvSource({
|
||||
"-1, 422",
|
||||
"-1, 400",
|
||||
"0, 200",
|
||||
"1, 200",
|
||||
"8640000000000000, 200",
|
||||
|
|
Loading…
Reference in New Issue