SebWeo.com
Каждый владелец сайта и SEO-специалист ведет ежедневную упорную борьбу за удержание пользователя на страницах вебресурса. Однако когда в ход идут «черные» технические манипуляции, под удар попадает не только пользовательский опыт (UX), но и репутация домена в поисковых системах. Один из самых серьезных технических грехов, за который веб-ресурс может мгновенно потерять весь органический трафик и вылететь из топов Google — это History Hijacking (несанкционированный перехват или подмена истории браузера).
Речь идет о крайне неприятной ситуации: посетитель заходит на ваш сайт с поисковой выдачи, изучает контент, а затем нажимает кнопку «Назад» в своем браузере, чтобы вернуться в список поиска. Однако вместо ожидаемого возвращения назад он либо остается на той же странице, либо попадает на совсем другой сайт с назойливой рекламой, фейковыми опросами или казино/порно. Самое опасное то, что ваш сайт может заниматься этим вредительством прямо сейчас, а вы как вебмастер/администратор даже не догадываетесь о существовании проблемы.
Современные стандарты веб-разработки предоставляют программистам колоссальную гибкость для управления сессиями и переходами без перезагрузки страниц с помощью HTML5 History API. Этот инструментарий незаменим при создании современных Single Page Applications (SPA) на базе Vue, Nuxt.js, React или Angular, а также при реализации динамических AJAX-фильтров в интернет-магазинах на OpenCart или WordPress. Для управления стеком истории используются три основных инструмента объекта window.history:
history.pushState(state, title, url) — добавляет совершенно новую запись в стек истории браузера.history.replaceState(state, title, url) — модифицирует текущую запись в стеке истории без добавления нового шага.popstate — вызывается операционной системой браузера всякий раз, когда пользователь осуществляет навигационное действие по истории (нажимает кнопку «Назад» или «Вперед»).При нормальной работе эти инструменты помогают изменять URL в адресной строке без перезагрузки страницы. Но при злоупотреблении скрипты начинают агрессивно «спамить» в стек истории фейковыми записями.
pushStateКак видно из схемы, каждый вызов pushState создает новый уровень в стеке. Если вредоносный скрипт программно вызовет этот метод несколько раз подряд, то при нажатии пользователем кнопки «Назад» браузер просто перейдет на предыдущее искусственно созданное состояние той же страницы.
Вредоносные или некорректно настроенные рекламные скрипты используют метод pushState() как оружие против UX. Как только пользователь попадает на страницу, такой скрипт программно выполняет серию циклических вызовов window.history.pushState(), искусственно заполняя стек истории браузера дубликатами текущей страницы или промежуточными редиректами. Когда человек пытается выйти и нажимает кнопку «Назад», браузер честно выполняет команду и возвращается на один шаг назад в стеке истории. Но поскольку предварительным шагом является точно такое же искусственно сгенерированное состояние вашей же страницы, пользователь визуально остается на месте.
Чтобы действительно вернуться в поисковую выдачу Google, бедному посетителю приходится судорожно щелкать по кнопке «Назад» десятки раз подряд, пытаясь опередить скорость выполнения циклов JavaScript, или зажимать кнопку мыши для вызова контекстного меню истории и принудительного выбора предыдущего сайта.
Поисковик Google ведет бескомпромиссную войну за чистоту выдачи и качество пользовательского опыта. Перехват кнопки «Назад» четко классифицируется официальным документом правил Google Search Essentials (бывшие Webmaster Guidelines) как грубое нарушение в разрезе «Обманчивых действий» (Deceptive practices) и «Скрытых перенаправлений» (Sneaky redirects).
Алгоритмы Googlebot, работающие в современных изолированных песочницах на базе движка Chromium, мгновенно распознают аномальное поведение кода:
window.history и фиксирует вызовы pushState(), которые происходят без прямого взаимодействия с пользователем (без так называемого триггера User Activation, например клика или нажатия клавиши).popstate или цепочки редиректов при выходе с сайта четко сигнализируют алгоритмы о наличии проблемы.Какое наказание грозит сайту? Вебресурс гарантированно получает Manual Action (ручные санкции) от команды модерации Google Webmaster Tools. На панели Search Console появляется уведомление о нарушении безопасности или спаме. Последствия катастрофические: полное исключение домена из индекса Google или критическое падение позиций по всем ключевым запросам на 50-90 пунктов вниз. Процесс выхода из-под таких санкций после исправления кода может занять от нескольких месяцев до полугода.
Самая большая трагикомедия заключается в том, что более 90% владельцев информационных сайтов и блогов не внедряют History Hijacking намеренно. Они становятся жертвами посторонней инфраструктуры, которую сами же интегрируют для монетизации или улучшения функционала:
/category?price=from-100) разработчики часто ошибочно используют метод роутера router.push() вместо router.replace(). В результате каждое изменение ползунка цены засоряет историю и пользователь не может выйти обратно.
Поскольку вредоносные скрипты умеют маскироваться (не срабатывают для авторизованных админов, проверяют IP-адреса или запускаются исключительно на мобильных устройствах), обычная проверка не поможет. Требуется тщательный технический аудит:
Откройте ваш сайт, нажмите клавишу F12 и перейдите на вкладку Console. Введите следующий JavaScript-код, который поможет отследить скрытые манипуляции со стеком истории:
(function() {
const originalPushState = history.pushState;
history.pushState = function(state, title, url) {
console.warn('Внимание! Скрипт вызвал pushState без перехода. Создана новая запись истории:', url);
return originalPushState.apply(this, arguments);
};
console.log('Мониторинг History API успешно активирован. Следите за предупреждениями...');
})(); После активации скрипта просто поскрольте страницу, покликайте по пустым местам. Если в консоли появляются предупреждения (warn), это означает, что один из подключенных плагинов или баннеров тайно манипулирует историей браузера.
Единственным надежным техническим способом защитить свой сайт от несанкционированного выполнения сторонних вредоносных скриптов, ломающих кнопку Назад, является внедрение жесткой политики Content Security Policy (CSP). CSP — это специальный HTTP-заголовок ответа сервера, четко указывающий браузеру пользователя, из которых именно доменов и источников разрешено загружать и выполнять JavaScript-код, стили, картинки и фреймы.
Ниже приведены готовые практические примеры конфигурации CSP для разных уровней серверной архитектуры веб-ресурса.
Если вы администрируете собственный сервер на базе Ubuntu и управляете сайтом напрямую или через панели типа DirectAdmin, добавьте следующую конфигурацию в блок server { ... } вашего конфигурационного файла Nginx (обычно находится по пути /etc/nginx/sites-available/):
# Добавление заголовка Content Security Policy в Nginx add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' https://www.google-analytics.com https://ssl.google-analytics.com; object-src 'none'; base-uri 'self'; 'frameance' always;
Если ваш сайт работает на классическом хостинге или локальной среде WampServer/Laragon под управлением Apache, добавьте эти строки в самое начало корневого .htaccess вашего WordPress или OpenCart сайта:
<IfModule mod_headers.c> Header set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' https://www.google-analytics.com; object-src 'none'; base-uri 'self';" </IfModule>
Если у вас нет прямого доступа к системным файлам конфигурации сервера, вы можете отправлять заголовки безопасности непосредственно через код WordPress-приложения. Для этого откройте файл functions.php вашей активной темы разработки и добавьте следующий хук:
function sebweo_send_csp_headers() {
if (!is_admin()) {
// Формируем строчку политики безопасности
$csp_policy = "default-src 'self'; " .
"script-src 'self' 'unsafe-inline' https://www.googletagmanager.com https://www.google-analytics.com; " .
"style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; " .
"font-src 'self' https://fonts.gstatic.com; " .
"img-src 'self' data: https://*.wp.com; " .
"frame-src 'none'; " .
"object-src 'none';";
header("Content-Security-Policy: " . $csp_policy);
}
}
add_action('send_headers', 'sebweo_send_csp_headers'); Разбор директив CSP, используемых в примерах:
default-src 'self' — по умолчанию позволяет загрузить любые типы контента (скрипты, стили, картинки) исключительно из вашего собственного домена.script-src 'self' 'unsafe-inline' ... — четко ограничивает выполнение JavaScript. Разрешены только собственные файлы, скрипты онлайн шаблона и коды метрики (в данных примерах используется Google Analytics). Любой левый сторонний рекламный JS-код будет заблокирован браузером до момента его выполнения.object-src 'none' — полностью запрещает устаревшие технологии Flash и Java-апплеты, которые часто являются источником уязвимостей.frame-src 'none' — запрещает загрузку посторонних фреймов, предотвращая скрытые кликджекинг-атаки.
Многие вебмастеры, заметив, что после показа или закрытия полноэкранной рекламы (Vignette Ads) от Google AdSense в URL сайта добавляется суффикс #google_vignette, начинают паниковать. Ведь визуально сценарий выглядит угрожающе: пользователь нажимает кнопку «Назад», но вместо выхода с сайта просто возвращается на ту же страницу, с которой исчезает этот самый хэш #google_vignette.
Возникает логичный вопрос: Считает ли сам Google такое поведение нарушением и угрожают ли за это санкции?
Когда на сайте появляется межстраничная реклама AdSense, скрипты Google используют стандартный механизм браузера для работы с якорями (hashes). Добавление хеша #google_vignette в адресную строку автоматически создает новую запись в стеке истории браузера (Browser History Stack).
Это дефолтное поведение любого современного браузера: изменение фрагмента URL после символа # воспринимается системой как навигация внутри страницы, чтобы пользователь мог вернуться в предыдущее состояние экрана. Именно поэтому первый клик по кнопке «Назад» лишь «отматывает» историю на шаг назад, убирая хеш, но оставляя посетителя на том же URL-адресе.
Нет, за Google AdSense штрафов или санкций не будет. И вот почему:
pushState сразу при входе, в случае с виньетками AdSense изменение URL происходит в ответ на действие пользователя (клик по ссылке, закрытие окна или ожидание загрузки перехода).google_vignette или gclid) при расчете метрик блокировки навигации.Хотя сам по себе #google_vignette безопасен для SEO, проблемы могут возникнуть, если на сайте параллельно работают другие кастомные JS-скрипты.
Например, если ваш SPA-роутер (на Nuxt или React) или плагин для плавного скрола (Smooth Scroll) сконфигурирован так, что он панически реагирует на любое изменение хеша в URL и пытается программно «перебить» его своим вызовом history.pushState() или replaceState(). В таком случае возникает конфликт скриптов: Google добавляет свой хэш, ваш сайт пытается его очистить или обработать, и стек истории зацикливается уже по-настоящему.
Резюме для кейса: Появление
#google_vignetteи необходимость двойного клика на кнопку «Назад» для выхода с сайта после просмотра официальной рекламы Google – это легальная техническая особенность работы платформы AdSense. Она не является нарушением правил Google Search Essentials и не приведет к ручным санкциям. Однако вебмастеру следует быть бдительным, чтобы кастомные скрипты сайта не вступали в конфликт с этим хэшем.
Многие предприниматели сталкиваются с одной и той же проблемой. После утверждения бюджета разработка затягивается, появляются…
Футбольная секция быстро показывает, насколько обувь подходит ребенку. Если пара скользит, давит или плохо цепляется…
Компания Samsung — один из лидеров на рынке электроники. Ее смартфоны выделяются надежностью, качественными дисплеями,…
Испанский язык привлекает миллионы людей своей мелодичностью, эмоциональностью и относительной простотой изучения. Одним из важнейших…
Рабочее пространство давно перестало быть просто столом с ноутбуком. Сегодня это полноценная экосистема, где каждая…
Когда проект зависит от чужих ограничений, возрастают риски простоев, потери доступа к данным и сложности…