Часть 1. Глава 6. Ошибки у всех на виду

Сергей Васильевич Виноградов
Как известно, сторонники ПО с открытыми исходными кодами часто говорят, что если исходники смотрят много глаз, то ошибки всегда на виду, "всплывают вверх" и исправляются.
Это повторяют как мантру. Это и есть мантра, запущенная пропагандой, скорее всего, Агентства Национальной Безопасности США.

Очень приятно, когда вместо того, чтобы заботиться о безопасности исходных кодов, все подряд просто повторяют, что ошибки у всех на виду. То есть ничего делать не надо, они сами исправятся. АНБ может вносить множество ошибок или просто искать уже существующие, а чтобы они подольше существовали говорить, что "они у всех на виду". Таким образом, мы очень редко слышим об аудитах безопасности ПО с открытым исходным кодом.

Почему-то даже, вроде бы, опытные специалисты часто повторяют эту мантру. Есть какое-то в ней волшебство. Как и в мантре монетаристской экономической теории о том, что рынок сам всё урегулирует.
Что в этом волшебного?

Волшебство в том, что прилетит вдруг волшебник. А нам ничего делать не надо. Он сам прилетит и на своём вертолёте. Да ещё с мороженным.
Однако, практика показывает, что ошибки, причём довольно глупые, живут, иногда, и годами, и даже существенно больше десяти лет. В том числе, и ошибки безопасности. Ошибка в GNU PG, при которой по известному ключу шифрования RSA 4096 битов можно определить сгенерированный следом за ним ключ 256-ти битного шифрования тому пример. Ошибке 18-ть лет, если не ошибаюсь. Причём, по некоторой информации, АНБ знало о ней по крайней мере несколько лет до её исправления.

Удивительна та лёгкость, с которой люди подпадают под всякие "волшебные" обещания. То рынок у них всё за них сделает, то некое сообщество, само по себе, ошибки найдёт.
Я, в своей практике, видел известное ПО с открытыми исходниками, в котором, буквально в 5-10 строчках кода было сконцентрировано сразу 3 дефекта (правда, не безопасности). Причём, когда я читал эти строки, уже зная, что там ошибка, я никак не мог понять, где она.
Хотя ошибка была именно в этих строках. Не в сложном взаимодействии компонентов, ни в каких-то сложных особенностях сетевых протоколов или их реализаций. Просто так всё было запрограммировано в небольшом куске кода.
Программисты, работающие за зарплату, многократно пытались исправить этот участок, однако безуспешно. Всё время вылезал хотя бы один дефект. Так повторялось годами.
Часто бывает, что один и тот же дефект исправляется и снова появляется. Тоже годами.

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


Когда-то один из менеджеров клиента фирмы, где я работал, на полном серьёзе убеждал меня в том, что можно провести аттестацию безопасности объекта информатизации по требованиям ФСТЭК (Федеральной службы по техническому и экспортному контролю) без сертификации используемых там СЗИ (Средств Защиты Информации).
Я даже спрашивал у руководящего работника ФСТЭК, можно ли это. Оказалось, что нет, нельзя.
Когда я сказал об этом тому менеджеру, он ответил: "а зачем им рассказывать о такой возможности?". Фирма, которая их обслуживала, навешала им лапши на уши, что всё можно, что они договорятся, у них там связи.
И менеджеру легче было просто поверить на слово и чувствовать себя беззаботно, чем разбираться в проблеме. Вот такой вот отсосинг информационной безопасности.


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


Далее. Даже если ПО сертифицируется и имеет правильно сделанную программу вознаграждений за найденные уязвимости, с высокими премиями, с независимым авторитетным арбитражом и т.п. Даже если ПО полностью формально верифицируется на соответствие требованиям, всё равно могут быть проблемы.
Проблема в том, что требования никто не сертифицирует. Требования могут содержать, например, недостаточную функциональность СЗИ. Которая повлечёт за собой худшую защиту информации. Или, требования могут содержать правильные, но слишком сложные способы настройки СЗИ. Такие, что СЗИ, установленная на реальную систему, практически всегда будет настроена неверно. То есть вся её формальная корректность пойдёт коту ректально, так как неверные настройки оставят бреши в безопасности.

Представим себе один такой пример.
У нас есть МСЭ - межсетевой экран. Он должен разграничивать работу приложений с сетью. У нас есть приложение, которое обращается к крупной CDN (Content Distribution Network), которая осуществляет распространение контента для этого приложения (например, обновлений).
Допустим, доменное имя для обновлений приложения "updates.app.good" . Мы его знаем и хотим разрешить в МСЭ.
Однако, МСЭ проверяет пакеты на уровне TCP/IP, и там нет доменных имён. Поэтому, он разрешит доменное имя "updates.app.good" в IP-адреса. Однако, в связи с тем, что у CDN могут быть крупные подсети, DNS каждый раз может указывать разные IP адреса. То есть приложение будет пытаться получить обновление не с тех IP, которые известны МСЭ.
Таким образом, МСЭ запретит вполне легальные обновления. Узнать весь возможный диапазон постоянно меняющихся IP-адресов не представляется возможным. Значит, нам нужно разрешить все возможные подсети CDN. Однако, этими подсетями может пользоваться и злоумышленник, ведь CDN предоставляет услуги любому заплатившему. Получается, что мы разрешили и доступ приложения к IP-адресам злоумышленника.

Получилось, что отсутствие соответствующей возможности в МСЭ и присутствие возможности в прикладном приложении повлекло за собой снижение уровня разграничения доступа к сети и возможность доступа приложения к вредоносным IP прямо через МСЭ. Притом, что МСЭ может быть сколько угодно сертифицирован по нормативным требованиям ФСТЭК.


