Блоги

Я перестал доверять собственному коду — 13.07.26 14:49

Я перестал доверять собственному коду - 13.07.26 14:49 0

Иногда одна случайная статья меняет отношение к тому, чем ты занимаешься каждый день. Со мной именно так и вышло.

Был вечер, где-то в марте 2026-го. Я лениво листал новости по кибербезопасности — из тех, что читаешь вполглаза перед сном, — и наткнулся на разбор атаки под названием Glassworm. Пробежал по диагонали, отложил телефон. А через минуту взял снова и перечитал заново — не потому, что текст был сложный, а потому что решил, что неправильно понял прочитанное.

Больше полутора сотен репозиториев на GitHub. Вредоносные пакеты в npm. Заражённые расширения для VS Code. Цифры внушительные, но поразили меня не они. Поразило другое: вредоносный код никто не прятал за хитрой обфускацией. Его вообще нельзя было увидеть. Не в переносном смысле — в самом буквальном.

Я сидел и пытался уложить это в голове. Как можно спрятать код так, чтобы его не заметил ни разработчик, ни редактор, ни даже GitHub при просмотре диффа? Ответ оказался одновременно простым и неприятным: невидимые символы Unicode. Те самые, что существуют в файле, занимают место, участвуют в обработке текста — и при этом никак не отображаются на экране.

Ты открываешь файл, видишь аккуратный код — каждая строка выглядит безобидно. И только компьютер знает, что между этими строками уже спрятана вторая история. Та, которую человек не увидит никогда.

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

Тяну библиотеки и ни разу до этого вечера не задумался, насколько вообще можно доверять тому, что показывает мне редактор.

Мы привыкли думать, что редактор показывает файл таким, какой он есть. Это неправда. Редактор показывает не байты — он показывает их интерпретацию. Разница кажется несущественной ровно до того момента, пока кто-то не начинает использовать её против тебя.

Я не удержался и провёл маленький эксперимент — открыл пару примеров заражённых файлов в разных редакторах. VS Code молчал, Notepad++ молчал, онлайн — подсмотрщик GitHub был абсолютно спокоен, и только hex-редактор наконец расставил всё по местам: там, где обычные редакторы показывали пустоту, лежали вполне реальные байты, невидимые символы никуда не делись их просто никто не рисовал на экране.

Именно тогда я поймал себя на мысли, от которой стало по-настоящему тревожно.

А смог бы я заметить такую атаку в собственном проекте? Не в чужом, не в исследовательском примере — в своём. В коде, который писал сам. Ответ пришёл почти мгновенно, и он был честным: нет не смог бы. Вот этот ответ и не давал мне покоя следующие несколько дней.

Проще написать самому

Сначала я, как любой нормальный человек, полез искать готовое решение. После такой громкой атаки просто не могло быть, чтобы никто ещё не написал вменяемый сканер. Я нашёл один инструмент, потом второй, потом третий. Каждый что-то умел — и каждый чего-то важного не умел. Один работал только с npm, другой требовал облачный сервис и подписку, третий понимал лишь пару типов файлов.

А мне хотелось до обидного простой вещи. Открыть программу, перетащить в неё файл или папку, подождать несколько секунд и получить честный ответ: есть тут что-то подозрительное или нет. Без регистрации, без облаков, без отправки моих файлов неизвестно куда. Просто локальный инструмент, которому можно доверять, потому что он никуда ничего не отправляет.

И вот тогда в голове мелькнула та самая мысль, которая обычно оборачивается сотнями часов работы: «Наверное… проще написать самому».

Тогда я ещё не знал, что эта идея превратится в месяц почти ежедневной разработки, в десятки поздних вечеров, в целую коллекцию собственных ошибок — и в проект, который я в итоге назову Инквизитор. Но самое интересное ждало меня даже не в разработке. Оно ждало в тот день, когда я впервые направлю этот сканер на собственный код.

Самая опасная строка — та, которой не видно

Чтобы объяснить, почему невидимые символы — это так неприятно, проще всего представить обычный лист бумаги. На нём напечатан текст. Вы читаете его внимательно, каждую букву, каждую запятую страница выглядит совершенно чистой. А потом кто-то подносит специальную лампу — и между строк проступает второе сообщение, написанное невидимыми чернилами. Оно было там всё это время. Просто до определённого момента для ваших глаз его не существовало.

