24 марта 2022 г.

Схема Мячина. Об утечке Яндекса и других

    Это копия сообщения из моего linked.in, потому что там неудобно читать.

    Итак, хотя никто этого не просил, предлагаю свой вариант, как не допустить утечки, подобной #Yandex. На заметку не только #DeliveryClub, но вообще всем (вот такой я самонадеянный и с распухшим эго).

    В чём проблема не только Яндекса, но 99,99999% фирм (и снова привет, кое-какой менеджер из кое-какой фирмы, ага) - они полагаются на то, что доступ к БД строго ограничен, а сотрудники - доверенные лица. Это, прошу прощения, говно. Никогда, никогда, НИКОГДА нельзя рассчитывать, что даже самый проверенный человек не станет "предателем".

    Вообще, у вас ещё после Сноудена в голове должно было щёлкнуть, что эта схема просто нерабочая. При том, что я поддерживаю Сноудена и то, что он сделал, но будь я его работодателем, у меня была бы иная позиция.

    Итак, нарушитель - это сотрудник компании с доступом к БД. От этого нарушителя и отталкиваемся. Предлагаемый мной подход будет защищать от этой модели, но не защитит от нарушитеЛЕЙ, которые целенаправленно будут менять работу сервера и принимать MR друг друга в мастер, когда цель этих мёрджей будет в сливе данных.

Что требуется

  1. Курьер должен знать номер заказа, количество позиций заказа и адрес доставки + комментарии к доставке. Но не имени, ни телефона
  2. Сервер должен знать телефон курьера, номер и точный состав заказа и ваш телефон. Но ни вашего адреса, ни имени.

    Уже здесь видно, что имя не нужно никому, не так ли? Это первый очевидный косяк - зачем вы вообще хранили имя?!

  3. Администратор БД не должен получить доступ к номеру телефона, но должен получить к номеру заказа и данным курьера

