Работу дали без интервью. Это должно было насторожить сразу. «Рекрутер» из компании Carmlize добавил разработчика в рабочий Slack, никто не позвонил, никто не спросил про опыт, ни один инженер не написал ни строчки. Первое живое сообщение — ссылка на GitHub и дружелюбное «вот техническое задание, склонируйте и запустите». Он не запустил. Полез смотреть.
Через несколько недель вышло совместное предупреждение государственных ведомств по кибербезопасности — ровно про этот приём. Фейковые собеседования скомпрометировали больше 30 000 машин в 100+ странах примерно за восемь месяцев. Интуиция оказалась дешевле любого антивируса.
Масштаб, который плохо укладывается в голове
- 30 000+ устройств в 100+ странах с декабря 2025-го по июль 2026 года.
- 7 000+ криптокошельков, украдено около $10,7 млн.
- 338+ вредоносных npm-пакетов, связанных с приманками «собеседование», скачали больше 50 000 раз. Исследователи Socket считают их с июля 2025 года.
- Одна волна в ноябре 2025-го добавила 197 пакетов и 31 000+ загрузок.
- В июне 2025-го 24 разных npm-аккаунта опубликовали 35 пакетов, и часть успели удалить раньше, чем их толком посчитали.
Каждая из этих загрузок — разработчик, который думал, что выполняет тестовое.
Как устроена приманка
Схема выглядит безобидно ровно до момента, когда вы открываете файлы. Репозиторий Carmlize — приличный на вид проект: дашборд на Next.js с живыми котировками, экраном обмена, движком сопоставления ордеров, подключением кошелька и небольшим контрактом на Solidity. Бриф для кандидата при этом честно сообщает: «никакого Solidity, никакой работы с RPC». А в репозитории — ровно это. Мелочь, которая многое объясняет: бриф просто скопировали и наклеили на чужую приманку.
Вредоносного кода внутри самого проекта нет. Так и задумано — ловушка не в репозитории, а в том, что репозиторий подтягивает.
Шаг первый: токен в .npmrc
В корне лежит файл .npmrc со строкой вида //registry.npmjs.org/:_authToken=... Легитимное тестовое с учётными данными в комплекте — это нонсенс. С этим файлом npm install залогинится в реестр как кто-то другой и получит доступ к пакетам, которых публично не существует.
Шаг второй: безобидный плагин для анимаций
В package.json прописан dev-зависимостью пакет animatecss-tailwind-adapter, а конфиг Tailwind его подгружает с настройками длительности и задержки. Кто станет допрашивать помощник для анимации? Смотрим метаданные — и картинка складывается: единственная существующая версия 2.0.6, впервые опубликована 28 июля 2026 года (пакет, стартующий с двойки, имитирует солидную историю), аккаунт мейнтейнера не совпадает ни с автором в package.json, ни с владельцем GitHub-репозитория.
Шаг третий: пакет, которого нет
Анимационный плагин зависит от @aaron205whitmore/postcss-animate-utils. Публичный реестр на этот запрос отдаёт 404 — ни посмотреть, ни скачать, ни прочитать. Достать его можно только с правильными правами. Например, с тем самым токеном из .npmrc.
Дальше всё сходится:
- Вы запускаете npm install. npm молча использует вложенный токен.
- Скачивается скрытый пакет, и его install-скрипты выполняются немедленно.
- Вы запускаете npm run dev. Tailwind читает конфиг, конфиг грузит плагин, плагин подтягивает скрытый пакет внутри вашего Node-процесса — с правами, которые есть у вашей учётной записи.
Читать код можно построчно и ничего не найти. Репозиторий — просто фургон доставки.
Легитимное тестовое против приманки
| Признак | Нормальное тестовое | Приманка |
|---|---|---|
| Начало процесса | Созвон, вопросы про опыт, живой инженер в переписке | Сразу Slack и ссылка на репозиторий |
| Что смотрят | Ваш код и решения, запуск не обязателен | Настойчивая просьба «склонировать и запустить» |
| Учётные данные в репозитории | Их нет, ключи выдаются отдельно и лично | Токен в .npmrc, приватный registry-адрес |
| Зависимости | Известные пакеты с историей версий | Свежий пакет, стартующий с версии 2, чужой мейнтейнер |
| Конфиги сборки | Загружают только стандартные пресеты | tailwind.config, postcss.config, vite.config тянут код |
| Компания | Есть продукт, клиенты, реальные люди | Виртуальный адрес на сотни компаний, профили с одной публикацией |
Что именно ищут на вашей машине
В предупреждении перечислены семейства вредоносных программ с почти мультяшными именами: BeaverTail, InvisibleFerret, OtterCookie. Работа у них прозаичная: криптокошельки и seed-фразы, куки браузера и сохранённые пароли, SSH-ключи, файлы .env, учётные данные GitHub и облачных сервисов. Плюс закладка на будущее, чтобы вернуться.
Отдельно стоит сказать вот о чём: в предупреждении указано, что украденные учётные данные разработчика открывают атакующим путь в инфраструктуру его работодателя. Служебный ноутбук в этой истории — не только ваш риск.
Восемь признаков, что тестовое — приманка
- Вас «наняли» или добавили в Slack до того, как с вами поговорил хоть один человек.
- Настаивают именно на запуске. Настоящему проверяющему интересен ваш код, а не работоспособность их сборки.
- В репозитории лежат учётные данные: токены, настоящие ключи, приватные registry-адреса.
- Зависимость подозрительно новая. npm view <pkg> time maintainers repository занимает секунды и рассказывает много.
- Конфиги подгружают пакеты: tailwind.config, postcss.config, next.config, vite.config выполняют код при сборке.
- Есть install-скрипты. Читайте каждый preinstall, postinstall и prepare.
- Живых людей в компании не найти: общий виртуальный офис, профили-призраки, никто не отвечает.
- Бриф и код противоречат друг другу — как «никакого Solidity» рядом с контрактом на Solidity.
Как смотреть такое тестовое безопасно
- Открывайте в редакторе и ничего не устанавливайте. VS Code спрашивает, доверяете ли вы папке, — отвечайте нет, потому что задачи из .vscode тоже умеют запускать код.
- Изучайте пакеты без запуска: npm view <pkg> для метаданных, npm pack <pkg> чтобы скачать tarball и прочитать содержимое.
- Если запустить всё-таки нужно — только одноразовая виртуалка или контейнер без кошельков, SSH-ключей, браузерных сессий и облачных доступов. Файл .npmrc удалить до всего остального.
- npm install --ignore-scripts закрывает часть сценариев, но не спасёт от плагина, который подгружается из конфига во время сборки. Это и есть основной вектор описанной атаки.
Двадцать минут на проверку адреса компании, мейнтейнера зависимости и содержимого .npmrc стоят дешевле, чем разговор с безопасниками.
Если вы уже запустили
- Отключите машину от сети.
- С другого, чистого устройства переведите крипту на новый кошелёк, смените пароли и перевыпустите SSH-ключи, токены GitHub и облачные ключи.
- Разлогиньтесь во всех важных сессиях: почта, GitHub, биржи, Google.
- Просканируйте машину. Надёжнее — снести и переустановить.
- Сообщите о пакетах в службу безопасности npm, а о рабочем пространстве и «рекрутере» — в Slack и LinkedIn.
Спасает в таких историях не хитрый инструмент, а ощущение, что что-то не так, и привычка посмотреть вокруг до запуска. Код в приманках выглядит чистым специально — выдают их детали вокруг: компания, которой нет, сотрудники, которых нет, отсутствие интервью и пароль, который никто не должен был класть в архив. Нормальный работодатель спокойно проведёт собеседование и не обидится на вопросы до запуска его кода. Если торопят — это и есть ответ.
Комментарии (0)
Войдите, чтобы комментировать.
Пока нет комментариев. Будьте первым.