Новый год — это не только праздник, но и повод вспомнить о старых «друзьях»: багах, которые годами кочуют из релиза в релиз, из бэклога в бэклог. Они — как ненужные елочные игрушки, которые уже порядком надоели, но все равно не выбрасываются.
Яркий пример — уязвимость Log4Shell, которая скрывалась в популярной библиотеке Apache Log4j с 2013 г., а в 2021-м внезапно стала публичной. Уже спустя 72 часа хакеры атаковали VMware, Cisco и даже игровые платформы. Но главный сюрприз вскрылся через несколько лет, когда выяснилось, что большинство исследуемых российских компаний по-прежнему не пропатчились…
Почему же ошибки 20-летней давности все еще парализуют инфраструктуру? Ответ кроется в сложном переплетении технического, экономического и человеческого факторов. Из-за этого уже ставшие банальными уязвимости превращаются в Кощеев Бессмертных: совсем не сказочных, но успешно выживающих там, где их давно должны были истребить. Давайте разбираться, какие дефекты ПО чаще всего задерживаются в проектах, почему их не исправляют и как с этим бороться.
Сложный код: миллионы строк и незаметные ловушки
Современное ПО — это не просто программы, а настоящие цифровые мегаполисы. К примеру, Windows содержит более 50 млн строк кода, а системы-автопилоты Boeing — свыше 15 млн. При этом исследование Coverity говорит, что на 1000 строк обычно приходится одна ошибка. Логично, что в новых приложениях, где этих строк миллионы, вероятность встретить уязвимости довольно высока.
Зависимости
Сегодня сторонние библиотеки составляют до 90% кода большинства приложений. Когда взорвалась Log4Shell, оказалось, что Apache Log4j вшита в десятки тысяч проектов — от банковских систем до медицинского оборудования. Причем для ее устранения нужно пропатчить каждый зависимый компонент, а у крупной корпорации на это могут уйти годы.
Наш опыт показывает, что разработчики редко проверяют степень вложенности и зависимости используемых библиотек, а уж тем более их код — доверяют сообществу... Не забывайте, что, если в вашем приложении «вдруг» всплывет опасная уязвимость, ответственность все равно ляжет на вас, а не на разработчиков библиотеки и сообщество в целом ;)
Ошибки на стыках систем
Современные ИС плотно интегрируются и обмениваются данными через API. На стыках образуются теневые зоны, где уязвимости проявляются довольно редко, но метко. Например, Shellshock десятилетиями скрывалась в Bash из-за специфических условий эксплуатации, а активировалась лишь в 2014 г., когда хакеры научились использовать ее в контексте IoT. В результате под угрозой оказались:
- Веб-серверы, использующие CGI-скрипты. Атакующий мог отправить туда специально сформированный HTTP-заголовок (например, User-Agent, Referer), который передавался в Bash и вызывал выполнение вредоносного кода.
- DHCP-клиенты. Злоумышленники могли атаковать их с помощью вредоносного DHCP-сервера.
- SSH-серверы — если Bash использовался для обработки переменной окружения.
- Устройства, работающие под управлением Linux: от сложных промышленных систем (ICS, SCADA и др.) до роутеров.
Нехватка экспертизы
Многие уязвимости возникают по вине разработчиков, которые пренебрегают фундаментальными принципами DevSecOps или не до конца осознают, как их код будет взаимодействовать с внешним окружением. Простой пример — отсутствие проверки данных, полученных от пользователя (из форм, URL-параметров, HTTP-заголовков и т. д.).
Если пользовательский ввод:
- используется для формирования системных команд — злоумышленник может выполнить Command Injection;
- напрямую вставляется в SQL-запрос без очистки или использования параметризованных запросов — атакующий может реализовать SQL-инъекцию;
- содержит HTML или JavaScript и отображается на странице без соответствующего экранирования — вредоносный скрипт может выполниться в браузере другого пользователя (XSS, Command Injection);
- используется для формирования пути к файлу без проверки на наличие «../» или аналогичных символов — злоумышленник может получить доступ к файлам вне разрешенной директории (Path Traversal/Directory Traversal).
Одна из причин возникновения подобных уязвимостей — банальная нехватка экспертизы в области безопасного кодирования. Учиться этому никто не заставляет (по крайней мере, пока), да и курсы не всегда поспевают за развитием методов злоумышленников. Но даже опытные разработчики не застрахованы от ошибок. Усталость, невнимательность, спешка и нехватка практики в работе с определенными технологиями могут приводить к небольшим ошибкам, которые со временем трансформируются в серьезные проблемы. Например, обнаруженная в 2014 г. уязвимость Heartbleed появилась в OpenSSL после оптимизации, сделанной еще в 2011-м для ускорения работы библиотеки. Ее эксплуатация давала злоумышленникам неограниченный доступ к 64 КБ оперативной памяти сервера: сразу после обнаружения Heartbleed хакеры начали массово красть SSL-ключи.
Справедливости ради надо сказать, что найти все уязвимости в коде — задача крайне сложная. Автоматизированные инструменты статического и динамического анализа просто не способны обнаружить все логические и архитектурные изъяны. В свою очередь, для проведения пентестов и аудита исходного кода нужны высококвалифицированные специалисты, а значит, дополнительные финансовые вложения. Из-за этого многие компании либо проводят недостаточно глубокие проверки, либо делают это слишком редко.
Причины бессмертия: почему уязвимости не умирают
- Устаревшие legacy-системы
Критическая инфраструктура часто работает на ПО, выпущенном десятки лет назад. Например, в российских больницах до сих пор используют Windows XP, а на заводах — протокол SMBv1, на который завязан эксплойт EternalBlue. Давно пора искать альтернативное ПО, но этот процесс может затянуться и даже привести к остановке производства, поэтому зачастую его откладывают в долгий ящик.
- Цифровые IoT-могильники
Роутеры, камеры и промышленные датчики часто не получают обновлений после выпуска. Производители закладывают срок жизни прошивок в 2–3 года, но реальный эксплуатационный период IoT-устройств может превышать 10 лет. Та же Shellshock до сих пор встречается в умных системах.
- Человеческий фактор
Сотрудники могут игнорировать патчинг по разным причинам, например:
- Страх остановить важные процессы (в частности, при обновлении «1С:Предприятия»).
- Недостаток знаний, отсутствие регламентов и плановых проверок безопасности.
- Нежелание брать ответственность («это задача ИТ-отдела — не моя проблема»).
- Цепная реакция
- Одна уязвимость может затронуть десятки взаимосвязанных приложений. Вспомните упомянутый выше пример с Log4Shell: для ее устранения нужно обновить каждый зависимый компонент.
- Экономические и бизнес-факторы
- Многие ставят в приоритет скорость вывода новых функций и отодвигают безопасность на второй план.
- Обнаружение багов и тестирование/развертывание патчей — дорогостоящий процесс. Может показаться, что для старых и некритичных систем это экономически нецелесообразно. Но только до тех пор, пока не произойдет серьезный инцидент ;)
- Предотвращенные инциденты не приносят прямой прибыли, поэтому ИБ-инициативы часто воспринимаются как затраты, а не инвестиции.
- Зачастую компании прекращают поддержку старых версий ПО, даже если они все еще используются. В итоге пользователи остаются наедине с известными, но неисправленными уязвимостями.
Spectre и Meltdown показали, что ошибки в процессорах могут «спать» десятилетиями — пока не появятся методы их эксплуатации. Другие уязвимости активируются, когда меняется окружение: как Shellshock после повального перехода бизнеса на облачные сервисы. Особую тревогу вызывают 0-day: EternalBlue разрабатывалась АНБ еще с 2012 г., но стала публичной только в 2017-м. Остается лишь гадать, сколько систем было скомпрометировано с ее помощью до этого момента...
Что делать
В борьбе с хроническими багами вам поможет следующий джентльменский набор:
- Используйте SBOM для отслеживания зависимостей и OSA/SCA для поиска уязвимостей в сторонних библиотеках. Не забывайте обновляться!
- Регулярно проверяйте написанный код SAST/DAST-инструментами.
- Сканируйте образы контейнеров и конфигурации инфраструктуры на предмет уязвимостей и мисконфигов.
- Храните секреты в соответствующих менеджерах.
- Проверяйте среду на наличие открытых портов, устаревших пакетов и т. д.
- Внедряйте в компании культуру безопасности и проводите обучение сотрудников.
В следующий раз, когда увидите запрос на обновление ПО, вспомните: где-то там может скрываться злой и совсем не сказочный баг, дремавший последние 10 лет. Клик на «напомнить позже» вполне может запустить цепную реакцию по уничтожению ваших цифровых активов.
***
В заключение хочу напомнить, что новогодние релизы — не повод для экспериментов. Залог спокойного отдыха — предсказуемость и готовность к сбоям. Надеяться на новогоднее чудо можно, но лучше все-таки соблюдать дисциплину ;)
Что стоит сделать:
- Заморозить изменения в продуктиве за 1–2 недели до праздников.
- Убедиться, что CI/CD-пайплайн стабилен, а все автотесты — зеленые.
- Усилить мониторинг и логирование (ошибки, откаты, алерты).
- Назначить дежурных и прописать план реагирования на инциденты.
Чего делать не стоит:
- Деплоить критичные изменения без rollback-плана.
- Релизить фичи без полной регрессии и проверки в staging.
- Проводить эксперименты и A/B-тесты без тщательного контроля.
- Оставлять среду без мониторинга и контроля нагрузки.
Поздравляю всех причастных с наступающим Новым годом!