Я перестал доверять собственному коду - 13.07.26 14:49 1

С файлами происходит почти то же самое, только вместо чернил — символы Unicode. Когда большинство людей слышит слово «Unicode», они представляют эмодзи, китайские иероглифы, арабскую вязь. На деле это огромная таблица символов почти для всех письменностей мира — и среди миллионов её знаков есть такие, которые не должен видеть никто. Не потому, что они секретные, а потому что они в принципе не предназначены для отображения: они помогают компьютеру понимать направление письма, структуру текста, особенности отдельных языков. Для человека их не существует для машины — существуют. Вот этим и воспользовались.

Меня в этой истории поразило, если честно, не техническое исполнение. Меня поразила психология.

Представьте себя на месте разработчика. Вы открываете pull request перед вами два десятка мелких правок: исправлены опечатки, обновлена документация, переименована переменная, поправлен комментарий. Обычный рабочий день.

Такие изменения просматривают десятками, иногда сотнями, и никто не ждёт, что среди них затесался вредоносный код — особенно если этот код невозможно увидеть.

Именно поэтому атака оказалась такой опасной. Она была направлена не против компьютера. Она была направлена против человека — против нашего доверия, против привычки быстро пролистывать понятные изменения, против уверенности, что глаз обязательно зацепится за проблему. А глаз бессилен, когда проблемы для него физически не существует.

И чем дольше я об этом думал, тем чаще ловил себя на одной мысли. Я ведь каждый день открываю не только исходный код я открываю документы Word, PDF-файлы, архивы, презентации, письма. И каждый раз мысленно делаю один и тот же вывод: «выглядит нормально». После истории с невидимыми символами эта фраза перестала меня успокаивать — потому что между «выглядит нормально» и «является безопасным» лежит пропасть, о существовании которой я раньше просто не думал.

В тот вечер на листке бумаги появился первый набросок будущего Инквизитора. Мне нужен был инструмент, который проверяет не то, что вижу я, а то, что видит компьютер, потому что компьютеру не соврёшь красивой картинкой — он всегда работает с байтами.

Честно говоря, тогда я был уверен, что это проект на несколько вечеров. Как же я ошибался.

Как сканер начал ловить меня самого

Первое, что стало ясно, когда я сел писать код: проблема шире, чем один тип атаки. Не только Unicode, не только стеганография, не только скрытые токены. Всё это объединяет не технология, а сам принцип — невидимость. Эти атаки не ломают систему в лоб они прячутся в том, что мы привыкли считать нормальным.

Поэтому и отталкиваться я стал от простой идеи: файл — это не текст, файл — это набор байтов. Если хочешь действительно что-то найти, нельзя доверять «красивой картинке» редактора, надо работать уровнем ниже.

Первые версии сканера были примитивными. Он просто шёл по файлу и искал то, чего там быть не должно: невидимые символы, подозрительные последовательности, закодированные блоки данных, странные смешения алфавитов, откровенные секреты вроде забытых API-ключей. Ничего магического, но даже этого хватило, чтобы начать видеть то, чего для моих глаз раньше не существовало.

А дальше начался самый неприятный и самый полезный этап любой такой разработки. Потому что худшие баги здесь не те, что роняют программу. Худшие те, что показывают тебе правду о твоих собственных ошибках. Их было три, и каждый я запомнил.

Первый вылез, когда я добавил в тесты фейковые ключи для проверки детектора секретов — стандартную заглушку AWS из документации, выдуманный ключ Stripe. Нужны они ровно для одного: убедиться, что детектор вообще ловит такие форматы, а потом я прогнал сканер по самому проекту — и получил пять «критических» находок прямо в тестовом файле. На секунду стало не смешно, потом смешно, потом снова не смешно. Формально программа была права: она нашла строки, которые выглядят как настоящие ключи, но она не понимала контекста — что это заглушки, специально положенные для теста. Так появился первый «человеческий» слой логики: если файл лежит в папке tests/ или называется test_*, найденные в нём секреты не стоит с ходу объявлять критическими. Урок оказался важнее, чем сам баг: инструмент безопасности без понимания контекста это просто генератор шума.

