Уязвимость тайны голосования при ЭГ: сценарий проверки
После публикации о проблемах с тайной ЭГ с нами через нашего бота связался аккаунт “ДИТ Москва” и попробовал убедить, что у администраторов нет технической возможности записать результат. Господа, вы нас за кого держите?
Мы публикуем подробный сценарий проверки, понятный для технических специалистов, и каждый, кто записан на электронное голосование, но еще не голосовал, может его проверить до 20:00 мск 30 июня. Для этого нужно в браузере открыть консоль разработчика и проследить сетевые запросы.
Заранее поясним ключевую мысль: все ваши запросы можно логировать на сервере (ЭГ использует веб-сервер Nginx) ПОЛНОСТЬЮ, вместе с заголовками и потрохами, и складывать с разных серверов в единое хранилище, например, Elasticsearch, для последующей аналитики.
Поехали:
- Заходим на сайт 2020og.ru и логинимся. В процессе вас перебросит на elec.2020og.ru, login.2020og.ru, потом обратно, и все ответы от этих серверов будут ставить вам cookie laravel_session=abcdef123 (содержимое у каждого из вас будет свое). Это те самые куки для идентификации пользователя, о которых сейчас каждый сайт спрашивает “хотите ли вы их принять”. ДИТ не спрашивает, ДИТ просто их ставит.
- Обратите внимание на запрос при проверке номера телефона на сайте ЭГ, вот он в сокращенном виде
POST https://elec.2020og.ru/common/ajax/confirm/sms/
Cookie: laravel_session=abcdef123
‘type=sms&value=9261234567&voitingId=0′
Внимание, гипотеза (неопровержимая): сервер elec.2020og.ru сохранил этот запрос, содержащий ваш cookie и номер телефона, в логи и отправил в единое хранилище. - Соглашаемся с условиями и получаем бюллетень. Вот как происходит его выдача, тут происходит несколько переадресаций, видимо, это и есть тот самый “анонимайзер”, но спойлер: он ничего не анонимизирует:
POST https://elec.2020og.ru/#complete
Cookie: laravel_session=abcdef123
ответ: HTTP/2 302 Found
location: https://elec.moscow/election/check/ длинная-длинная-цепочка-из-букв-и-цифр=
(на самом деле тут скрыт ваш номер бюллетеня, допустим, 777-ggg-aaa. Как проверить: вставить эту длинную цепочку на сайт https://www.base64decode.org/, раскодировать, потом взять из результата url и еще раз раскодировать. Нас наперстками не проведешь!)
GET https://elec.moscow/election/check/ длинная-длинная-цепочка-из-букв-и-цифр=
ответ: HTTP/2 302 Found
location: https://elec.moscow/election/ 777-ggg-aaa (тот самый номер вашего бюллетеня, уже в открытом виде)
Видите? Сервер (никто не сможет этого опровергнуть) сохранил лог, в котором есть ваш cookie, уже связанный с номером телефона, и номер вашего бюллетеня!
- Ставим галочку и отправляем голос. Ваш голос зашифровывается, создается транзакция и отправляется на сервер, чтобы потом попасть в блокчейн.
POST https://elec.moscow/election/vote
rawStoreBallotTx=транзакция_с_голосом
guid=777-ggg-aaa (номер вашего бюллетеня)
votingId=…
district=…
accountAddressBlock=…
keyVerificationHash=…
rawTxHash=xxxyyyzzz (вашу транзакцию можно будет найти в выгрузке блокчейна на сайте https://observer2020.mos.ru/observer/blocks-list по этому хэшу)
Что же, время собирать камни! После всего этого процесса в логах ДИТ, по неопровержимой гипотезе, хранится:
- связка cookie – номер телефона (laravel_session=abcdef123 и 9261234567)
- связка cookie – номер бюллетеня (laravel_session=abcdef123 и 777-ggg-aaa)
- связка номер бюллетеня – зашифрованный голос (777-ggg-aaa и транзакция_с_голосом, ищется в блокчейне по rawTxHash=xxxyyyzzz)
Дальше сотрудникам ДИТ остается только расшифровать голоса (что будет сделано при подсчете голосов, либо заранее, потому что ключ-то у ДИТ есть, хоть они разделили его на три части, но и себе могли оставить копию про запас), сопоставить их через логи с номерами телефонов и сделать для начальства красивую табличку в экселе. Верите ли вы, что они этого не сделают?
Рекомендуем: ТАСС: тайны голосования при ЭГ нет, и в ходе ЭГ из результатов постфактум исключались бюллетени
У всех желающих осталась пара часов, чтобы проверить наши выводы. А вот у ДИТ времени не осталось, чтобы что-то изменить. Они будут рассказывать, что ничего не хранят, показывать картинки с анонимайзерами и миксерами, но у них нет никакого способа доказать, что их сервера Nginx не пишут логи с настройками “записывать каждый байт запроса и ответа”, и что эти логи потом не будут сведены в таблицу с ФИО и голосами за или против поправок.