Как страницы угадывают открытые DevTools: разница размеров окна, замер паузы debugger и геттеры консоли. Почему они ошибаются и почему это слабый сигнал.
Некоторые страницы странно меняются, стоит нажать F12: содержимое пропадает, вкладка зависает или появляется полоса «Выполнение приостановлено в отладчике», которая не уходит. Магии здесь нет. Скрипт на странице угадывает, что DevTools открыты, по побочным эффектам, которые браузер не может скрыть от JavaScript страницы. В этом материале — три классических приёма, способы, которыми каждый из них ошибается, и причины, по которым ни один не годится как надёжный сигнал.
Главное
- Ни один браузер не сообщает странице «DevTools открыты». Любой детектор — это эвристика, которая выводит это из побочного эффекта: изменившегося размера окна, приостановленного скрипта или иного поведения вызова консоли.
- Разница размеров окна сравнивает
outerWidthиinnerWidth(и высоты). Закреплённые DevTools отнимают место у вьюпорта, и разница растёт. Откреплённые DevTools разницу не меняют. - Оператор
debuggerостанавливает выполнение только при открытых DevTools, поэтому скрипт может замерить паузу или вызывать оператор в цикле, «наказывая» открытую панель. Именно поэтому некоторые страницы зависают. - Геттеры консоли срабатывают, когда консоль форматирует объект. Это тот же класс приёмов, что и утечка сериализации CDP, и поведение зависит от версии браузера.
- Это слабый сигнал. Разработчики, сотрудники поддержки и любопытные пользователи открывают DevTools на законных основаниях, а масштаб или боковые панели дают ложные срабатывания, поэтому серьёзные системы используют его как вход с малым весом.
Зачем сайтам искать открытые DevTools
Цель почти никогда не в том, чтобы поймать читающего страницу человека. Типичные мотивы:
- Защита от скрапинга. Просмотр сетевых запросов или DOM часто первый шаг к парсингу, и сайт может повысить оценку риска.
- Защита клиентского кода. Логику платного доступа, обфусцированные скрипты и код верификации рекламы проще изучать с подключённым отладчиком.
- Оценка мошенничества и злоупотреблений. Открытый инспектор — ещё один слабый вход рядом с более сильными в стеке обнаружения ботов.
Обратите внимание на рамки: речь о человеке, который открыл DevTools вручную. Фреймворки автоматизации, управляющие браузером через протокол, на котором работают DevTools, — другая задача; о ней в материалах про обнаружение автоматизации через CDP и обнаружение headless-браузеров.
Приём 1: разница размеров окна
Браузер отдаёт два размера. window.outerWidth — ширина всего окна браузера вместе с панелями инструментов и боковыми панелями, а window.innerWidth — ширина вьюпорта страницы. Обычно ширины различаются лишь на несколько пикселей рамки окна, а высоты — на высоту панели вкладок и панели инструментов, поэтому порог в детекторах ставят заметно выше. Если закрепить DevTools сбоку или снизу, вьюпорт сжимается, а внешнее окно остаётся прежним, и разница подскакивает на сотни пикселей.
const threshold = 160; // px
const widthGap = window.outerWidth - window.innerWidth > threshold;
const heightGap = window.outerHeight - window.innerHeight > threshold;
const looksOpen = widthGap || heightGap;
Это дёшево, пассивно и не требует разрешений, поэтому проверка встречается чаще всего. Но она предсказуемо ломается:
- Откреплённые DevTools открываются в отдельном окне, вьюпорт страницы не меняется, и ничего не обнаруживается.
- Боковые панели браузера (списки для чтения, ИИ-помощники, вертикальные вкладки) тоже сжимают вьюпорт и могут выглядеть как закреплённый инспектор.
- Масштаб и масштабирование дисплея на некоторых платформах меняют соотношение двух значений, и разница появляется без всяких DevTools.
- Мобильные и встроенные представления часто отдают странные или равные значения, и там проверка бессмысленна.
Те же два значения участвуют и в проверках экрана и окна в фингерпринтинге по разрешению экрана.
Приём 2: оператор debugger
Оператор debugger вызывает доступные средства отладки, а если их нет — ничего не делает. При закрытых DevTools это пустая операция в доли миллисекунды. При открытых (и активных точках останова) выполнение останавливается на этой строке, пока пользователь не продолжит.
Это даёт странице два применения. Первое — замер времени: взять метку, выполнить debugger, взять вторую и считать паузу дольше нескольких десятков миллисекунд признаком «подключён отладчик».
const t0 = performance.now();
debugger;
const paused = performance.now() - t0 > 100; // human-scale pause
Второе — ловушка: вызывать debugger из таймера или цикла, так что после каждого продолжения он снова останавливает выполнение. Поэтому при открытых DevTools страница может казаться зависшей или постоянно открывать панель Sources. Браузер позволяет отключить точки останова или пропустить скрипт, так что это скорее досада, чем преграда, а пользователь, который хотел лишь посмотреть консоль, получает худшую страницу.
Как это ломается: пауза вкладки может быть следствием спящего ноутбука, перегруженного устройства или фоновой вкладки с троттлингом — всё это растягивает замер; а при отключённых точках останова оператор снова ничего не делает.
Приём 3: геттеры консоли
Когда DevTools открыты, вывод объекта заставляет консоль строить его превью. Страница может вывести объект со свойством-геттером и посмотреть, выполнится ли геттер.
let opened = false;
const probe = new Error();
Object.defineProperty(probe, "stack", {
get() { opened = true; return ""; }
});
console.log(probe);
Срабатывает ли геттер, зависит от браузера, его версии и от того, какая панель консоли показана; движки время от времени меняют это поведение, так что проверка, работавшая в прошлом году, сейчас может молчать. Родственный механизм Chromium, когда подключённый клиент автоматизации заставляет каждый вызов console.* сериализовать аргументы, разобран в руководстве по обнаружению CDP; здесь важно помнить, что сработавший геттер может означать и «человек открыл консоль», и «подключён клиент протокола», а страница не отличит одно от другого.
Почему это слабый сигнал
Каждый из методов — догадка, и у каждой есть невинное объяснение. Веб-разработчик, тестировщик, журналист, проверяющий утверждение, пользователь, следующий статье поддержки, — все открывают DevTools, а сайт, блокирующий их, теряет реальных клиентов. При этом тот, кто решил изучить страницу, может открепить панель или отключить точки останова, так что проверки эвристичны и легко обходятся. Поэтому их используют как один признак с малым весом рядом с более сильными доказательствами вроде поведенческих сигналов, но никогда как вердикт.
Что делает проверка BrowserInsight
Проверка отпечатка показывает среди сведений о браузере флаг DevTools «открыты» или «закрыты». Она использует только разницу размеров окна с порогом 160 px, поэтому ведёт себя ровно так, как описано выше:
- Закреплённые DevTools (сбоку или снизу) обнаруживаются, потому что вьюпорт сжимается больше чем на 160 px.
- Откреплённые DevTools не обнаруживаются.
- Крупная боковая панель браузера может вызвать срабатывание, даже когда DevTools закрыты.
На странице обнаружения ботов есть строка «Обнаружение инструментов разработчика» на основе той же разницы в 160 px, с низкой степенью риска. Если разница найдена, она дополнительно запускает проверку геттером консоли, но эта проверка никогда не определяет результат сама по себе. Отдельная строка «Обнаружение эмуляции мобильного устройства» ищет режим устройства DevTools: мобильный User-Agent на настольной платформе или окно браузера, размер которого не совпадает с заявленным экраном телефона.
Ни одна из проверок не использует оператор debugger, поэтому BrowserInsight никогда не приостанавливает вашу страницу. Откройте инструмент с закреплёнными, а затем с откреплёнными DevTools и посмотрите, как меняется флаг: он показывает, что страница может вывести, но ничего не доказывает.
Вопросы и ответы
Сайт правда видит, что я открыл DevTools?
Напрямую нет. Он может только выводить это из побочных эффектов, таких как изменившийся размер вьюпорта или приостановленный скрипт, и вывод часто неверен.
Почему страница зависает при открытии DevTools?
Обычно скрипт вызывает debugger в цикле, и после каждого продолжения выполнение снова встаёт. Отключение точек останова в панели Sources прекращает паузы.
Обнаружение DevTools — это то же, что обнаружение бота?
Нет. Здесь речь о человеке с открытым инспектором. Инструменты автоматизации оставляют другие следы, о них в материале про обнаружение headless-браузеров.
Рекомендуем прочитать
- Обнаружение автоматизации через Chrome DevTools Protocol (CDP)
- Обнаружение ботов: как выявляют ботов и краулеров
- Обнаружение headless-браузеров: как Selenium и Playwright оказываются раскрыты
- Фингерпринтинг по разрешению экрана: что выдаёт размер дисплея
- Поведенческое обнаружение ботов: нечеловеческие движения мыши


