Skip to content

Repository files navigation

itd-scanner

Детерминированный сканер и система семантического сравнения production-сборок фронтенда https://xn--d1ah4a.com/.

Проект скачивает граф публичных ресурсов фронтенда, не выполняя код сайта, пропускает JavaScript через консервативный уровень преобразований minimal в Wakaru, а затем применяет собственную нормализацию с учётом областей видимости. Полученные снимки предназначены для хранения истории в Git и проверки изменений кода, а не для пересборки или запуска исходного приложения.

Чем это отличается от обычного форматирования

В production-сборках могут меняться хеши содержимого, минифицированные идентификаторы, имена классов CSS Modules и отладочные идентификаторы Sentry, даже если поведение приложения почти не изменилось. itd-scanner устраняет эти источники шума, сохраняя строки, числа, имена свойств, порядок инструкций, пути запросов и поток управления.

Этапы нормализации:

  1. Сканер скачивает HTML и рекурсивно находит ресурсы того же origin: ESM-модули, зависимости Vite, CSS, шрифты, изображения и JSON.
  2. Проверяются перенаправления, типы ответов, UTF-8, количество ресурсов и ограничения на размер. Статические импорты обязательны, а необязательные URL-литералы могут отсутствовать.
  3. Ресурсам назначаются логические пути, например entry.js, routes/login.js и components/icon-play.js. Неизвестные общие чанки сопоставляются с предыдущим манифестом по структурным отпечаткам, не зависящим от имён переменных.
  4. JavaScript декомпилируется зафиксированной версией Wakaru на уровне minimal.
  5. Babel разрешает привязки идентификаторов, после чего переименовываются только лексические переменные и ссылки на них. Ключи объектов, свойства, литералы, глобальные имена и порядок выполнения сохраняются.
  6. Нормализуются минифицированные экспорты между чанками, пути импортов, классы CSS Modules и меняющиеся отладочные UUID Sentry.
  7. Формируется сводный отчёт с приоритетом объявленных маршрутов, их эффективными шаблонами и ограничениями, HTTP- и WebSocket-адресами, ключами хранилищ, пользовательскими строками и версиями Sentry. Diff маршрутов показывает изменения порядка, fallback и сужающих проверок параметров.

Скачанный JavaScript не вычисляется, не импортируется и не запускается.

Требования

  • Node.js 22.18 или новее;
  • Git — для истории снимков и сравнительных тестов.

Установка строго зафиксированного графа зависимостей:

npm ci

Локальный запуск

Создание снимка сайта:

npm run scan -- --output snapshot

Команда создаёт:

  • snapshot/raw/ — точные скачанные байты для проверки результатов;
  • snapshot/source/ — стабильный, нормализованный и читаемый код;
  • snapshot/manifest.json — хеши, исходные URL, логические имена и сигнатуры сопоставления;
  • snapshot/reports/summary.md — сводный отчёт о текущей сборке.

Локальная snapshot/ игнорируется в ветке со сканером. GitHub Actions записывает её в отдельную ветку snapshots.

Полезные команды:

npm test
npm run build
npm run check
npm run scan -- --output snapshot
npm run scan -- --no-wakaru

Флаг --no-wakaru предназначен для диагностики и модульных тестов. Для production-снимков следует использовать Wakaru.

Проверка нормализации на исторических сборках

Сравнить две произвольные директории со сборками можно командой:

npm run benchmark -- <старая-сборка> <новая-сборка> <каталог-результата>

На реальных сборках от 13 и 20 августа обычное форматирование отмечает изменёнными все 85 файлов и 19 167 строк. В каноническом представлении остаются 11 файлов и 807 строк — уровень шума снижается на 95,79%. В оставшемся diff основной сборки видны реальные изменения, например загрузка удалённых SVG-иконок и состояние мутаций лайков, а не массовое переименование минифицированных переменных.

Автоматический запуск

Workflow .github/workflows/scan.yml запускается каждые шесть часов: в 03:17, 09:17, 15:17 и 21:17 по часовому поясу Europe/Moscow. Его также можно запустить вручную. Ненулевая минута помогает не попадать в наиболее загруженный для GitHub Actions момент в начале часа.

Код сканера хранится в основной ветке, а история сгенерированных снимков — в ветке snapshots. При первом успешном запуске workflow автоматически создаёт эту ветку, последовательно выполняет конкурирующие сканы, запрашивает только разрешение contents: write и создаёт коммит лишь при изменении опубликованной сборки или версии нормализатора.

Текущее расписание задаётся выражением:

cron: "17 3,9,15,21 * * *"
timezone: "Europe/Moscow"

Проверка изменений между снимками

Сначала откройте snapshot/reports/summary.md, затем изучите соответствующие файлы в snapshot/source/. Точные минифицированные файлы остаются в snapshot/raw/, но .gitattributes помечает их как сгенерированные и отключает для них шумные текстовые diff.

Сканер намеренно не нормализует:

  • строковые и числовые литералы;
  • ключи объектов и невычисляемые свойства;
  • порядок инструкций, элементов массивов и свойств объектов;
  • условия и операторы;
  • вызовы с наблюдаемыми побочными эффектами.

Обновление компилятора всё ещё может создавать структурный шум из-за инлайнинга, tree shaking или изменения порядка модулей. Точный слой raw позволяет проверить каноническое представление в спорных случаях.

Конфигурация и безопасность

Целевой URL и ограничения находятся в itd-scanner.config.json. Разрешены только HTTPS и ресурсы или перенаправления того же origin. Сканер завершает работу без записи нового снимка, если вместо приложения получена challenge-страница, нарушена кодировка UTF-8, отсутствует статический импорт, возвращён неожиданный тип содержимого или превышено настроенное ограничение на ресурсы.

Сканируйте только те сайты, условия использования и применимое законодательство которых разрешают такой анализ. Сканер не обходит защитные проверки и не обращается к содержимому, требующему авторизации.

About

Декомпилятор фронтенда ИТД.com

Resources

Stars

0 stars

Watchers

0 watching

Forks

Contributors

Languages