Эта небольшая заметка является промежуточным итогом на тему поиска уже известных уязвимостей в open source C# проектах. Я хотел посмотреть на примеры кода, который бы являлся уязвим и был причиной появления очередной CVE, но оказалось, что не всё так просто…
Предыстория (уязвимости в C/C++ проектах)
Я уже сталкивался с подобной задачей касаемо языков программирования C и C++, и хотел бы сделать небольшую отсылку к проделанной ранее работе, чтобы суть вопроса, вынесенного в заголовок, стала более понятна.
Вдаваться в детали не буду, расскажу в нескольких предложениях. Предыдущая цель была аналогичной — посмотреть, какие CVE были обнаружены в open source C/C++ проектах, и выяснить, может ли PVS-Studio находить подобные проблемы. По результатам работы я нашёл несколько интересных уязвимостей (а если бы продолжил работу в этом направлении, уверен, нашёл бы ещё больше), появления которых можно было бы предотвратить, используя PVS-Studio. Эксперимент закончился удачно, и на его основе я написал статью "Как PVS-Studio может помочь в поиске уязвимостей?".
Удобным было то, что в описании CVE часто фигурировали ссылки на коммиты, закрывающие уязвимость. Таким образом, просматривая историю изменений кода, можно было понять, в чём заключается уязвимость, и каким образом она была закрыта. В итоге задача сводилась примерно к тому, чтобы среди таких исправлений найти что-то интересное.
Подводя итог вышесказанному, можно выделить несколько пунктов, которые определяют CVE, удобную для проверки:
- Содержит ссылку на исходный код (до и после исправлений).
- Коммит является локальным, то есть не 'размазан' по нескольким файлам, а затрагивает вполне определённое место.
- Код в этом месте связан с использованием каких-то общедоступных средств, а не специфичных для конкретного проекта (например, каких-то функций, заменяющих их стандартные аналоги).
- Уязвимость не является следствием специфичной ошибки в логике работы приложения.
Если CVE отвечает этим требованиям, скорее всего она будет доступна для обнаружения с помощью статического анализа исходного кода.
Уязвимости в C# проектах
В направлении поиска уязвимостей в open source C# проектах я предпринимал несколько заходов с различных сторон, но все они не принесли ожидаемого результата.
Основными информационными средствами, на которые я ориентировался, были база CVE и сайт CVE Details (а также Google, GitHub, reddit, StackOverflow).
Вот основные подходы, которые я использовал:
- Поиск наиболее популярных C# проектов с GitHub в базе CVE. C# проекты на GitHub были отсортированы по количеству 'звёздочек', после чего я 'пробил' по базе CVE порядка 100 проектов — большая их часть даже не упоминается.
- Была написана небольшая утилита, которая просканировала базу CVE, нашла все ссылки на GitHub (их оказалось больше 5000), и 'выцепила' из них те, которые являлись ссылками на коммиты, затрагивающие C# (.cs) файлы. На моё удивление, таких ссылок оказалось всего 8! Этого явно было недостаточно. Кроме того, не все коммиты подходили под описанные в предыдущем разделе критерии «оптимальности».
- Поисковым запросом на GitHub среди issues всех C# проектов с количеством 'звёзд' больше 10 выбрал те, которые в названии, теме или комментариях содержали слово «CVE». Опять мимо — в большинстве случаев конкретные CVE не рассматривались, либо не было ссылок на коммиты с исправлениями.
- Перебирал проекты из списка .NET Open Source Developer Projects. Искал их в базе CVE, на сайте CVE Details, в Google.
- Прошёлся по базе CVE поиском по определённым ключевым словам, вроде C# или .Net.
- Поиск в Google по идентификаторам различных CVE из базы CVE и с сайта CVE Details.
- Дополнительно искал в Google информацию по различным поисковым запросам, связанным с уязвимостями C# / .Net и open source проектами.
К моему большому удивлению, все эти подходы не принесли ожидаемого результата — было найдено крошечное количество уязвимостей, в которых были бы также ссылки на исходный код, чтобы можно было точно понять суть проблемы.
Имея опыт подобной работы с проектами на C/C++ меня вот что удивило:
- Малое количество задокументированных уязвимостей С# проектов в базе CVE в принципе. Неужели C# проекты почти не подвержены уязвимостям? Не очень верится. Или просто уязвимости в C# коде не документируются/афишируются, поэтому их так мало в базе CVE?
- Уязвимость есть в базе CVE, есть ссылка на релиз, в котором уязвимость была закрыта (что само собой уже подтверждает её наличие), но при этом нет никаких упоминаний уязвимого кода, даже при том, что это open source проект! Повторюсь, в C/C++ проектах, как правило, были ссылки на конкретные коммиты, закрывающие уязвимости. Т.е. разработчики сообщали не только о том, что уязвимость была закрыта, но и демонстрировали саму проблему и способ её решения.
Заключение
В общем, я был удивлён таким положением дел в отношении уязвимостей в C# проектах. Почему их так мало? Почему мало примеров уязвимостей, которые были закрыты?
Ситуация действительно такая, какая есть? Или был какой-то изъян в моих подходах, которые не позволили получить необходимого результата?
Если у вас есть примеры разбора уязвимого кода (задокументированного, то есть, имеющего идентификатор CVE) или вы заметили какой-то явный изъян в моём подходе, не позволивший получить ожидаемых результатов, прошу написать мне на почту — vasiliev@viva64.com, с интересном прочитаю ваши предложения/замечания.
Список найденных уязвимостей
Ниже я привожу список тех уязвимостей, которые бы имели и идентификатор CVE, и примеры уязвимого кода. Возможно, они будут кому-то интересны/полезны. Также, если вы хотите предложить в письме ссылку на пример кода уязвимостей, пожалуйста, посмотрите, не встречается ли идентификатор этой уязвимости в нижеприведённом списке.
- CVE-2017-15280
- CVE-2017-15279
- CVE-2015-8814
- CVE-2015-8813
- CVE-2013-6795
- CVE-2012-3382
- CVE-2011-0991
- CVE-2015-2526
- CVE-2016-0132
- CVE-2017-8759
- CVE-2017-8585
Если хотите поделиться этой статьей с англоязычной аудиторией, то прошу использовать ссылку на перевод: Sergey Vasiliev. What Is Wrong with Vulnerabilities in C# Projects?
Комментарии (27)
F0iL
31.10.2017 11:31+3А почему вас смущает малое количество уязвимостей в проектах на C#? Это же особенность самой платформы — «управляемый» код в виртуальной машине, отсутствие сырых указателей, отлов переполнений, некорректных преобразований типов и выходов за границы массивов средой исполнения, и многое многое другое — даже если разработчик от души наделает ошибок при кодировании (не считая именно логических ошибок, типа хранения паролей в нехэшированном виде или неправильных условий в if'ах), в большинстве самое худшее что может случиться — необработанное исключение и никаких там remote code execution.
А при веб-разработке, сам фреймворк во многих случаях фильтрует CSRF, XSS, ORM-библиотека экранирует входные данные, и т.д., что тоже сильно снижает требования к уровню разработчика и вероятность по невнимательности оставить дыру.Areldar
31.10.2017 13:05+2Мне кажется основной посыл не малое количество уязвимостей в C# проектах, а их плохое оформление. То есть одно дело когда уязвимостей в базе мало, но те, что есть оформлено хорошо, другое дело когда уязвимостей в базе мало, а те что есть оформлены абы как.
staticlab
31.10.2017 13:25Тогда почему в 4 приведённых фиксах уязвимостей в Umbraco — XXE, XSS, XSRF, XSRF?
F0iL
31.10.2017 14:25Да, всегда можно реализовать что-то не по «лучшим практикам», всегда можно навернуть свой костыль для каких-то целей, или же просто оказаться в ситуации, которую не предусмотрели авторы фреймворка. Да и в самом C#, к примеру, можно упороться unsafe-методами и маршаллингом структур и отстрелить себе обе ноги, но необходимость в этом возникает крайней редко.
Я не говорил что уязвимости невозможны в приципе, я говорил что многое сделано для сокращения их возможного числа.staticlab
31.10.2017 15:25Так получается, что, с одной стороны, разработчики фреймворков и библиотек снижают сложность предотвращения уязвимостей, а с другой, это снижает требования к уровню разработчика, в результате чего вероятность багов и уязвимостей, наоборот, повышается.
mayorovp
31.10.2017 13:08+1CVE-2017-15280 — это давно уже не уязвимость. Потому что XXE через XmlTextReader с настройками по умолчанию закрыли в .NET 4.5.2, за три года до 2017го...
slonopotamus
31.10.2017 20:16+1Эмм… Может на C# тупо мало софта и не в чем искать уязвимости? На типичном не-Windows компьютере (включая мобилы-планшеты) софта на шарпе примерно ноль.
Наверняка в программах на D, Cobol, SmallTalk, Haskell тоже мало CVE.
kekekeks
31.10.2017 21:30Касательно уязвимостей.
Им в дотнете взяться особо неоткуда. Управляемый код со строгой статической типизацией перекрывает большинство классических проблем, так что выстрелить себе в ногу намного сложнее. Из потенциально дырявых технологий могу назвать разве что Remoting, которым уже лет 10 как не пользуются.
Остаются в основном штуки связанные с вебом, но и там можно поймать разве что XSS — SQL-инъеккциям тоже неоткуда взяться, ибо все используют LINQ.enzain
31.10.2017 22:45Вот вообще не очень понимаю, что все в этот LINQ упоролись…
От слова — совсем… даже вон — товарищь по оптимизации, один из разрабов дотнет писал — что таки линком не стоит особо сильно увлекаться…kekekeks
31.10.2017 23:08+1Это Entity Framework-ом не стоит особо увлекаться, ибо тормозит из-за своего change-tracking-а. Нормальные реализации типа linq2db (не путать с linq2sql) по производительности сравнимы с ручным написанием запросов.
Это касательно доступа к БД. Манипуляции же с объектами внутри процесса, там да, можно использованием LINQ себе производительность хорошо так просадить. В особо терминальных случаях его запускают поверх байтмассивов, а потом удивляются, чому оно работает на 4-5 порядков медленнее вручную написанного цикла.
enzain
01.11.2017 09:30Ну, там где я читал — речь шла про LINQ в принципе, хотя — может быть не применительно к базам, опять же, а манипуляций с объектами… К сожалению не могу найти статью тут на хабре....
lair
01.11.2017 00:08Потому что мощная и удобная штука.
enzain
01.11.2017 09:31Мощьная и удобная — понятие субъективное
Мне например коннекты и датасеты — удобнее, как не крути… :)
lair
01.11.2017 11:32Вот именно потому, что субъективная, вы и не понимаете.
(правда, надо заметить, что статическая типизация и AST — вещи все-таки объективные, ну не суть)
enzain
02.11.2017 09:39Удобная и мощная != производительная.
Суть моего высказывания была в этом.lair
02.11.2017 11:49Ну так любят и не за производительность (хотя в умелых руках производительность LINQ, как бы бессмысленно эта фраза не звучала, достаточна).
enzain
02.11.2017 15:03На вкус и цвет, все фломастеры разные.
Некоторые мои коллеги/знакомые считают на полном серьезе что производительность — не их забота, главное побыстрее сдать заказ и получить бабла. А производительность… ну, купит заказчик новый сервер за пару лимонов, и будет все хорошо с производительностью :)lair
02.11.2017 15:33На вкус и цвет, все фломастеры разные.
Ну так это и есть субъективная характеристика.
Csharper101
01.11.2017 10:58А чем linq вам не нравится? Не сложные запросы на нем можно писать и очень даже удобно, а для более сложных запросов можно написать sql-запрос
vuser
01.11.2017 10:58Microsoft C# — очень хороший пример качественной реализации C# и IL транскомпиляции вообще. Безопасность типов реализуется так, что в принципе, ошибки не являются критическими.
kwardakov
01.11.2017 10:58Исходя из моих наблюдений, общество C# разработчиков имеет больше вертикальных связей и меньше горизонтальных, за счет этого больше фрагментировано.
Идеи и хорошие практики распространяются медленнее, ну и вообще вкладываться в OSS у дотнетчиков — редкость.
questor
Больше похоже на вступление к статье, чем на саму статью.