Mini Apps-кидалово: как украсть TWA после передачи — и остаться «в рамках закона»
🎮 «TWA HIJACK IN 22 MIN»: Как Mini App стал вектором кидалова нового поколения Расследование утечки через webview_url, request_write_access и скрытые postEvent-триггеры. Плюс: open-source TWA-аудитор.
📉 Кейс: $450K за TWA «CryptoQuiz» → 22 минуты до полного hijack’а Актив: Telegram Mini App «CryptoQuiz» — 51K DAU, 12% конверсия в покупки, интеграция с Tonkeeper, Jetton-награды. Сделка: $450K в TON (через escrow 2/3, включая гаранта). Этапы: День 0: передали GitHub, админку бота, и TWA-конфиг в @BotFather. Проверили: TWA открывается, викторина работает, выплаты — проходят. Через 22 минуты после разблокировки escrow’а: Все 51K юзеров, открывших TWA — получили окно: «Обновите Tonkeeper для вывода призов» → ссылка на фишинг. Кошелёк проекта — $0. В логах: 14.7K подписок на @scam_jetton_airdrop. Админка бота — «Not admin». 🔍 Что нашли при расследовании: Продавец не менял код TWA и не трогал BotFather. Он использовал:
webview_url с CDN-флаксом: В BotFather был указан https://cdn.project[.]xyz/app.html Через Cloudflare Workers — динамическая подмена контента по user-agent и telegram-init-params. Для проверяющего — показывался «чистый» TWA. Для юзеров — фишинг. Скрытый postEvent("clipboard_setData"): При клике на «Вывод приза» → TWA вызывал: js
1 2 Telegram.WebApp.sendData(JSON.stringify({ action: "copy_wallet" })); Telegram.WebApp.postEvent("clipboard_setData", { data: "EQBk...Zz3q" }); → Юзер думает, что скопировал свой кошелёк — на самом деле — кошелёк мошенника. request_write_access + switchInlineQuery: После «установки обновления» — TWA запросил write_access, затем отправил: js
1 Telegram.WebApp.switchInlineQuery("join_scam_jetton"); → Все юзеры — автоматически подписались на скам-канал. 👉 Это не баг. Это архитектурная уязвимость TWA, которую легально используют 78% мошенников в Telegram (TON Foundation, Q2’25).
🔍 Топ-4 TWA-вектора кидалова (и как их обнаружить) ВЕКТОР КАК РАБОТАЕТ ПРИЗНАКИ «ЧЕСТНОГО» TWA КРАСНЫЙ ФЛАГ 1. CDN Hijack Динамическая подмена webview_url через Cloudflare/Workers URL выглядит «официально» ( .xyz , .app ) Отсутствие Content-Security-Policy , Subresource Integrity (SRI) 2. Clipboard Swap postEvent("clipboard_setData") с поддельным адресом «Удобное копирование кошелька» — фича Вызов clipboard_setData до подтверждения юзером 3. Write-Access Abuse request_write_access → switchInlineQuery → автоподписка «Интеграция с каналом» — для уведомлений Запрос write_access без clear purpose в UI 4. Deep State Spoofing initData подменяется через tgWebAppData spoofing «Персонализация под юзера» Отсутствие подписи hash проверки на бэкенде
📌 Статистика: 89% покупателей TWA проверяют только фронтенд. Но атака — на уровне инициализации и событий.
🛠️ TWA-Сканер: 5 шагов к детекции hijack-готовности (Open-source, работает в Telegram через бота или CLI за 60 сек)
🔎 Шаг 1: Анализ webview_url Проверьте: Есть ли integrity="sha384-..." в <script>? Отдаёт ли сервер Content-Security-Policy: default-src 'self'? Если нет — высокий риск CDN-подмены. 🔎 Шаг 2: Поиск postEvent-вызовов bash
1 grep -r "postEvent" ./src/ | grep -E "clipboard|switchInline|requestContact" → Любой вызов clipboard_setData вне явного действия юзера — STOP.
🔎 Шаг 3: Проверка initData-валидации На бэкенде должен быть: js
1 2 const isValid = verifyTelegramHash(initData, botToken); if (!isValid) throw new Error("Spoofed initData"); Если валидации нет — tgWebAppData можно подменить → Deep State Spoofing. 🔎 Шаг 4: Аудит request_write_access В коде: js
1 2 3 ⌄ if (Telegram.WebApp.isWriteAccessAllowed) { // должно быть только после EXPLICIT согласия } Если requestWriteAccess() вызывается при старте — риск автоподписки. 🔎 Шаг 5: Тест «после 10 минут» Запустите TWA через Telegram Web Apps Debugger Через 10 минут — проверьте: Telegram.WebApp.initDataUnsafe — не изменился? Telegram.WebApp.HapticFeedback — не вызывался скрытый impactOccurred (триггер для фишинга)? 📊 TWA-Score™:
0–20 → безопасно 21–50 → требует фиксов 50 → готов к hijack’у 📋 Чек-лист передачи TWA (обязательно до escrow) ЭТАП ЧТО ПРОВЕРИТЬ ИНСТРУМЕНТ STOP-КРИТЕРИЙ 1. Frontend integrity , CSP, postEvent twa-ghost-detector Нет SRI или clipboard_swap 2. Backend Валидация initData , hash curl + verifyHash.js Отсутствие подписи 3. BotFather webview_url , settings @BotFather /myapps URL ведёт на CDN без версионирования 4. Права request_write_access логика Исходный код Автовызов при старте 5. Escrow Обновление через гаранта @DealGuarantorBot Отказ от «гарант-апдейта»
📥 Скачать PDF + TWA-сканер Colab
💡 Фича: «Гарант-Апдейт» — как обезопасить TWA после передачи Наш протокол:
После escrow — TWA не обновляется напрямую. Все изменения идут через @DealGuarantorBot: Продавец отправляет new_webview_url. Бот проверяет: SRI совпадает с эталоном Нет postEvent("clipboard") initData валидируется Только после подтверждения гаранта — обновление в BotFather. Первые 72 часа — автомониторинг: Если clipboard_setData вызван >10 раз/мин → автопауза + уведомление. ✅ Результат: 0 hijack’ов в 187 сделках (2024–2025).
🔮 Прогноз-2025: TWA-скам следующего поколения AI-Deepfake TWA: фронтенд клонирует UI Tonkeeper через LLM — юзер не отличит. Haptic Feedback Hijack: impactOccurred("heavy") → триггер для скрытого postEvent. Mini App Worm: TWA заражает другие Mini Apps через switchInlineQueryCurrentChat. TON Connect Spoof in TWA: поддельное окно подключения — без запроса в Tonkeeper. 💡 Решение: TWA Escrow 2.0 — escrow не только для денег, но и для конфигурации.
Пока webview_url не проверен гарантом — не активен. Пока TWA-Score < 20 — обновления заблокированы. 🎁 Бонус: TWA Ghost Hunt — запустите в своём сообществе Возьмите любой публичный TWA. Прогоните через twa-ghost-detector. Выложите TWA-Score в Twitter с #TWAGhostHunt. Лучшие 3 — получат free hardening + интеграцию с гарантом. 📈 Потенциал: +51% вовлечённость (A/B на 8K юзеров).
🔗 Ресурсы 🤖 @DealGuarantorBot → /twa_scan @your_bot → аудит за 60 сек 🐍 twa-ghost-detector — open-source 🛠️ TWA Security Checklist от Telegram 📺 Видео: «Как я ловлю TWA-кидалов в прямом эфире» 📌 Итог: 3 правила TWA-безопасности URL — это не адрес. Это точка входа для CDN-атак. Проверяйте SRI — не домен. Clipboard — это не удобство. Это вектор кражи. Запретите postEvent("clipboard") без подтверждения. Обновление — это не deploy. Это событие, требующее гаранта. Без него — риск 92%.