Обзор от WhiteSource показал, какие из языков программирования имеют наибольшие дыры в безопасности. Победитель антирейтинга — Си. Но это только начало истории.

Технологии в целом нашпигованы ошибками безопасности. На низком уровне это ошибки в железе. Так это было с уязвимостью Intel и ошибками Spectre. Чуть выше — дыры в безопасности языков программирования. И их ну очень много!

Недавно Open-Source компания WhiteSource, занимающаяся вопросами безопасности, провела исследование уязвимостей в семи наиболее распространённых языках программирования за последние десять лет. Для обнаружения ошибок компания использовала свою базу данных языковой безопасности. Она содержит уязвимости с открытым исходным кодом из нескольких источников, таких как Национальная База данных Уязвимостей (NVD), инструкции по безопасности, трекеры GitHub`a и проектов с открытым исходным кодом.

Компания выделила следующие языки: C, Java, JavaScript, Python, Ruby, PHP и C++. И это не удивительно. Как и то, какой язык имеет наибольшее число ошибок безопасности. С большим отрывом это Си. Более 50% обнаруженных уязвимостей были в нём.

Как недавно заметил Киис «Кэйз» Кук (Kees «Case» Cook), инженер по безопасности ядра Linux в Google: «Cи — это улучшенный ассемблер. Почти машинный код». Кроме того, «Cи несёт вызывающий беспокойство багаж, неопределённое поведение и другие слабые стороны, которые ведут к пробелам в безопасности и уязвимостям инфраструктуры».

Однако, в WhiteSource утверждают, что «нельзя говорить, что Си менее безопасен, чем другие языки. Большое число уязвимостей в открытом исходном коде Си может объясняться рядом факторов. Для начала, Си использовался дольше, чем другие языки, которые мы исследовали. Он имеет наибольший объём написанного кода. Это также один из языков, который стоит за такими важными инфраструктурами как OpenSSL и ядро Linux. Такая комбинация объёма и центрального положения объясняет большое число известных уязвимостей в open-source».

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

C++ при этом «прославился» уязвимостями наиболее высокой степени опасности за последние пять лет. Ошибки буфера, которые долгое время терзали Си, зачастую обнаруживаются и в C++.


Цифры не отражают всю картину, если говорить о том, какой язык наиболее или наименее защищён.
(Изображение WhiteSource)


При этом JavaScript, возможно, наиболее популярный язык. И единственный, который показал «непрерывное увеличение количества уязвимостей за последние 10 лет».

WhiteSource подчёркивает, что прежде чем насмехаться над JavaScript, следует учесть, что эти результаты обманчивы. Большую часть из Общего Перечня Уязвимостей (Common Weakness Enumeration) в JavaScript составляют выходы за пределы назначенного каталога и дыры в криптозащите пакетов JavaScript, которые едва используются и поддерживаются.

Почему тогда эти и другие языковые проблемы на виду? Новые автоматизированные программы, такие как Source Code Analysis Tools, обнаруживают уязвимости, которые в ином случае проглядели бы.

Единственный язык, который хорошо показал себя в отношении дыр безопасности это (барабанная дробь!) — Python. Да-да, старый добрый часто высмеиваемый Python.

Почти все языки вносят свой вклад в Общий Перечень Уязвимостей. Две ошибки из перечня лидировали и были представлены в 70% случаев: Межсайтовый скриптинг (XSS), также известный как CWE-79 и Недостаточная проверка входных данных (CWE-20).

Другие часто встречающиеся ошибки: Утечка / раскрытие информации (CWE-200), Выход за пределы назначенного каталога (CWE-22) и CWE-264 — Разрешения, привилегии и средства управления доступом. Последнее с недавних пор вытесняется своим более конкретным и близким родственником — Неправильным контролем доступа (CWE-284).

Но действительно ли Си наихудший, а Python наилучший? В WhiteSource считают, что это слишком простой вывод: «Хотя игра "Мой язык программирования безопасней, чем твой" — это определённо весёлый способ провести время … ответ по всей видимости не поможет вам создать более инновационный или защищённый софт».

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

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

> АКЦИЯ: 40% скидка на IaaS для разработчиков.

Стивен Дж. Воган-Николс (Steven J. Vaughan-Nichols) для Linux and Open Source

Оригинал статьи

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


  1. NeoCode
    26.03.2019 17:31
    +2

    В Си хотя-бы статическая типизация (хотя и менее строгая чем хотелось бы). В С++ с типизацией еще лучше. А в динамических языках никогда не знаешь что в переменной: строка, число или еще что-то.


    1. bromzh
      26.03.2019 21:10

      В Си хотя-бы статическая типизация (хотя и менее строгая чем хотелось бы).

      Но при этом она там слабая aka неявная. Что при незнании чревато более трудноотлавливаемыми ошибками.


      А в динамических языках никогда не знаешь что в переменной: строка, число или еще что-то.

      А в C никогда не знаешь, что живёт в переменных типа void *.


      Ну и во многих динамических языках появляются type hints, а в статических — auto/dynamic, так что границы размываются.


      1. ColdPhoenix
        27.03.2019 08:05

        Ну все же void * обычно не идет как основа работы, лишь ввод/вывод и подобное.


        Да и auto это не динамический тип, а автовывод типа. Но итоговый тип все ещё типизирован.


      1. WinPooh73
        27.03.2019 08:57

        Не в переменных типа void *, а по адресу, на который указывает void *. Что находится в самой переменной — достаточно чётко определено, это адрес ячейки памяти в формате, специфичном для данной платформы.


      1. NeoCode
        27.03.2019 21:26

        Переменные типа void* это явное использование «низкоуровневой динамики». В более высокоуровневых языках есть всякие variant, any (C++/Boost), dynamic (C#) которые делают нечто похожее на динамическую типизацию. Но — только там где это действительно нужно, и это делается явно. Видя тип variant/any/dynamic, программист понимает, что вот конкретно здесь применена динамическая типизация. Как правило, понятно и для какой конкретной цели она применена. Против такой явной динамики я ничего не имею, наоборот это очень полезная штука. А вот если бы некий программист стал использовать такой динамический тип АБСОЛЮТНО ВЕЗДЕ вместо всех других типов данных, то это был бы кошмар:) Но ведь именно это и происходит в php/питоне/javascript…


        1. bromzh
          28.03.2019 12:59

          Но ведь именно это и происходит в php/питоне/javascript…

          Да, происходит. И нет, это не кошмар, это просто немного другой взгляд на вещи.


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


          И я не топлю только за динамику, везде есть и плюсы и минусы. Плюсы типизации, какой бы она ни была, нужно использовать, а о минусах знать и стараться их избегать.
          Ставить в плюс только лишь наличие статической типизации в языке (даже такой не очень хорошей, как в C), при этом ужасаясь любой динамической (даже такой хорошей, как в питоне) — извините, но это как-то однобоко.


    1. pesh1983
      26.03.2019 23:59

      Обычно там работают с интерфейсом объекта, а не с его типом) А интерфейс может быть реализован множеством типов.


  1. staticmain
    26.03.2019 18:11
    +5

    Т.е. они проверили open source проекты, которые пишут студенты, допускающие ошибки из разряда `char a[10]; a[10] = '\0';` а не какие-то наученные опытом сеньоры\миддлы, прогнали через какой-то статический анализатор, при этом значительно перекосив баланс количества проектов на определенном языке и говорят что какой-то язык уязвимее?


  1. makondo
    26.03.2019 19:02
    +1

    Нужна гистограмма, нормализованная на количество проанализированных строк. Ясное дело, что кода на С\С++ больше, и ошибок там тоже больше.


  1. Jouretz
    26.03.2019 20:49
    +1

    Безопасность языка != Безопасность кода с гитхаба использующего этот язык
    Количество уязвимостей в проектах, часть которых была заброшена до открытия этих самых уязвимостей с безопасностью языка кореллирует примерно никак?


  1. maledog
    26.03.2019 22:47
    -1

    Напомнило историю про «возможность выстрелить себе в ногу». Как по мне, так язык-«песочница» порождает недопрограммистов, которые просто не состоянии осознать все опасности, которые несет их код. Проверено на программистах java/php/python. Да здравствуют RCE при десериализации.


    1. pesh1983
      27.03.2019 00:10
      +1

      Ну уж конечно, лучше все писать на си, хотя о чем это я, сразу уж на ассемблере, чего мелочиться. Вот там реальный контроль, и реальное понимание, что делает с кодом процессор. Вот на них только тру программисты пишут) Я вам так скажу, каждой задаче — свой инструмент. Посмотрю я на вас, как вы в веб страницы на си писать будете)) или рабочий прототип веб сервиса 1 день, вместо 1 часа на питоне) Ну или кроссплатформенное приложение без перекомпиляции) Задачу можно решить разными способами, вопрос во времени и целесообразности использования конкретных инструментов)


      1. maledog
        27.03.2019 01:23
        -1

        М-м. А апач и nginx конечно на php написаны? Или ПО для Esp и прочих контроллеров, там конечно тоже процветают высокоуровневые скриптовые языки. Равно как и их интерпретаторы, виртуальные машины. биндинги с api ОС.
        Web-сервис на С написать за час реально, просто для начала нужно изучить ентот самый html/css дабы подсунуть браузеру строки в нужном порядке.
        Но если вы html/css не знаете, то и а питоне у вас за час только hello world получится.
        А уж кроссплатформенность ява-приложений лучше не упоминайте. Всегда выясняется что у реального приложения внезапно весьма платформозависимые корни. Будь то работа с hardware или банальные файловые операции. Да я лучше перекомпилирую приложение под платформу, зато получу значительный выигрыш в ресурсах.


        1. pesh1983
          27.03.2019 02:08

          > М-м. А апач и nginx конечно на php написаны? Или ПО для Esp и прочих контроллеров, там конечно тоже процветают высокоуровневые скриптовые языки.

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

          > Web-сервис на С написать за час реально, просто для начала нужно изучить ентот самый html/css дабы подсунуть браузеру строки в нужном порядке.

          Никто не спорит) Но на питоне все равно будет быстрее, просто потому, что там нет заморочек с явным выделением памяти, ее освобождением, проверок на границы массива и целочисленного переполнения и т. д. и т. п. Разработчик языка уже позаботился об этом, предоставив разработчикам на питоне думать над задачей и не отвлекаться на решение низкоуровневых тривиальных нюансов.

          > А уж кроссплатформенность ява-приложений лучше не упоминайте. Всегда выясняется что у реального приложения внезапно весьма платформозависимые корни.

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


          1. maledog
            27.03.2019 08:47

            За JetBrains не скажу, но вот у меня Atollic TrueSTUDIO на базе eclipse которая съела гигабайт памяти на редактируемом коде для микроконтроллера.
            Кроме того у JetBrains платформозависимые разве что пути.


            1. pesh1983
              27.03.2019 10:06

              Когда я работал в Visual Studio, у меня эта софтина мало того, что тормозила жутко время от времени, так ещё иногда фризила компьютер на пару-тройку секунд. Чё он там делал, я не знаю, но работать в этой среде мне было очень некомфортно. Это же не говорит о том, что на чем он там написан (си++?) плохой язык) это говорит лишь о криворукости людей, его написавших.


              1. maledog
                27.03.2019 10:36

                В таком случае, нельзя говорить что язык A безопаснее языка B, потому что на языке B можно сделать ошибку. Особенно когда выясняется что наиболее сложные и ответственные функции у языка A реализованы как раз на языке B.
                После нахождения дыры в Openssl только ленивый не форкнул ее или не бросился реализовывать tls на своем языке, но через некоторое время посыпались новости вида «Продукт N вернулся на openssl после нахождения детских ошибок в собственной реализации tls»


        1. VolCh
          27.03.2019 08:31

          Обычно веб-сервисы не предполагают html/css, а работают с json/xml.


          1. maledog
            27.03.2019 08:44

            При этом libjson и libxml написаны на c либо c++. А когда производительность скриптовых языков начинает проседать, они берут c-шную библиотеку, используют unsafe и продолжают считать свое приложение полностью безопасным.


            1. pesh1983
              27.03.2019 10:12

              Это вы прям за всех разработчиков скриптовых языков утверждаете? Смело однако) Да, когда не хватает скорости, берут и пишут части на си. И это замечательно, потому что там, где нужна простота и решение бизнес задач, может вполне подойти скриптовый простой язык, который дополняется более низкоуровневым при необходимости. Ну и пишется везде по-разному, не стоит вот так легко всех записывать в горе программисты только по личным наблюдениям пары-тройки своих коллег.


              1. maledog
                27.03.2019 10:43

                Мой исходный комментарий был о том, что выстрелить себе в ногу можно используя любой язык. И когда на безопасном языке попытаются реализовать то, что небезопасно в опасном, то получат ровно тоже самое. Например, вы можете поднять производительность безопасного языка, но для этого вам придется использовать либо С либо ассемблерные вставки и тогда вся безопасность вашего приложения сведется на нет.
                Насчет языков(не только скриптовых) использующих unsafe.
                Python, java, go, perl, php и даже оплот безопасности rust используют.


  1. Inanity
    26.03.2019 22:53
    +5

    Надо срочно придумать язык Joe++. Неуязвимый Joe++, лидер по безопасности, хотя ни одной программы на нём нет…


    1. VolCh
      27.03.2019 08:32

      А потом кто-то его выберет как самый безопасный :)


  1. Rudmz
    27.03.2019 12:03

    Си — язык мягко говоря не молодой и в его случае за «безопасность» отвечает не язык, а программист. Но и для поиска уязвимостей в нём требуется большая квалификация, чем в скриптовых языках (привет Drupal, WordPress и т.д.). И тем более любой язык позволяет выполнить фокус с запросом в БД: «Did you really name your son Robert'); DROP TABLE Students;--?»


  1. Rodegast
    27.03.2019 14:53

    ИХМО самый безопасный язык это Haskell.


  1. EviLOne
    27.03.2019 14:53

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