Берт Хьюберт — основатель PowerDNS, программного обеспечения, которое обеспечивает значительную часть Интернета.
Почему раздувание по-прежнему остаётся самой большой уязвимостью программного обеспечения. Призыв к бережливому программному обеспечению в 2024 годуЭтот пост посвящён памяти Никлауса Вирта, пионера компьютерных технологий, который скончался 1 января 2024 года. В 1995 году он написал влиятельную статью под названием «Призыв к экономичному программному обеспечению», опубликованную в Computer, журнале для членов IEEE Computer Society, которую я прочитал в начале своей карьеры предпринимателя и разработчика программного обеспечения. Далее я попытаюсь обосновать то же самое почти 30 лет спустя, с учётом сегодняшних компьютерных ужасов. Версия этого поста изначально была опубликована в моем личном блоге Berthub.eu.Несколько лет назад я выступил в местном университете с докладом о кибербезопасности под названием «
Кибер и информационная безопасность: мы все сошли с ума?». Это всё ещё стоит прочитать сегодня, поскольку мы все вместе
сошли с ума.
То, как мы создаём и поставляем программное обеспечение в наши дни, большей частью просто смешно. Это приводит к тому, что приложения используют миллионы строк кода, чтобы открыть дверь гаража, а другие простые программы импортируют 1600 внешних библиотек кода (зависимостей) неизвестного происхождения. Безопасность программного обеспечения ужасна, и это зависит как от качества кода, так и от его объёма. Многие из нас, программистов, знают, что текущая ситуация несостоятельна. К сожалению, многие программисты (и их руководство) никогда не сталкивались с чем-то другим. А у остальных из нас редко бывает время сделать свою работу лучше.
>>
Это касается не только вас; мы не просто страдаем от ностальгии: программное обеспечение сегодня действительно очень странное.Позвольте мне кратко остановиться на ужасном состоянии безопасности программного обеспечения, а затем потратить некоторое время на то, почему оно так плохо. Я также упоминаю некоторые нормативные и законодательные изменения, которые мы могли бы использовать, чтобы снова сделать качество программного обеспечения приоритетом. Наконец, я говорю о действительно полезной части программного обеспечения, которую я написал в качестве доказательства концепции того, что всё еще можно создавать минимальное и простое, но современное программное обеспечение.
Я надеюсь, что этот пост окажет некоторую моральную поддержку страдающим программистам и технологам, которые хотят улучшить ситуацию. Это касается не только вас; Мы не просто страдаем от ностальгии: программное обеспечение сегодня действительно очень странное.
Ужасное состояние безопасности программного обеспеченияНе вдаваясь в подробности: «
Старик (48 лет) кричит на облако», позвольте мне ещё раз констатировать некоторые очевидные вещи. Состояние безопасности программного обеспечения является ужасным. Если мы посмотрим только на прошлый год, если вы использовали стандартное программное обеспечение, такое как
Ivanti,
MOVEit,
Outlook,
Confluence,
Barracuda Email Security Gateway,
Citrix NetScaler ADC и NetScaler Gateway, скорее всего, вас взломали. Даже компании с почти бесконечными ресурсами (такие как Apple и Google) допускали тривиальные «худшие» ошибки безопасности, которые подвергли опасности их клиентов. Тем не менее, мы продолжаем полагаться на все эти продукты.
>>
Программное обеспечение сейчас (по праву) считается настолько опасным, что мы советуем всем не запускать его самостоятельно. Вместо этого вы должны оставить это провайдеру «X как услуги» или, возможно, просто «облаку». Сравните это с гипотетической ситуацией, когда вероятность возгорания автомобилей настолько высока, что советуем не управлять автомобилем самостоятельно, а предоставить это профессионалам, которых всегда сопровождают профессиональные пожарные.Программное обеспечение сейчас (по праву) считается настолько опасным, что мы советуем всем не запускать его самостоятельно. Вместо этого вы должны оставить это провайдеру «
X как услуги» или, возможно, просто «облаку». Сравните это с гипотетической ситуацией, когда вероятность возгорания автомобилей настолько высока, что советуем не управлять автомобилем самостоятельно, а предоставить это профессионалам, которых всегда сопровождают профессиональные пожарные.
Предполагается, что облако каким-то образом способно сделать небезопасное программное обеспечение заслуживающим доверия. Однако в прошлом году мы узнали, что платформа электронной почты Microsoft
была тщательно взломана, включая секретную правительственную электронную почту. (
Дважды! ) Есть и
вполне обоснованные опасения по поводу безопасности облака Azure. Между тем, любимец отрасли Okta, предоставляющий облачное программное обеспечение, позволяющее пользователям входить в различные приложения,
перешёл в полную собственность. Это было их второе нарушение за два года. Кроме того, наблюдалось подозрительное количество случаев взлома пользователей Okta.
Очевидно, нам нужно лучшее программное обеспечение.
Европейский Союз принял три законодательных акта с этой целью:
NIS2 для важных услуг; Закон
о киберустойчивости практически для всего коммерческого программного обеспечения и электронных устройств; и обновлённую
Директиву об ответственности за качество продукции, которая также распространяется на программное обеспечение. Законодательство всегда сложное, и ещё неизвестно,
правильно ли они его поняли. Но то, что безопасность программного обеспечения в наши дни настолько ужасна, что требует принятия закона, кажется очевидным.
Почему безопасность программного обеспечения так плохаЯ хочу коснуться стимулов. Сегодняшняя ситуация явно благоприятна для коммерческих операторов. Создание более безопасного программного обеспечения требует времени и больших усилий, а текущие инциденты безопасности, похоже, не влияют на прибыль или цены акций. Вы можете
ускорить выход на рынок, сокращая углы. Так что с экономической точки зрения то, что мы видим, вполне предсказуемо. Законодательство может сыграть очень важную роль в изменении этого уравнения.
Безопасность программного обеспечения зависит от двух факторов —
плотности проблем безопасности в исходном коде и огромного
количества кода, доступного хакерам. Как любили подчеркивать в 1980-х годах представители оборонного сообщества США,
количество имеет своё собственное качество. Обратное справедливо и для программного обеспечения: чем больше у вас его, тем большему риску вы подвергаетесь.
Например, пользователи Apple iPhone неоднократно подвергались взлому на протяжении многих лет из-за огромной поверхности атаки, открытой iMessage. Можно отправить незапрошенное iMessage пользователю Apple. Телефон немедленно обработает это сообщение и сможет просмотреть его. Проблема в том, что Apple мудро решила, что такие нежелательные сообщения должны поддерживать широкий спектр форматов изображений, случайно
включая PDF-файлы со странными встроенными сжатыми шрифтами, использующими древний формат, который фактически включал язык программирования. Таким образом, кто-то может отправить на ваш iPhone незапрошенное сообщение, которое поможет выявить слабые места в остальной части телефона.
Таким образом, злоумышленники смогли извлечь выгоду из ошибок безопасности в миллионах строк кода телефона. Вам не нужна высокая плотность ошибок, чтобы найти
уязвимую дыру в миллионах строк кода.
>>
Устранение всех ошибок в вашем коде не избавит вас от решения реализовать функцию автоматического выполнения кода, встроенного в документы.Apple могла бы предотвратить эту ситуацию, ограничив предварительный просмотр гораздо меньшим диапазоном форматов изображений или даже одним «известным хорошим» форматом изображения. Apple могла бы избавить себя от огромного количества проблем, просто предоставив злоумышленникам
меньше строк своего кода. Между прочим, Закон ЕС о киберустойчивости
прямо предписывает поставщикам минимизировать поверхность атаки.
Apple (безусловно) не самый худший нарушитель в этой области. Но это широко уважаемая и хорошо обеспеченная ресурсами компания, которая обычно тщательно продумывает то, что делает. И даже они ошиблись, напрасно выпустив и выставив слишком много кода.
Можем ли мы написать лучший код?Есть те, кто считает, что самая большая проблема — это качество кода, выраженное в плотности ошибок в нём. На этом фронте происходит много интересных вещей, таких как использование
безопасных для памяти языков, таких как
Rust. Другие языки
также повышают уровень безопасности.
Фаззеры — инструменты тестирования, которые автоматически изменяют входные данные компьютерных программ для поиска слабых мест и ошибок — также становятся всё более совершенными.
Но многие проблемы безопасности кроются в логике, лежащей в основе кода. Например, эксплойт электронной почты Barracuda возник в сторонней библиотеке, которая фактически
выполняла код в электронных таблицах Excel при их сканировании на наличие вирусов. Устранение всех ошибок в вашем коде не избавит вас от решения реализовать функцию автоматического выполнения кода, встроенного в документы.
Состояние поставки программного обеспеченияДругая проблема заключается в том, что мы часто не знаем, какой код на самом деле отправляем. Программное обеспечение стало
огромным. В 1995 году
Никлаус Вирт посетовал, что размер программного обеспечения вырос до мегабайт. В своей статье «Призыв к экономичному программному обеспечению» он описал свою
операционную систему Oberon, размер которой составлял всего 200 килобайт, включая редактор и компилятор. Сейчас существуют проекты, размер файлов конфигурации которых превышает 200 КБ.
Типичное приложение сегодня построено на
Electron JS, платформе, включающей в себя как Chromium («Chrome»), так и Node.JS, которая обеспечивает доступ к десяткам тысяч программных пакетов для JavaScript. По моим оценкам, простое использование Electron JS требует не менее 50 миллионов строк кода, если вы включаете зависимости. Возможно, больше. Тем временем приложение, вероятно, содержит сотни или тысячи вспомогательных пакетов. Многие используемые пакеты также по умолчанию будут передавать информацию о ваших пользователях рекламодателям и другим брокерам данных. Зависимости влекут за собой дополнительные зависимости, и что именно включается в сборку, может меняться ежедневно, и никто точно не знает.
Если это приложение контролирует что-либо в вашем доме, оно также будет подключаться к стеку программного обеспечения на
Amazon, вероятно, также работающему на Node.js, что также включает множество зависимостей.
>>
Вероятно, мы рассматриваем более 50 миллионов активных строк кода, позволяющих открыть дверь гаража, запуская несколько образов операционной системы на нескольких серверах.Но подождите, это еще не всё. Раньше мы поставляли программное обеспечение как результат работы компилятора или, возможно, как набор файлов для интерпретации. Такое программное обеспечение затем необходимо было
установить и
настроить для правильной работы. Упаковать код для отправки в таком виде — это большая работа. Но это была хорошая работа, поскольку она заставила людей задуматься о том, что было в их «посылках». Этот пакет программного обеспечения затем будет интегрироваться с операционной системой и локальными службами в зависимости от конфигурации.
Поскольку программное обеспечение работало на другом компьютере, а не на том, на котором оно было разработано, людям действительно нужно было знать, что они поставляют, и тщательно это продумывать. А иногда это не срабатывало, что приводило к шутке, когда разработчик говорит специалистам по эксплуатации: «Ну, в моей системе это работает», а затем отвечает: «Тогда создайте резервную копию вашей электронной почты, мы запустим ваш ноутбук в производство!»
Раньше это была шутка, но в наши дни мы часто поставляем программное обеспечение в виде контейнеров, поставляя не только само программное обеспечение, но также включая файлы операционной системы, чтобы гарантировать, что программное обеспечение работает в хорошо известной среде. Зачастую это влечёт за собой доставку полного образа компьютерного диска. Это снова значительно увеличивает объём развёртываемого кода. Обратите внимание, что с контейнерами типа Docker можно делать хорошие вещи (см. ниже), но на
Docker Hub много образов размером более 350 МБ.
>>
В мире выпускается слишком много кода, и мы даже не знаем, что поставляем, и недостаточно внимательно (или вообще не) присматриваемся к тому, что, как мы знаем, поставляем.Сложите всё это, и мы, вероятно, получим более 50 миллионов активных строк кода, позволяющих открыть дверь гаража и запускающих несколько образов операционной системы на нескольких серверах.
Теперь, даже если все включенные зависимости являются золотыми, уверены ли мы, что их обновления безопасности попадут в ваше приложение для открывания гаражных ворот? Интересно, сколько приложений Electron до сих пор поставляются с
ошибкой обработки изображений, из-за которой Google и Apple в прошлом году пытались выпустить обновления? Мы даже не знаем.
Но что ещё хуже, это известный факт, что все эти зависимости
не являются золотыми. Экосистема Node.js имеет
комичную историю, когда репозитории пакетов
были захвачены, взломаны или воскрешены под тем же именем кем-то другим,
кто-то с гнусными планами по обеспечению вашей безопасности.
PyPI (аналог Node.js на Python) страдает от
аналогичных проблем. Зависимости всегда требуют тщательного изучения, но никто не может разумно ожидать, что они будут
часто проверять тысячи из них. Но мы предпочитаем об этом не думать. (Обратите внимание, что вам также не следует переусердствовать и без необходимости переопределять всё самостоятельно, чтобы предотвратить зависимости. Существуют очень хорошие модули, которые,
вероятно, более безопасны, чем те, которые вы можете ввести самостоятельно.)
В мире выпускается слишком много кода, и мы даже не знаем, что поставляем, и недостаточно внимательно (или вообще не) присматриваемся к тому, что, как мы знаем,
поставляем.
Вы можете писать экономичный код уже сегодняВ небольшой реконструкции проекта Вирта «Оберон» я написал некоторый код, чтобы доказать свою точку зрения и убедить себя, что я всё ещё знаю, о чем говорю и пишу. Можете ли вы по-прежнему создавать полезное и современное программное обеспечение старым способом? Я решил попытаться создать минималистичное, но полнофункциональное решение для обмена изображениями, которому я мог бы доверять.
Трифекта – это результат. Это
настоящее автономное программное обеспечение, которое позволяет вам использовать браузер для перетаскивания изображений для удобного обмена ими. Меня годами мучило то, что мне приходилось использовать
imgur для этой цели. Imgur не только устанавливает множество файлов cookie и трекеров в мой браузер, я также навязываю эти трекеры людям, которые просматривают изображения, которыми я делюсь. Если вы хотите самостоятельно разместить такой веб-сервис, вы также не хотите, чтобы вас взломали. Большинство решений для обмена изображениями, которые, как я обнаружил, вы можете запустить самостоятельно, основаны на огромных платформах, которым я не слишком доверяю по причинам, изложенным выше.
Итак, чтобы подчеркнуть свою точку зрения, я решил создать минималистичное, но в то же время полезное решение для обмена изображениями, которому я мог бы доверять. И что ещё более важно, чтобы другие люди тоже могли доверять, потому что вы можете проверить весь код Trifecta за несколько часов. Он состоит
из 1600 строк нового исходного кода, а также около пяти важных зависимостей.
В итоге вы получите в общей сложности 3 мегабайта кода.
Напротив,
ещё одно решение для обмена изображениями поставляется в виде образа Docker размером 288 МБ, хотя, по общему признанию, оно выглядит лучше и имеет некоторые дополнительные функции. Но их размер не составляет 285 МБ. Ещё одно сравнение —
это решение для обмена изображениями на базе Node, которое насчитывает 1600 зависимостей, что, по-видимому, составляет более 4 миллионов строк JavaScript.
>>
В мире поставляется слишком много кода, большая часть которого написана третьими лицами, иногда непреднамеренно, большая часть не проверяется. Из-за этого существует огромная поверхность атаки, полная посредственного кода.Обратите внимание, что Trifecta не задуман как общедоступный сайт, на котором случайные люди могут обмениваться изображениями, поскольку это обычно не заканчивается хорошо. Однако он очень подходит для корпоративного или личного использования. Подробнее о проекте можно прочитать
здесь, а также есть
страница о технологии, используемой для доставки такого крошечного автономного решения.
Ответ на TrifectaЭто было довольно интересно. До сих пор наиболее распространённой реакцией на Trifecta было то, что для её развёртывания мне следует использовать целый пакет веб-сервисов Amazon. Это чрезвычайно странный ответ на проект с чётко сформулированной целью предоставления автономного программного обеспечения, не зависящего от внешних сервисов. Я не уверен, что здесь происходит.
Другая реакция заключалась в том, что я несправедливо отношусь к Docker и что контейнеры определённо можно использовать во благо. И я полностью согласен. Но я также смотрю на то, что на самом деле делают люди (также с другими формами контейнеров или виртуальных машин), и это не так уж и здорово.
Я хочу закончить этот пост некоторыми наблюдениями из
статьи Никлауса Вирта 1995 года:
«Для некоторых сложность равна силе. (…) Люди всё чаще ошибочно интерпретируют сложность как изысканность, что сбивает с толку: непостижимое должно вызывать подозрение, а не восхищение».Я также заметил, что некоторые люди предпочитают сложные системы. Как давно заметил
Тони Хоар: «Существует два метода проектирования программного обеспечения.
Один из них — сделать программу настолько простой, чтобы в ней явно не было ошибок. Другой — сделать это настолько сложным, чтобы не было очевидных ошибок». Если вы не умеете делать первый вариант, второй способ, возможно, станет выглядеть ужасно привлекательным.
Вернёмся к Вирту:
«Недостаток времени, вероятно, является основной причиной появления громоздкого программного обеспечения. Нехватка времени, с которой сталкиваются дизайнеры, препятствует тщательному планированию. Это также препятствует улучшению приемлемых решений; вместо этого он поощряет быстро продуманные дополнения и исправления программного обеспечения. Нехватка времени постепенно подрывает стандарты качества и совершенства инженеров. Это оказывает пагубное воздействие как на людей, так и на продукты».Зачем тратить недели на сокращение программного обеспечения, если вы также можете предоставить целый образ предустановленной операционной системы, который просто работает?
«Чума, вызванная взрывом программного обеспечения, не является «законом природы». Этого можно избежать, и задача инженера-программиста — сократить его».Если это действительно лежит на плечах специалистов по программному обеспечению, возможно, нам следует потребовать для этого больше времени.
В мире поставляется слишком много кода, большая часть которого написана третьими лицами, иногда непреднамеренно, большая часть не проверяется. Из-за этого существует огромная
поверхность атаки, полная посредственного кода. Продолжаются усилия по улучшению качества самого кода, но многие эксплойты происходят из-за логических сбоев, и в их сканировании достигнут меньший прогресс. Между тем, можно было бы добиться больших успехов, сократив объём кода, который мы раскрываем миру. Это увеличит время вывода продуктов на рынок, но не за горами закон, который должен заставить поставщиков более серьёзно относиться к безопасности.
Trifecta, как и упомянутый выше проект Вирта «Оберон», задуман как доказательство того, что вы можете предоставить большую функциональность даже с ограниченным количеством кода и зависимостей. Если приложить усилия и принять законодательство, возможно, в будущем снова появится возможность открывания гаражных ворот кодом менее 50 миллионов строк. Давайте попробуем воплотить это в жизнь.