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

Комментарии (27)


  1. questor
    31.10.2017 11:18

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


  1. F0iL
    31.10.2017 11:31
    +3

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


    1. Areldar
      31.10.2017 13:05
      +2

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


    1. staticlab
      31.10.2017 13:25

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


      1. F0iL
        31.10.2017 14:25

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


        1. staticlab
          31.10.2017 15:25

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


  1. unsafePtr
    31.10.2017 12:51

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


    1. kefirr
      31.10.2017 13:02

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


  1. mayorovp
    31.10.2017 13:08
    +1

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


  1. slonopotamus
    31.10.2017 20:16
    +1

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


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


    1. galakt
      01.11.2017 10:58

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



  1. kekekeks
    31.10.2017 21:30

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


    1. enzain
      31.10.2017 22:45

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


      1. kekekeks
        31.10.2017 23:08
        +1

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


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


        1. enzain
          01.11.2017 09:30

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


      1. lair
        01.11.2017 00:08

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


        1. enzain
          01.11.2017 09:31

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


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


          1. lair
            01.11.2017 11:32

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


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


            1. enzain
              02.11.2017 09:39

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


              1. lair
                02.11.2017 11:49

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


                1. enzain
                  02.11.2017 15:03

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


                  1. lair
                    02.11.2017 15:33

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

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


      1. Csharper101
        01.11.2017 10:58

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


  1. vuser
    01.11.2017 10:58

    Microsoft C# — очень хороший пример качественной реализации C# и IL транскомпиляции вообще. Безопасность типов реализуется так, что в принципе, ошибки не являются критическими.


  1. kwardakov
    01.11.2017 10:58

    Исходя из моих наблюдений, общество C# разработчиков имеет больше вертикальных связей и меньше горизонтальных, за счет этого больше фрагментировано.
    Идеи и хорошие практики распространяются медленнее, ну и вообще вкладываться в OSS у дотнетчиков — редкость.


    1. Simplevolk
      01.11.2017 15:17

      С появлением .net core и других проектов в OSS это может измениться.