Не повинно бути нічого, що можна зібрати
Скомпрометований Bitwarden CLI зібрав SSH-ключі, хмарні облікові дані та npm-токени з 334 машин розробників. Справжня проблема не в тому, як шкідливий код потрапив усередину. А в тому, що кожен секрет лежав собі як звичайний файл і чекав, поки його прочитають. <<<CLV-SUBTITLE>>>
Учора скомпрометована версія CLI від Bitwarden зібрала SSH-ключі, облікові дані AWS, npm-токени, змінні середовища, історію shell та секрети Git із 334 машин розробників.
Сьогодні це був Bitwarden. Минулого місяця — Axios. До того — Checkmarx. Завтра це буде розширення для VS Code, або Acrobat, або формула Homebrew, або образ Docker. Вектор змінюється щотижня. Результат завжди однаковий.
Шкідливий код потрапляє на машину. Він читає ~/.ssh/. Він читає ~/.aws/credentials. Він читає ~/.npmrc. Він читає ~/.git-credentials. Він читає історію shell, змінні середовища, сховища паролів браузера. Пакує все це й надсилає на сервер C2.
І це працює. Щоразу.
Збір урожаю
Навантаження Bitwarden — 10-мегабайтний обфускований файл під назвою bw1.js — не намагалося зламати жодного шифрування. Це було не потрібно. Ось що воно зібрало, згідно з документацією Socket та Aikido:
- SSH-ключі та відбитки хостів
- Хмарні облікові дані AWS, GCP та Azure
- Токени автентифікації npm
- Облікові дані Git та віддалені URL-адреси
- Змінні середовища
- Історію shell
- Автентифікацію Claude Code та конфігурації MCP
Далі воно використало викрадені npm-токени, щоб повторно опублікувати інші пакети, які підтримувала жертва, поширюючись далі. Жертви ставали векторами.
Нічого з цього не потребувало зламу шифрування. Кожен із цих секретів був файлом у файловій системі, доступним для читання будь-яким процесом, що запущений від імені користувача.
Це не історія про Bitwarden
Шифрування сховища Bitwarden не було зламано. Їхня архітектура з нульовим знанням витримала. Шкідливий код навіть не торкався сховища.
І не мусив.
Сховище захищає те, що всередині нього. Але SSH-ключі ніколи не були в сховищі. Облікові дані AWS ніколи не були в сховищі. npm-токени, облікові дані Git, ключі API у файлах .env — нічого з цього не зберігається в менеджерах паролів. Усе це лежить у dotfiles, у відкритому вигляді, на кожній машині розробника.
Атакувальник це зрозумів. Сховище — це замкнений сейф у будинку, де кожна шухляда відкрита.
Справжня поверхня атаки
Відкрийте термінал просто зараз. Подивіться, що є на вашій машині.
~/.ssh/id_ed25519 — ваш особистий ключ. Файл у відкритому вигляді.
~/.aws/credentials — ваш доступ до хмари. Файл у відкритому вигляді.
~/.npmrc — ваш токен публікації. Файл у відкритому вигляді.
~/.git-credentials — ваш доступ до репозиторію. Файл у відкритому вигляді.
~/.env у десятку директорій проєктів — ключі API, паролі баз даних, секрети підпису. Усі файли у відкритому вигляді.
Будь-який процес, запущений від вашого імені, може прочитати все це. Без підвищення привілеїв. Без експлойту. Достатньо cat.
Це типова конфігурація розробника у 2026 році. Ми кладемо паролі в зашифроване сховище, а все інше залишаємо відкритим.
Неправильне запитання
Після кожної атаки на ланцюг постачання індустрія ставить одне й те саме запитання: як не допустити потрапляння шкідливого коду?
Краща безпека CI/CD. Підписування коду. Сканування залежностей. Пісочниці для середовищ виконання. Усе це добре. Нічого з цього не є достатнім. Поверхня атаки занадто широка. Занадто багато векторів — менеджери пакетів, розширення браузера, плагіни IDE, застосунки OAuth, скомпрометовані інструменти збірки. Ви не можете закрити кожну точку входу.
Правильне запитання таке: коли шкідливий код неминуче отримує виконання на машині розробника, що він там знаходить?
Якщо відповідь — «сотні облікових даних у відкритому вигляді в передбачуваних місцях файлової системи», жодне зміцнення ланцюга постачання не має значення. Ви граєте в обороні на полі, де ворота за вашою спиною відкриті навстіж.
Не повинно бути нічого, що можна зібрати
Рішення — не краще виявлення шкідливого коду. Рішення — не пісочниця для npm install. Рішення — не швидше реагування на інциденти.
Рішення таке: секрети не повинні існувати як файли на диску.
SSH-ключі, що виводяться з апаратного забезпечення в момент автентифікації, — а не зберігаються в ~/.ssh/. Хмарні облікові дані, що видаються на кожну сесію з ідентичністю, прив'язаною до апаратного забезпечення, — а не записуються в ~/.aws/. Токени API з обмеженим обсягом прав, короткочасні та захищені апаратним ключем, — а не лежать у файлах .env.
Коли облікові дані існують лише всередині апаратного модуля безпеки та в тимчасовій пам'яті процесу під час використання, шкідливому коду немає чого читати. Немає файлу для витоку. Немає dotfile для збирання. Процес запускається, нічого не знаходить і рухається далі.
Це не теорія. Облікові дані, прив'язані до апаратного забезпечення, існують уже сьогодні. WebAuthn PRF може виводити криптографічні ключі з фізичного дотику до автентифікатора — ключі, які ніколи не потрапляють у файлову систему. Технологія вже є. Просто галузь ще не зробила її типовою.
Що робити зараз
Якщо Ви постраждали через компрометацію CLI Bitwarden:
- Замініть кожні облікові дані на машині — SSH-ключі, токени хмари, npm-токени, ключі API, усе в dotfiles та змінних середовища
- Перевірте, чи не були повторно опубліковані npm-пакети, які Ви підтримуєте
- Проведіть аудит активності GitHub та робочих процесів CI/CD щодо несанкціонованих змін
Якщо Ви не постраждали — дії ті самі. Подивіться на свою машину. Порахуйте секрети у відкритому вигляді. Запитайте себе, що станеться, коли — не «якщо», а «коли» — щось шкідливе запуститься від Вашого імені.
Відповідь має бути: нічого. Не повинно бути нічого, що можна зібрати.