From 6108a32631ee5f481cb5dc9a793733302b0d8d36 Mon Sep 17 00:00:00 2001 From: Greyson Parrelli Date: Mon, 25 Nov 2019 11:04:45 -0500 Subject: [PATCH] Prevent reading UUIDs from external contacts. --- .../contacts/sync/DirectoryHelperV1.java | 9 +++++++-- .../securesms/recipients/Recipient.java | 16 ++++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/org/thoughtcrime/securesms/contacts/sync/DirectoryHelperV1.java b/src/org/thoughtcrime/securesms/contacts/sync/DirectoryHelperV1.java index 4a4313db74..994827541d 100644 --- a/src/org/thoughtcrime/securesms/contacts/sync/DirectoryHelperV1.java +++ b/src/org/thoughtcrime/securesms/contacts/sync/DirectoryHelperV1.java @@ -14,6 +14,7 @@ import android.provider.ContactsContract; import android.text.TextUtils; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.annotation.WorkerThread; import com.annimon.stream.Collectors; @@ -42,6 +43,7 @@ import org.thoughtcrime.securesms.util.concurrent.SignalExecutors; import org.whispersystems.libsignal.util.guava.Optional; import org.whispersystems.signalservice.api.SignalServiceAccountManager; import org.whispersystems.signalservice.api.push.ContactTokenDetails; +import org.whispersystems.signalservice.api.util.UuidUtil; import java.io.IOException; import java.util.Calendar; @@ -140,8 +142,8 @@ class DirectoryHelperV1 { while (cursor != null && cursor.moveToNext()) { String number = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.NUMBER)); - if (!TextUtils.isEmpty(number)) { - RecipientId recipientId = Recipient.external(context, number).getId(); + if (isValidContactNumber(number)) { + RecipientId recipientId = Recipient.externalContact(context, number).getId(); String displayName = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)); String contactPhotoUri = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.PHOTO_URI)); String contactLabel = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.LABEL)); @@ -303,6 +305,9 @@ class DirectoryHelperV1 { }); } + private static boolean isValidContactNumber(@Nullable String number) { + return !TextUtils.isEmpty(number) && !UuidUtil.isUuid(number); + } private static class DirectoryResult { diff --git a/src/org/thoughtcrime/securesms/recipients/Recipient.java b/src/org/thoughtcrime/securesms/recipients/Recipient.java index e5717dc43b..79e8f73ae4 100644 --- a/src/org/thoughtcrime/securesms/recipients/Recipient.java +++ b/src/org/thoughtcrime/securesms/recipients/Recipient.java @@ -186,6 +186,22 @@ public class Recipient { } } + /** + * A safety wrapper around {@link #external(Context, String)} for when you know you're using an + * identifier for a system contact, and therefore always want to prevent interpreting it as a + * UUID. This will crash if given a UUID. + * + * (This may seem strange, but apparently some devices are returning valid UUIDs for contacts) + */ + @WorkerThread + public static @NonNull Recipient externalContact(@NonNull Context context, @NonNull String identifier) { + if (UuidUtil.isUuid(identifier)) { + throw new UuidRecipientError(); + } else { + return external(context, identifier); + } + } + /** * Returns a fully-populated {@link Recipient} based off of a string identifier, creating one in * the database if necessary. The identifier may be a uuid, phone number, email,