Math.random()
в Googlebot выдаёт полностью детерминированные серии чисел. Я написал маленький скрипт, который использует этот баг для точной идентификации гуглобота:Источник
При первом вызове
Math.random()
из гуглобота результат всегда будет 0,14881141134537756
, второй вызов всегда вернёт 0,19426893815398216
. Скрипт по ссылке выше просто использует эту информацию для идентификации бота Google, хотя немножко обфусцирует свои действия, чтобы они не выглядели слишком произвольными.Краулинг в масштабе Google
Представьте объём работы, которую необходимо выполнить Google, чтобы обойти весь веб, да при этом ещё выполнить все скрипты. Здесь не обойтись без обильных оптимизаций, и я полагаю, что детерминированные случайные числа реализованы по следующим причинам::
- Скорость.
- Лучшая безопасность.
- Предсказуемость — гуглобот может быть уверен, что страница отобразится одинаково при каждом визите.
Ускорение времени…
Googlebot также запускает JavaScript с ускоренными часами, что вполне логично. Зачем реально ждать 5 секунд, если ты бот? Так что Google на самом деле запускает таймер в гораздо более быстром темпе. Если создать простой скрипт с тикером и запустить функцию Fetch & Render в консоли Google Search Console, то скрипт выполнится практически мгновенно, но результат будет выглядеть так:
Вторая дата — это дата из будущего! Марти Макфлай мог бы гордиться.
Когда это началось?
Мне стало интересно, обновляется ли генератор «случайных» чисел у Google, но поиск числа
0,14881141134537756
вернул более 18 000 результатов, так что константа кажется довольно стабильной. Обнаружив это, я погуглил ещё немного и нашёл старый комментарий на Hacker News от пользователя KMag:В какой-то момент кто-то из SEO выяснил, что random() всегда возвращает 0,5. Не уверен, что кто-нибудь понял, что JavaScript всегда при этом видел какую-то дату из лета 2006 года, но предполагаю, что ситуация изменилась.
Похоже на то, что ситуация сохраняется в течение долгого времени, но раньше
random()
всегда возвращал 0,5
, а сейчас выдаёт детерминированные серии чисел. Дата действительно вначале установлена точно, но затем может идти в будущее. KMag дальше сказал:Надеюсь, что теперь они установали случайное начальное число и дату, используя криптографический хэш всех загруженных скриптов и текста страницы, так что он будет детерминированным, но им будет сложно манипулировать.
Кажется, этого не произошло. Но я не уверен, что таким образом можно сделать многое из того, что вы не можете сделать с помощью юзер-агента и IP. Но может быть такой способ позволит сделать нечто, правдоподобно отрицая свою вину!
Комментарии (18)
vilgeforce
13.02.2018 10:18Осталось найти тот seed, который будет выдавать ту же последовательность и наконец объяснить происхождение «бага», который вовсе и не баг :-)
AelDeyr
13.02.2018 12:24Matt Kulukundis упоминал что они используют детерминированный рандом в продакшене и «честный» при отладке в своей SwissTable (замена google::dense_hash_map).
По-видимому, это связано со скоростью (функция случайного числа выполняется в L1 кэше) и удобством отлова багов. Можно предположить, что такой подход работает для многих сервисов компании.
youtu.be/ncHmEUmJZf4?t=2645
sebres
13.02.2018 14:59Я написал маленький скрипт, который использует этот баг для точной идентификации гуглобота
На кой он это спрашивается делал, если гуглобот никогда и не скрывался, и по
navigator.userAgent
и кучей других разных способов однозначно определяется как бот.
Точней уже некуда.
И да, это не баг, это — фича...
EvilFox
13.02.2018 18:47Наверное потому что некоторые другие боты (да и не только боты) любят притворяться гуглоботом.
reket
14.02.2018 15:45Возможно ошибаюсь, но гугл бот может прикидываться обычным пользователем чтоб проверить одинаковый ли контент выдается пользователю и боту. Например, боту без навязчивой рекламмы.
sebres
14.02.2018 15:59Да запросто, но думаю в этом случае оно сделает это c другим юзер-агентом, с другого-IP,… и наверное другим движком (в котором ранд работает случайным образом).
Эта фича у гугла, чтобы в том числе хотя бы из js-движка не переиндексировать страницы, зависящие от случайных составляющих (ака "Случайная страница").
Хотя правильный сервер может или но-робот проставить или оборачивать "случайную" динамику конструктами типаif (!bot) {...};
.
AVI-crak
13.02.2018 20:17Индетерминированный ключ…
Жители планеты Мелдж ищут этот ключ уже сотни лет.
altervision
Странно, что до сих пор никто из «шибко активных» не предъявил Гуглу претензии за это случайное число, ведь 1488 в его начале выглядит очень подозрительно.
ShamanR
Пока вы на этом не сакцентировали внимание даже не заметил ничего необычного в числе.
begemot_sun
А для тех кто не в теме, можно расшифровать?
Nord001
Гугл думает что про это:
ru.wikipedia.org/wiki/14/88
TimsTims
Кому лень открывать Википедию
gearbox
ок, теперь я тоже в курсе. Спасибо двум джентельменам в треде.
hdfan2
david_mz
При первом вызове Math.random() из гуглобота результат всегда будет 0, РОСКОМНАДЗОР1141134537756
asmrnv777
Рандом хардкодить мы не бросим!