Validate registration ids for new accounts

This commit is contained in:
ravi-signal
2023-06-06 10:08:54 -05:00
committed by GitHub
parent 099932ae68
commit 2b266c7beb
6 changed files with 80 additions and 2 deletions

View File

@@ -131,6 +131,7 @@ public class AccountController {
private static final String ACCOUNT_VERIFY_COUNTER_NAME = name(AccountController.class, "verify");
private static final String CAPTCHA_ATTEMPT_COUNTER_NAME = name(AccountController.class, "captcha");
private static final String CHALLENGE_ISSUED_COUNTER_NAME = name(AccountController.class, "challengeIssued");
private static final String INVALID_ACCOUNT_ATTRS_COUNTER_NAME = name(AccountController.class, "invalidAccountAttrs");
private static final DistributionSummary REREGISTRATION_IDLE_DAYS_DISTRIBUTION = DistributionSummary
.builder(name(AccountController.class, "reregistrationIdleDays"))
@@ -391,6 +392,11 @@ public class AccountController {
rateLimiters.getVerifyLimiter().validate(number);
if (!AccountsManager.validNewAccountAttributes(accountAttributes)) {
Metrics.counter(INVALID_ACCOUNT_ATTRS_COUNTER_NAME, Tags.of(UserAgentTagUtil.getPlatformTag(userAgent))).increment();
throw new WebApplicationException(Response.status(422, "account attributes invalid").build());
}
// Note that successful verification depends on being able to find a stored verification code for the given number.
// We check that numbers are normalized before we store verification codes, and so don't need to re-assert
// normalization here.

View File

@@ -69,6 +69,7 @@ public class RegistrationController {
private static final String REGION_CODE_TAG_NAME = "regionCode";
private static final String VERIFICATION_TYPE_TAG_NAME = "verification";
private static final String ACCOUNT_ACTIVATED_TAG_NAME = "accountActivated";
private static final String INVALID_ACCOUNT_ATTRS_COUNTER_NAME = name(RegistrationController.class, "invalidAccountAttrs");
private final AccountsManager accounts;
private final PhoneVerificationTokenManager phoneVerificationTokenManager;
@@ -118,6 +119,10 @@ public class RegistrationController {
final String password = authorizationHeader.getPassword();
RateLimiter.adaptLegacyException(() -> rateLimiters.getRegistrationLimiter().validate(number));
if (!AccountsManager.validNewAccountAttributes(registrationRequest.accountAttributes())) {
Metrics.counter(INVALID_ACCOUNT_ATTRS_COUNTER_NAME, Tags.of(UserAgentTagUtil.getPlatformTag(userAgent))).increment();
throw new WebApplicationException(Response.status(422, "account attributes invalid").build());
}
final PhoneVerificationRequest.VerificationType verificationType = phoneVerificationTokenManager.verify(number,
registrationRequest);

View File

@@ -28,6 +28,7 @@ import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.OptionalInt;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicReference;
@@ -330,6 +331,21 @@ public class AccountsManager {
return updatedAccount.get();
}
public static boolean validNewAccountAttributes(final AccountAttributes accountAttributes) {
if (!validRegistrationId(accountAttributes.getRegistrationId())) {
return false;
}
final OptionalInt pniRegistrationId = accountAttributes.getPhoneNumberIdentityRegistrationId();
if (pniRegistrationId.isPresent() && !validRegistrationId(pniRegistrationId.getAsInt())) {
return false;
}
return true;
}
private static boolean validRegistrationId(int registrationId) {
return registrationId > 0 && registrationId <= Device.MAX_REGISTRATION_ID;
}
public Account updatePniKeys(final Account account,
final byte[] pniIdentityKey,
final Map<Long, SignedPreKey> pniSignedPreKeys,

View File

@@ -20,6 +20,7 @@ public class Device {
public static final long MASTER_ID = 1;
public static final int MAXIMUM_DEVICE_ID = 256;
public static final int MAX_REGISTRATION_ID = 0x3FFF;
public static final List<Long> ALL_POSSIBLE_DEVICE_IDS = LongStream.range(1, MAXIMUM_DEVICE_ID).boxed().collect(Collectors.toList());
@JsonProperty