Возникла идея сделать один мелкий сайтик с юзерами, а там регистрация. В силу того, что я не понял, зачем мне для регистрации просить email, да ещё гонять трафик и снюхиваться со всякими email-серверами, то емейла/телефона при регистрации не будет.


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


Поэтому возникла идея поставить капчу позже, а сначала попросить юзера доказать, что он выдержал некий proof-of-time алгоритм (и возможно proof-of-memory с микрокодом типа как в RandomX, но похрен). Proof-of-time - это, короче, пруф того, что ты регался не менее 5 секунд. Реализуется как 5 обменов с браузерным JS, между которыми не может быть менее секунды, причём сервер не утруждает себя хранением состояния, чтобы выдерживать SYN-flood-атаки (запустили регистрацию 100500 раз и свалили).


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


На экране юзера такая регистрация будет выглядеть как прогресс-бар, который тупо доходит до 100% за 5 секунд.


Простейший вариант - тупо зашифровать своим секретным ключом AES128 строчку вида «<256-bit-random-salt>» и на входе расшифровывать обратно, сверяя timestamp. Но может есть чё попроще?


А ещё были такие идеи на тему proof-of-memory: генерим на сервере 512 байт данных и запоминаем, а юзеру отправляем 1 МБ, где в случайных местах замешаны эти 512 байт. Потом посылаем юзеру 10 запросов в рандомные места этого 1 МБ куска, ответы на большинство из которых нас не волнуют. Пара запросов, которые попадают в «наши данные» мы проверяем, но юзер вынужден помнить весь 1 МБ, не зная где среди них лежат наши данные. Потом я прочитал про RandomX и понял, что это содомия, а нормальные чуваки просто генерят какой-то псевдомашинный код на тему перемещения блоков в памяти, который (код) юзер физически состоянии исполнить только имея, скажем, 4 гига оперативы - короче надо ещё про это почитать!









 






URL записи