Как это сделать

    Это общий подход и его можно модифицировать в деталях. Также я не оговариваю алгоритмы шифрования, длины ключей и всё такое. Это ПОДХОД. Но оговорю, что все ключи - уникальны для одного заказа, а не один на все заказы и что ключи хранятся отдельно от данных (впрочем, это очевидно).

  1. Клиентское приложение сообщает, что будет формировать заказ
  2. Сервер присылает клиентскому приложению свой ключ
  3. Клиентское приложение в ответ даёт свой ключ серверу
  4. Оба они генерируют общий секрет
  5. Клиентское приложение отправляет заказ на сервер, зашифрованный общим секретом и в ответ получает номер заказа

    На этом этапе сервер знает состав заказа и его номер

  6. Сервер связывается с рестораном и создаёт с ним пару ключей с общим секретом 
  7. Сервер сообщает ресторану состав заказа, пошифрованный на этом секрете, а также номер заказа 
  8. Сервер связывается с курьером и создаёт с ним пару ключей с общим секретом 
  9. Сервер сообщает курьеру номер заказа, ресторан и количество позиций заказа, но не его состав

    На этом этапе ресторан знает номер заказа и его состав. При чём нумерация заказов для ресторана лучше пусть вообще не совпадает с номером клиента. Тогда утечка связки "номер у пользователя" и "состав" не позволит связать этот заказ с рестораном для типовых заказов. Потому что "бургер и кола" - слишком общий заказ


    Курьер знает номер заказа, с точки зрения ресторана, дабы его забрать. И знает количество позиций, но не состав заказа. Для него это просто коробки


  10. И курьер, и ресторан, оба сообщают серверу, что заказ забрали
  11. Сервер сообщает приложению пользователя о том, что курьер в пути
  12. Приложения клиента и курьера, оба, отправляют на сервер ключи и тот пересылает их им обоим. Сам сервер, разумеется, ключей не сохраняет.

    Здесь первое узкое место и здесь возможен ТОЛЬКО целенаправленный саботаж - все разработчики сервиса должны будут друг друга покрывать, дабы сделать мёрдж в мастер, который заставит сервак сохранять ключи


  13. Приложения курьера и клиента создают общий секрет
  14. Клиент сообщает серверу свой физический адрес, пошифрованный секретом из пункта выше
  15. Сервер не может его прочитать, т.к. у него нет секрета курьера и клиента. Он просто перешлёт некий блоб курьеру
  16. Приложение курьера дешифрует данные и может прочитать адрес
  17. Клиент, на общем с сервером секрете, шифрует номер телефона и сообщает его серверу
  18. Для общения в чате с клиентом курьер использует их общий секрет. Сервер не знает об их переписке. В случае разбирательств клинет покажет скриншоты. А если всё хорошо, нефига читать чужие сообщения
  19. Для телефонного звонка курьер звонит из приложения, а сервер проксирует звонок через себя. Верно и обратное - клиент к курьеру

    Итак, сейчас сервер знает номер телефона, номер заказа, состав заказа, телефон курьера и телефон клиента. Не знает имени и адреса.


    Курьер знает адрес, номер заказа, количество позиций заказа. Не знает состав заказа, имени и телефона клиента.


    Клиент знает номер заказа, состав. Не знает имени курьера, телефона курьера. Курьеры тоже люди и нефига их ФИО раскидывать туда-сюда.

  20. Курьер доставляет заказ и сообщает об этом серверу 
  21. Курьерское приложение уничтожает секрет пользователя и его адрес (который прочесть без секрета всё равно нельзя). Больше курьер не может общаться с пользователем никак. Любая связь только через Яндекс. И ЭТО ОЧЕНЬ ВАЖНО. Потому что таксисты любят писать после выполнения заказа девушкам. А иногда любят угрожать 
  22. Клиент подтверждает получение заказа. Его приложение уничтожает секрет с курьером 
  23. Сервер получает 2 подтверждения доставки 
  24. Сервер уничтожает адрес пользователя и его номер телефона. Но сохраняет состав заказа и общий секрет на некоторый срок. Этот срок - это срок возможного обжалования заказа. Скажем, 24 часа

   На этом этапе у курьера нет ничего о пользователе и заказе. Наверное, только номер, чтобы, если что, ТП Яндекса могла сказать "была жалоба по заказу 210". У курьера остаётся общий с сервером секрет, чтобы номер заказа и количество позиций можно было считывать в установленные 24 часа

    У сервера есть общий с курьером секрет и секрет общий с клиентом. Остаётся инфа о составе заказа и его номер, остаётся инфа о связи с рестораном. Это нужно для разбирательств ошибок. У сервера нет адреса клиента, имени и телефона

    У клиента остаётся состав заказа, номер и общий с сервером ключ. Теперь жалобы он подписывает этим же ключом, дабы сервер мог удостовериться, что это реально тот же заказ, ведь он и жалоба на одном ключе.

    Через 24 часа у клиента вытирается общий секрет. Он продолжает видеть свой заказ и номер, но уже не может пожаловаться.

    Сервер также вытирает общий ключ с клиентом, а также уничтожает оставшиеся данные с заказом. Ну или не уничтожает, потому что это БД и дорого. Прочесть их нельзя из-за вытертого ключа.

Конечный результат

  1. Никто никогда не знает имени
  2. Курьер никогда не знает телефон и не может писать в личку после выполнения работы
  3. Админ не может сдамить данные за полгода на сервере
  4. Сиюминутный SELECT * FROM DOSTAVKA содержит минимальную информацию и каждый заказ пошифрован на своём ключе, который живёт в другой таблице. Это будет просто шифрованный мусор

    Если Яндекс, или Деливери, или кто угодно возьмёт в работу эту схему (не в этом виде, а подгонит под свои запросы, конечно), назовите её "схема Мячина". Я про это никогда не узнаю, никто у вас не будет знает, кто такой Мячин. Но я буду про себя думать, что кому-то когда-то смог помочь.