Как мы потеряли Minecraft-сервер: пароль от базы лежал в лаунчере

Это было в 2015 году. У нас был Minecraft-сервер, онлайн держался около 50 человек постоянно. Технической частью занимался не я — к проекту присоединился начинающий программист, он написал лаунчер и магазин. Я отвечал за сайт и продвижение.

Потом у него начались проблемы с учёбой, он пропал, и за сервером стало некому следить. А через какое-то время сервер взломали. На нём внезапно появилась куча левых админов, а потом кто-то просто снёс базу данных. Целиком.

Восстанавливать было нечего. Проект закрыли.

Что именно мы сделали не так

В лаунчере хранились логин и пароль от базы данных. От той же базы, на которой работали и сайт, и сервер. Лаунчер подключался к ней напрямую — проверял, есть ли у игрока покупки, подтягивал данные аккаунта, что-то там ещё.

Кто-то вытащил эти данные из кода лаунчера. Всё.

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

Почему это ломается всегда

Лаунчер — это программа, которую скачивает игрок. Она лежит у него на диске. Он её владелец, а не вы.

Всё, что находится внутри клиентской программы, считайте опубликованным. Не «его сложно достать», не «оно зашифровано», а именно опубликованным. Java-лаунчер разбирается декомпилятором за пару минут, и это не хакерский инструмент, это обычная утилита разработчика.

Обфускация тут не спасает, и вот почему: в тот момент, когда лаунчер подключается к базе, пароль обязан быть в открытом виде. Можно сколько угодно шифровать строку в коде — программа сама её расшифрует, потому что иначе не сможет подключиться. Достаточно поймать её в этот момент. Или вообще не лезть в код: подключение к базе идёт по сети, и его видно снифером.

Ровно та же логика — про ключи API в мобильных приложениях, про пароли в JavaScript на сайте, про токены в конфигах, которые «всё равно никто не откроет». Клиент не может хранить секреты. Никакие.

Про левых админов

Отдельно понятно, откуда взялись администраторы, которых мы не выдавали.

Права в таких сборках лежат в таблице базы данных. Если у тебя есть доступ к базе, тебе не нужно ничего взламывать в игре — ты просто дописываешь себе строчку. Игровой сервер послушно раздаёт права, потому что он верит своей базе. Это его работа.

Так что «взломали сервер» — неточная формулировка. Сервер работал штатно, ему предъявили корректные данные.

Что надо было сделать

Между лаунчером и базой должен стоять посредник — простой HTTP-API на сайте.

Клиент не знает ни адреса базы, ни логина, ни пароля. Он знает только адрес вроде https://сайт/api/profile и свой токен, полученный после входа. Дальше он спрашивает у API: «что купил этот игрок?» — и получает ответ. Всё общение с базой происходит на сервере, куда игрок не имеет доступа в принципе.

Если токен у кого-то утёк — страдает один аккаунт, а не весь проект. Токен отзывается за секунду.

Второе — учётные записи базы с минимальными правами. Даже когда доступ к базе нужен, отдельная учётка для сайта не должна уметь DROP TABLE. У нас, судя по итогу, была одна учётка на всё и с полными правами.

Третье, и самое обидное: бэкапы. Взлом не убил бы проект, если бы у нас была копия базы хотя бы недельной давности. Мы потеряли не из-за того, что нас взломали, а из-за того, что нечего было восстановить. Разница огромная. Первое — неприятный день, второе — конец проекта.

Чем это аукнулось потом

Я тогда решил, что просто не повезло, и переключился на другое. По-настоящему я понял этот урок сильно позже, уже на работе, когда стал отвечать за инфраструктуру, где падение сервиса — это не «жаль ребят из клана», а остановившийся бизнес.

Резервные копии, снапшоты виртуалок, возможность откатиться за минуты вместо того, чтобы собирать систему заново по кускам. Всё, чего у нас не было в 2015-м.

Так что урок оказался полезным. Просто дорогим — мы заплатили за него целым проектом.

Если интересно, что там было: наша группа сохранилась — vk.ru/minecraft5game.

Добавить комментарий

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.