Валидация данных
Правило номер один в веб-разработке: никогда не доверяй клиенту. В мини-приложениях MAX это правило работает на 110% — потому что данные, которые приходят с клиента через Bridge, может подделать кто угодно. Давай разберём, как защититься.
Почему нужна валидация?
Когда мини-приложение инициализируется, Bridge
получает
initData — набор данных о пользователе
и сессии. Эти данные приходят с клиента, а значит,
злоумышленник может:
-
Подменить
user.idи выдать себя за другого пользователя - Изменить параметры сессии и получить несанкционированный доступ
- Отправить на твой сервер поддельный запрос от имени мини-приложения
initData на сервере — ты открываешь
дыру, через которую можно украсть данные
пользователей, накрутить игровую валюту или сломать
всю бизнес-логику. Это не теоретическая угроза — я
видел, как взламывали ботов других разработчиков
именно через непроверенные данные.
Как работает initData?
При запуске мини-приложения MAX передаёт в Bridge
строку
initData. Эта строка содержит
зашифрованные данные, подписанные секретным ключом
MAX. Твоя задача — передать эту строку на сервер и
проверить подпись.
// Клиент: получаем initData и передаём на сервер
const bridge = new MaxBridge();
bridge.init().then(data => {
// Отправляем initData на свой сервер для проверки
await fetch('/api/validate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
initData: data.initData
})
});
});
Проверка на сервере
На сервере ты должен проверить подпись
initData, используя секретный ключ
твоего бота. MAX подписывает данные алгоритмом
HMAC-SHA256. Общий принцип:
- Получи
initDataс клиента -
Извлеки из неё поле
hash(подпись) - Вычисли HMAC-SHA256 от оставшихся данных с ключом бота
- Сравни вычисленный хеш с переданным
- Если совпадает — данные подлинные, можно доверять
crypto,
на Python — hmac. Конкретный код и
формат initData описан в
API-документации —
не дублирую, чтобы не устареть.
Что проверять после валидации?
После того как подпись подтверждена, ты можешь доверять данным. Проверь дополнительно:
-
Срок действия —
initDataсодержит полеauth_date. Если данные старше 24 часов — отклони запрос - ID пользователя — убедись, что пользователь существует в твоей базе и не заблокирован
- Права доступа — проверь, что у пользователя есть доступ к запрашиваемому функционалу
// Псевдокод серверной валидации
async function validateInitData(initData: string) {
const parsed = parseQueryString(initData);
const hash = parsed.hash;
delete parsed.hash;
const expectedHash = hmacSha256(
sortKeys(parsed), 'секретный_ключ_бота'
);
if (hash !== expectedHash) {
throw new Error('Подпись недействительна');
}
// Проверяем срок
const age = Date.now() - parsed.auth_date * 1000;
if (age > 86400000) {
throw new Error('Данные устарели');
}
return parsed;
}
Безопасность в двух словах
Главный принцип безопасности мини-приложений MAX:
-
Всегда проверяй
initDataна сервере - Никогда не храни секретные ключи на клиенте
- Все критичные операции (списание валюты, изменение данных) делай только через серверный API
- Логируй подозрительную активность
initData — это не опциональная фича, а
обязательный минимум. Настрой её до того, как
откроешь мини-приложение пользователям.