Ещё один пример проблем с сертификацией. Такие языки, как C и C++, заведомо небезопасные. Они провоцируют программиста на использование "сырых" структур данных, таких как указатели на массив без возможности со стороны компилятора к проверке выхода за границы этого массива. Однако никакая сертификация не запрещает писать на этих языках. Также как никакая сертификация не предъявляет требования и не даёт преимуществ при сертификации системам, написанным на безопасных языках. Да и безопасных языков, как таковых, нет. Функции безопасности в них мизерные.


Ещё один пример архитектурной закладки.
Представим себе, что у вас есть браузер. Например, FireFox от компании Mozilla.
Где-то между 40-ой и 50-ой версией Mozilla начали менять схему дополнений для браузера так, что дополнениям сильно ограничили функциональность.
Якобы, это было сделано с целью повышения безопасности пользователя, так как дополнения будут более ограниченными.

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

Вторая проблема.
Современные браузеры сплошь и рядом работают по схеме https. То есть шифруют трафик. Поэтому перехватить трафик и посмотреть, что они посылают, сложно. Мало того, браузер это заметит. И, даже если ранее он посылал какую-либо конфиденциальную информацию куда-либо, при обнаружении прослушивания он может перестать это делать.

А вы думаете, что всеобщий переход на https нужен для повышения безопаности?
Как бы не так!
Он нужен АНБ, чтобы шифровать ваши данные, которые они забирают к себе на компьютеры.


Но это вводная.
Дело в том, что ранее, legacy API для дополнений в FireFox, позволял им просматривать содержимое всего траффика, в том числе и служебного. И просмотр был именно траффика до его шифрования. Таким образом, дополнение могло контролировать траффик, причём делать это относительно незаметно для браузера. В WebExtensions так возможности не осталось. Конец обеда.
Теперь дополнение не может контролировать траффик. Пользователь не имеет внутрибраузерных инструментов. Инструменты во-вне браузера обнаруживаются средствами протокола TLS (https), то есть средствами криптографии.

То есть, проконтролировать, что FireFox не шлёт теперь лишние данные, невозможно. В нём могут быть закладки от АНБ (NSA - National Security Agency), но мы о них не узнаем.

Да, конечно. Это браузер с открытыми исходными кодами. Однако, вы часто контролируете эти коды?
И вы собираете браузер непосредственно из исходников?

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


Третья проблема.
WebExtensions не содержат многих функций, которые нужны для работы дополнений, способных обеспечивать полноценное экранирование на уровне браузера. Таким образом, если ранее СЗИ можно было встроить прямо в браузер на уровне дополнения, то теперь это СЗИ не имеет практически никаких серьёзных полномочий. А значит, браузер, опять же, может творить, что хочет. И сайты, кстати, тоже.


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

Чтобы усугубить проблему, Mozilla ввели обязательную функцию подписывания дополнений (не помню точно, кажется, в версиях 30 и выше).
Теперь вообще никакие дополнения никак не могли быть установлены в Mozilla FireFox просто так, без разрешения Mozilla.
Даже если я сам на своём компьютере разработал дополнение, я не могу его установить в FireFox на своём компьютере. Внегалерейные версии тоже надо было загружать на сайт Mozilla.

Это существенно ухудшило возможности отладки под постоянно меняющиеся версии. Особенно в переходный период, когда все эти функции уже стали обязательными, но Mozilla в своей заносчивости, не реализовало полностью все возможности по тестированию и подпсыванию. Внегалерейные версии дополнений какое-то время тоже не могли нормально распространяться. То есть сложные дополнения становились неработоспособными.

Однако, дополнения всё ещё были. Затем Mozilla решила окончательно задавить их.
Безо всяких обсуждений было решено перейти на WebExtensions и закрыть старое API для дополнений. Хотя высшее руководство лживо обещало, что все нужные функции будут реализованы и в новом WE, реально запросы на функции, даже когда их просили десятки разработчиков, отклонялись без обсуждения с аргументацией на уровне "эта не та функция, которую мы хотели бы видеть в WebExtensions". То есть все запросы были отклонены тем, что они "не хотят". Дальнейшие споры бесполезны. Они не хотят и всё тут. Не хочешь молчать - забаним. Один из пользователей даже в знак протеста рассылал рассылки на несколько тысяч адресов Mozilla с ругательствами, пока какие-то из его требований не были удовлетворены. Однако, принципиально, осталось всё, как прежде.


Даже если бы WebExtensions содержали бы нужную функциональность, новые изменения были настолько широки, что дополнения пришлось бы переписывать, и очень сильно. А они, как вы понимаете, были бесплатными.
Ресурсов на такое массирование переписывание не было. Поэтому часть дополнений просто умерло даже не попытавшись дёрнуться на переписывание десятков тысяч строк кода запросто так.


Вот так вот Mozilla выступила за свободный, безопасный и приватный интернет, о котором они тогда писали прямо на главной странице сайта.


Мораль сей басни такова. Если вы используете чужие технологии, даже ещё развивающиеся - вы не можете надеяться ни на что.
Каждую минуту вы можете слететь с рельс, потому что гигант, на которого вы опираетесь (ваши рельсы), повернули совсем не в ту сторону. И вы совсем, очень не хотите туда, куда оин вас везут. А Mozilla, Microsoft, Google, Apple и другие лидеры отрасли просто плюют на ваши потребности и интересы.

Можно сколько угодно сертифицировать любые СЗИ, проверять открытые коды и так далее, но если стратегическая инициатива в руках противника, мы не победим.
Мы можем опираться только на свои технологии. Как только опираемся на чужие, они нас могут подвести. К сожалению, написать многие вещи с нуля просто не получается.