Что не так с уязвимостями в C# проектах?



    Эта небольшая заметка является промежуточным итогом на тему поиска уже известных уязвимостей в 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, и примеры уязвимого кода. Возможно, они будут кому-то интересны/полезны. Также, если вы хотите предложить в письме ссылку на пример кода уязвимостей, пожалуйста, посмотрите, не встречается ли идентификатор этой уязвимости в нижеприведённом списке.




    Если хотите поделиться этой статьей с англоязычной аудиторией, то прошу использовать ссылку на перевод: Sergey Vasiliev. What Is Wrong with Vulnerabilities in C# Projects?

    Прочитали статью и есть вопрос?
    Часто к нашим статьям задают одни и те же вопросы. Ответы на них мы собрали здесь: Ответы на вопросы читателей статей про PVS-Studio, версия 2015. Пожалуйста, ознакомьтесь со списком.
    PVS-Studio
    1,036.59
    Static Code Analysis for C, C++, C# and Java
    Share post

    Comments 28

      +11

      Больше похоже на вступление к статье, чем на саму статью.

        +24
        А почему вас смущает малое количество уязвимостей в проектах на C#? Это же особенность самой платформы — «управляемый» код в виртуальной машине, отсутствие сырых указателей, отлов переполнений, некорректных преобразований типов и выходов за границы массивов средой исполнения, и многое многое другое — даже если разработчик от души наделает ошибок при кодировании (не считая именно логических ошибок, типа хранения паролей в нехэшированном виде или неправильных условий в if'ах), в большинстве самое худшее что может случиться — необработанное исключение и никаких там remote code execution.
        А при веб-разработке, сам фреймворк во многих случаях фильтрует CSRF, XSS, ORM-библиотека экранирует входные данные, и т.д., что тоже сильно снижает требования к уровню разработчика и вероятность по невнимательности оставить дыру.
          +8
          Мне кажется основной посыл не малое количество уязвимостей в C# проектах, а их плохое оформление. То есть одно дело когда уязвимостей в базе мало, но те, что есть оформлено хорошо, другое дело когда уязвимостей в базе мало, а те что есть оформлены абы как.
            +3

            Тогда почему в 4 приведённых фиксах уязвимостей в Umbraco — XXE, XSS, XSRF, XSRF?

              +3
              Да, всегда можно реализовать что-то не по «лучшим практикам», всегда можно навернуть свой костыль для каких-то целей, или же просто оказаться в ситуации, которую не предусмотрели авторы фреймворка. Да и в самом C#, к примеру, можно упороться unsafe-методами и маршаллингом структур и отстрелить себе обе ноги, но необходимость в этом возникает крайней редко.
              Я не говорил что уязвимости невозможны в приципе, я говорил что многое сделано для сокращения их возможного числа.
                0

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

            +9
            После такой статьи от души радуешся что ты c# програмист.
              +6

              Или огорчаешься, потому что мало серьёзных проектов с открытым кодом на C#.

              +7

              CVE-2017-15280 — это давно уже не уязвимость. Потому что XXE через XmlTextReader с настройками по умолчанию закрыли в .NET 4.5.2, за три года до 2017го...

                +1

                Эмм… Может на C# тупо мало софта и не в чем искать уязвимости? На типичном не-Windows компьютере (включая мобилы-планшеты) софта на шарпе примерно ноль.


                Наверняка в программах на D, Cobol, SmallTalk, Haskell тоже мало CVE.

                  +1
                  На C# мало софта? Хороший вброс
                  +2
                    +3

                    Касательно уязвимостей.
                    Им в дотнете взяться особо неоткуда. Управляемый код со строгой статической типизацией перекрывает большинство классических проблем, так что выстрелить себе в ногу намного сложнее. Из потенциально дырявых технологий могу назвать разве что Remoting, которым уже лет 10 как не пользуются.
                    Остаются в основном штуки связанные с вебом, но и там можно поймать разве что XSS — SQL-инъеккциям тоже неоткуда взяться, ибо все используют LINQ.

                      –7

                      Вот вообще не очень понимаю, что все в этот LINQ упоролись…
                      От слова — совсем… даже вон — товарищь по оптимизации, один из разрабов дотнет писал — что таки линком не стоит особо сильно увлекаться…

                        +4

                        Это Entity Framework-ом не стоит особо увлекаться, ибо тормозит из-за своего change-tracking-а. Нормальные реализации типа linq2db (не путать с linq2sql) по производительности сравнимы с ручным написанием запросов.


                        Это касательно доступа к БД. Манипуляции же с объектами внутри процесса, там да, можно использованием LINQ себе производительность хорошо так просадить. В особо терминальных случаях его запускают поверх байтмассивов, а потом удивляются, чому оно работает на 4-5 порядков медленнее вручную написанного цикла.

                          0

                          Ну, там где я читал — речь шла про LINQ в принципе, хотя — может быть не применительно к базам, опять же, а манипуляций с объектами… К сожалению не могу найти статью тут на хабре....

                          +2

                          Потому что мощная и удобная штука.

                            –1

                            Мощьная и удобная — понятие субъективное


                            Мне например коннекты и датасеты — удобнее, как не крути… :)

                              +2

                              Вот именно потому, что субъективная, вы и не понимаете.


                              (правда, надо заметить, что статическая типизация и AST — вещи все-таки объективные, ну не суть)

                                0

                                Удобная и мощная != производительная.
                                Суть моего высказывания была в этом.

                                  +1

                                  Ну так любят и не за производительность (хотя в умелых руках производительность LINQ, как бы бессмысленно эта фраза не звучала, достаточна).

                                    0

                                    На вкус и цвет, все фломастеры разные.
                                    Некоторые мои коллеги/знакомые считают на полном серьезе что производительность — не их забота, главное побыстрее сдать заказ и получить бабла. А производительность… ну, купит заказчик новый сервер за пару лимонов, и будет все хорошо с производительностью :)

                                      0
                                      На вкус и цвет, все фломастеры разные.

                                      Ну так это и есть субъективная характеристика.

                            +1

                            А чем linq вам не нравится? Не сложные запросы на нем можно писать и очень даже удобно, а для более сложных запросов можно написать sql-запрос

                          +1
                          Microsoft C# — очень хороший пример качественной реализации C# и IL транскомпиляции вообще. Безопасность типов реализуется так, что в принципе, ошибки не являются критическими.
                            0
                            Исходя из моих наблюдений, общество C# разработчиков имеет больше вертикальных связей и меньше горизонтальных, за счет этого больше фрагментировано.
                            Идеи и хорошие практики распространяются медленнее, ну и вообще вкладываться в OSS у дотнетчиков — редкость.
                              +1
                              С появлением .net core и других проектов в OSS это может измениться.
                                0
                                Мне кажется это от того, что там вообще плохо с написанием велосипедов. В смысле, фреймворк покрывает 95% нужд, остальное подпирается костылем под конкретную задачу и… и никаких уязвимостей. Ну и OSS такое же — небольшие костыли. Во что вкладываться то?

                                Совсем другое дело на JS — есть голый язык, и на него как только не изгаляются для прикручивания лучших практик. Тут без OSS вообще никак.

                              Only users with full accounts can post comments. Log in, please.