Второй баг был обиднее. Я решил проверить, как программа поведёт себя с бинарными файлами, и просто перетащил в неё обычную картинку PNG, ожидая, что сканер её проигнорирует. Он её не проигнорировал он попытался прочитать её как текст и прогнать через анализатор кода. Через несколько секунд программа намертво зависла: на случайных байтах картинки регулярные выражения, ищущие закодированные строки, уходили в такой тяжёлый разбор, что просто не возвращались. Очевиднейшая вещь в мире нельзя заставлять текстовый анализатор считать бинарь текстом, но, когда пишешь инструмент с нуля, самые очевидные вещи почему-то приходят в голову последними. Пришлось научить программу с первых килобайтов понимать, где текст, а где двоичный файл, который надо просто вежливо пропустить.

Третий был самый показательный, потому что тихий. У меня в движке жила схема стеганографии на шестнадцать символов, одна из нескольких, которыми можно прятать сообщения. Я её написал, проверил на своих данных, вроде работало, а спустя пару месяцев, случайно копаясь в коде, обнаружил, что семь из шестнадцати символов её алфавита физически не попадали в список тех, что вообще считаются носителями скрытых данных. Схема кодировала сообщение, но при обратном чтении от него откусывалась почти половина. Формально она существовала и не работала ни разу с момента написания. Никто бы этого не заметил кроме меня, случайно.

Именно на этих трёх ошибках проект перестал быть «интересным экспериментом» и стал чем-то личным, потому что я перестал проверять чужие репозитории и начал проверять свои.

Почему это касается не только программистов

Поначалу картина в голове у меня была простая есть разработчики, есть код, есть уязвимости значит, это проблема узкого круга людей. Чем глубже я копал, тем быстрее эта картина рассыпалась, потому что реальность оказалась проще и неприятнее: этим атакам вообще не нужно, чтобы ты был разработчиком. Им не нужен твой GitHub, не нужен твой VS Code, им безразлично, знаешь ли ты, что такое Unicode им нужно ровно одно — чтобы ты открыл файл.

А открываем мы файлы постоянно. И чаще всего — не в коде, а в почте. Приходит письмо тема знакомая: «Счёт на оплату», «Документы от партнёра», «Резюме кандидата», «Уведомление о доставке» ничего необычного и здесь срабатывает самое опасное свойство человеческой психики — привычка. Мы видели такие письма сотни раз, открывали такие вложения десятки раз, и ничего не случалось. Мозг делает быстрый вывод: «это нормально», а дальше уже неважно, что внутри файла.

Я раньше думал, что атака — это обязательно что-то сложное эксплойты, хитрые цепочки уязвимостей, но чем больше я разбирался в инфостилерах и фишинговых кампаниях, тем яснее становилось: в большинстве случаев ничего сложного не происходит человек сам запускает атаку, сам открывает вложение, сам разрешает макрос, сам подтверждает действие и происходит это не потому, что люди глупые, а потому, что всё выглядит слишком нормально.

Стоит на секунду остановиться на слове «инфостилер», потому что за скучным термином прячется совершенно конкретная и очень прибыльная механика. Это класс вредоносов, чья единственная задача тихо собрать с заражённой машины всё ценное и отправить наружу сохранённые в браузере пароли, файлы криптокошельков и что особенно неприятно, session-куки — по сути готовый пропуск в аккаунт, который действует даже без пароля и обходит двухфакторную аутентификацию, потому что как бы подтверждает: вход уже был выполнен. Вся операция занимает секунды, ни окон, ни предупреждений, ни тормозов компьютер работает как ни в чём не, бывало, а доступ к твоим аккаунтам уже у кого-то другого.

Масштаб, тут отрезвляющий по оценкам Flashpoint и DeepStrike за один только 2025 год такие программы утащили порядка 1,8 миллиарда учётных данных с почти шести миллионов заражённых устройств и это не абстрактная страшилка «для айтишников». В январе 2026-го исследователь Джеремайя Фаулер нашёл в открытом доступе базу почти на 149 миллионов украденных логинов и паролей с аккаунтами Gmail, Instagram, Netflix и, среди прочего, с 420 тысячами учётных записей, привязанных к криптобирже Binance. Сама биржа тогда прямо подтвердила: её собственные системы не взламывали это были заражённые устройства обычных пользователей. А чуть раньше, в декабре 2025-го, в Kaspersky описали зловред, который целенаправленно охотится на пользователей минимум восьмидесяти криптобирж и кошельков, маскируясь под читы и моды для игр.

Истории разные — принцип один. Человек своими руками запускает то, что потом молча выгребает всё ценное из его браузера, собственно, поэтому в Инквизиторе с самого начала есть проверка не только кода, но и документов. Тот же движок, что ищет невидимые символы в Python-файле, точно так же разбирает Word, Excel, PowerPoint и PDF на встроенные макросы, на спрятанный внутри JavaScript, на авто запускаемые действия, на подозрительные ссылки наружу. Перед тем как открыть сомнительное вложение, особенно если в браузере у тебя логины от биржи и сохранённые пароли, можно за пару секунд прогнать его через сканер и увидеть, нет ли внутри чего-то, что сработает само, ещё до того, как ты успеешь прочитать текст письма.

Что осталось со мной после

Есть странный момент в любой разработке, о котором редко пишут. Ты начинаешь с инструмента, а заканчиваешь изменившимся восприятием.

Инквизитор задумывался как простая утилита открыл файл, проверил, закрыл — никакой философии. Но довольно быстро я поймал себя на том, что перестал «просто открывать файлы». Между двойным кликом и «прочитать» появилась короткая пауза, микросекундное «а что там внутри на самом деле?». Рационально я понимал, что подавляющее большинство файлов безопасны, но привычка уже изменилась и обратно её было не отмотать.

Важно уточнить одну вещь, чтобы меня правильно поняли. Инквизитор не открыл мне какой-то новый мир угроз, все эти вещи невидимые символы, скрытые payload’ы, инфостилеры, фишинговые документы существовали и до него. Они не появились после проекта, они просто стали для меня заметнее и пожалуй, это самая неприятная часть всей истории.

Потому что главный вывод, к которому я пришёл, оказался до обидного приземлённым. Раньше у меня была простая и удобная модель: аккуратный код хороший код, понятный дифф безопасное изменение, чистый файл ничего страшного. После Инквизитора эта модель сломалась. Не полностью, но достаточно, чтобы «красиво выглядит» перестало для меня что-либо гарантировать. Ощущение, честно говоря, не самое приятное оно забирает иллюзию контроля. Зато взамен даёт кое-что более честное.

Я перестал мыслить категориями «доверяю / не доверяю» и начал мыслить иначе «проверил или нет». Раньше я считал, что безопасность это состояние, теперь думаю, что это процесс: постоянная тихая проверка того, чему ты почему-то решил доверять по умолчанию.

При этом и это важно — Инквизитор не сделал меня параноиком, он не заставил бояться файлов, писем и кода, он сделал ровно одну вещь: убрал автоматическое доверие и заменил его коротким вопросом, который я теперь задаю себе чуть чаще, чем хотелось бы — «А что я сейчас на самом деле вижу?»

Я долго думал, стоит ли вообще выкладывать всё это в open source. Можно было оставить инструмент себе, но в какой-то момент стало очевидно, что проблема не моя личная. Она не про один проект, не про один язык, не про один стек. Она про то, как мы все взаимодействуем с цифровыми данными и как давно перестали проверять их глубже, чем на глаз и если один маленький локальный инструмент способен хоть немного снизить риск для кого-то ещё этого уже достаточно, чтобы им поделиться.

Соблазн закончить такую историю чем-то громким про новую эру безопасности, про то, что всё изменилось, большой, но правда куда проще. Инквизитор не изменил мир, он изменил меня, а единственный вывод, который я готов из этого сделать, звучит буднично: большинство современных угроз не выглядят как угрозы. Они выглядят как обычный файл, обычное письмо, обычный код, обычное действие и возможно, привычка иногда задавать себе один неудобный вопрос «а что я на самом деле сейчас вижу?» стоит больше, чем кажется. Хотя бы для того, чтобы однажды не совершить ошибку, которая выглядела слишком обыденно, чтобы оказаться опасной.

Инквизитор — open source, лицензия MIT, лежит на GitHub. Можно скачать готовую сборку под Windows, можно собрать из исходников — движок работает на чистой стандартной библиотеке Python, без обязательных зависимостей. Если найдёте баг —напишите, я всё ещё нахожу свои. Разработку веду соло, под брендом ShashevPro: https://github.com/andryhasayan-source/inkvizitor

Источник

Теги

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть
Закрыть