Почему правительство США отвергает динамические языки для безопасных проектов?

Я знаю некоторых людей, которые в настоящее время работают над проектом для военных США (низкий уровень безопасности, данные о невоенных людских ресурсах).

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

Одним из элементов, которые необходимо было решить, было удаление части проекта, которая была написана в Ruby как динамический язык.

Что является фоном /причиной того, что динамический язык не используется в безопасном режиме? Неужели это правительство медленно внедряет новые технологии? Или динамические языки создают дополнительный риск для безопасности по сравнению со статическими языками (ala Java )?

119 голосов | спросил Patrick 30 J000000Tuesday13 2013, 20:11:09

8 ответов


126

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

Рассмотрим эту последовательность в irb (интерактивная рубиновая оболочка):

irb(main):001:0> "bar".foo
NoMethodError: undefined method `foo' for "bar":String
        from (irb):1
        from /usr/bin/irb:12:in `<main>'
irb(main):002:0> class String
irb(main):003:1> def foo
irb(main):004:2> "foobar!"
irb(main):005:2> end
irb(main):006:1> end
=> nil
irb(main):007:0> "bar".foo
=> "foobar!"

Что произошло, я попытался вызвать метод foo в константе String. Это не удалось. Затем я открыл класс String и определил метод foo o return "foobar!", а затем вызвал его. Это сработало.

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

У многих других динамических языков есть похожие вещи, которые можно сделать. Perl имеет Tie :: Scalar , который может за кулисами изменить то, как работает данный скаляр ( это немного более очевидно и требует определенной команды, которую вы можете видеть, но скаль, который передается откуда-то еще, может быть проблемой). Если у вас есть доступ к Cookbook Perl, найдите рецепт 13.15 - Создание магических переменных с привязкой.

Из-за этих вещей (а другие часто являются частью динамических языков) многие подходы к статическому анализу безопасности в коде не работают. Perl и Undecidability показывает, что это так и указывает даже на такие тривиальные проблемы с подсветкой синтаксиса (whatever / 25 ; # / ; die "this dies!"; создает проблемы, потому что whatever может быть определен для принятия аргументов или не во время выполнения полностью побеждает синтаксический маркер или статический анализатор).


Это может стать еще более интересным в Ruby с возможностью доступа к среде, в которой было определено закрытие (см. YouTube: поддержка Ruby Reasonable от RubyConf 2011 Джошуа Баланко). Я был ознакомлен с этим видео с Комментарий Ars Technica от MouseTheLuckyDog .

Рассмотрим следующий код:

 def mal(&block)
    puts ">:)"
    block.call
    t = block.binding.eval('(self.methods - Object.methods).sample')
    block.binding.eval <<-END
        def #{t.to_s}
          raise 'MWHWAHAW!'
        end
    END
end

class Foo
    def bar
        puts "bar"
    end

    def qux
        mal do
            puts "qux"
        end
    end
end

f = Foo.new
f.bar
f.qux

f.bar
f.qux

Этот код полностью виден, но метод mal может быть где-то еще ... и с открытыми классами, конечно, его можно переопределить где-то еще.

Запуск этого кода:

~ /$ ruby ​​foo.rb
бар
> :)
QUX
бар
b.rb: 20: в `qux ': MWHWAHAW! (Ошибка выполнения)
    от b.rb: 30: в `
~ /$ ruby ​​foo.rb
бар
> :)
QUX
b.rb: 20: в `bar ': MWHWAHAW! (Ошибка выполнения)
    от b.rb: 29: в `

В этом коде закрытие было доступно для доступа к all методов и других привязок, определенных в классе в этой области. Этовыбрал случайный метод и переопределил его, чтобы создать исключение. (см. Binding класс в Ruby, чтобы получить представление о к чему этот объект имеет доступ)

  

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

Более короткая версия, которая показывает переопределение переменной:

 def mal(&block)
    block.call
    block.binding.eval('a = 43')
end

a = 42
puts a
mal do 
  puts 1
end
puts a

Что, когда run производит:

42
1
43

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

Хорошо или плохо, жалуясь на рубин или нет (есть способы, в которых можно хотеть иметь возможность получить в среде метода (см. Абстрактный блог Ереси . В частности, речь идет о Схеме, где такая дискуссия была проведена. (связанный с SO: Почему система не поддерживает среду первого класса? )

  

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

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

ответил 30 J000000Tuesday13 2013, 20:32:33
50

Предполагая, что оценка была только для обеспечения безопасности, а не только приемочного сканирования (то есть, они не принимают Ruby, потому что они не хотят поддерживать Ruby), то:

Средства анализа безопасности обычно имеют плохое время с динамическим поведением.

Например:

Запустите любой проект .NET , написанный с использованием современных функций, таких как ASP.NET MVC и Entity Framework через что-то вроде Veracode и посмотрите, какой список ложных ложных срабатываний вы получите в своем отчете.

Veracode даже перечисляет многие базовые методы в основных библиотеках .NET 4 как «неподдерживаемые фреймворки» как неподдерживаемые или бета-версии, даже если большинство из них уже несколько лет на данный момент.

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

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

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

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

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

ответил Bill 30 J000000Tuesday13 2013, 21:27:31
33

Динамические языки могут использоваться в военных и военных целях. Я лично использовал и доставлял Perl и Python в приложениях DoD. Я также видел, что PHP и JavaScript используются и развертываются. По моему опыту, большинство некомпилированных кодов, которые я видел, были сценариями оболочки и Perl, потому что требуемые среды одобрены и установлены на множестве возможных целевых систем.

Тот факт, что эти языки динамичны, скорее всего, не проблема. Устные переводчики для этих языков должны быть одобрены для использования в целевых системах. Если интерпретатор не одобрен для использования (или, возможно, он есть, но не используется в целевых системах), то язык не может быть использован. Использование данного интерпретатора (или любого приложения) в защищенной системе требует любого количества препятствий безопасности: анализ источника, возможность компиляции из источника для целевых сред, дополнительный анализ двоичных файлов, отсутствие конфликтов с существующей инфраструктурой и т. Д.

ответил Thomas Owens 30 J000000Tuesday13 2013, 20:21:47
32

Я провел некоторое время с DOD (министерством обороны), написав код для F-16's MMU . Без нарушения каких-либо нераскрытий: MMU - это компьютерный блок, который контролирует почти все функции F-16. Очевидно, что во время полета не возникает ошибок, таких как ошибки во время выполнения. Не менее важно, чтобы система выполняла вычислительные операции в реальном времени.

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

  

Из-за критических функций поддержки Ada, теперь он используется не   только для военных применений, но также и в коммерческих проектах, где   ошибка программного обеспечения может иметь серьезные последствия, например. авионика и воздух   управление движением, коммерческие ракеты (например, Ариан 4 и 5), спутники   и других космических систем, железнодорожного транспорта и банковского дела. Для   Например, было написано программное обеспечение для полетной системы на Boeing 777   в Аде.

Мне очень не нравится цитировать слишком много, но это очень хорошо объясняет, почему именно такие статические языки (например, ADA) используются для таких проектов:

  

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

     

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

     

Динамическое управление памятью Ada является высокоуровневым и безопасным по типу. Ада делает   не имеют общих (и неопределенных) «указателей»; и не подразумевается   объявить любой тип указателя. Вместо этого все динамическое распределение памяти и   освобождение должно происходить через явно объявленные типы доступа.   Каждый тип доступа имеет связанный пул хранения, который обрабатывает   низкоуровневые детали управления памятью; программист может либо использовать   пул хранения по умолчанию или определить новые (это особенно   для доступа к неравномерной памяти). Можно даже   объявить несколько разных типов доступа, которые все обозначают одинаково   но используйте разные пулы хранения. Кроме того, язык предусматривает   проверки доступности, как во время компиляции, так и во время выполнения, что   гарантирует, что значение доступа не может пережить тип объекта, который он   указывает на.

ответил Michael Jasper 1 AM00000080000004131 2013, 08:15:41
13

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

Is this the government being slow to adopting new technologies?

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

Динамические языки часто будут «проглатывать» ошибки и в конечном итоге окажутся неожиданными. Это очень опасно для чувствительных систем. Если что-то не так происходит, вы хотите узнать его как можно скорее.

Если речь идет о безопасности, необходимо будет увидеть фактический прецедент. Например, я не думаю, что веб-страница Ruby on Rails будет автоматически менее безопасной, чем веб-страница Java.

ответил Sulthan 31 J000000Wednesday13 2013, 14:13:03
6

Я бы хотел добавить к существующим ответам, описав Drupal SA-CORE-2014-005 , который является крайне критичной уязвимостью, которая позволяет SQL-инъекцию и, в конечном счете, произвольное выполнение кода. Это вызвано динамической типизацией PHP и слабыми правилами ввода времени выполнения.

Полностью патч для этой проблемы:

-      foreach ($data as $i => $value) {
+      foreach (array_values($data) as $i => $value) {

Этот код является частью уровня абстракции SQL, предназначенного для предотвращения внедрения SQL. Он принимает SQL-запрос с именованными параметрами и ассоциативный массив, который предоставляет значение для каждого именованного параметра. Значение может быть массивом для таких случаев, как WHERE x IN (val1, val2, val3), где все три значения могут передаваться как одно значение массива для одного именованного параметра.

Уязвимость возникает из-за того, что код предполагает, что $i в $i => $value должен быть целым индексом значения. Он продолжается и объединяет этот «индекс» непосредственно в SQL-запрос как часть имени параметра, потому что целые числа не нуждаются в экранировании, правильно?

К сожалению, для Drupal PHP не предоставляет такую ​​гарантию. Можно передать другой ассоциативный массив, ключи которого являются строками, и этот цикл с удовольствием объединяет строковый ключ в запросе, как есть (помните, что код считает, что он может быть только когда-либо целым числом).

Хотя существуют способы иметь аналогичную ошибку в статически типизированном языке, они маловероятны. Хороший разработчик рассмотрит возможные варианты $i, прежде чем объединить его в запрос. С помощью статически типизированного языка очень легко обеспечить, чтобы $i должен быть целым числом, а в секретном коде, подобном этому, это, безусловно, будет выполнено.

Кроме того, код действительно проверяет, является ли это значение массивом перед итерацией по элементам. И в этом заключается вторая часть сбоя, которая позволяет эту уязвимость: как ассоциативный массив, так и «нормальный» массив возвращают true для is_array. Хотя верно и то, что в C # оба словаря и массивы - это IEnumerable, сложно построить код, который бы скомпоновал словарные ключи с такими индексами массивов, как это даже преднамеренно, не говоря уже о случайности.

ответил Roman Starkov 5 32014vEurope/Moscow11bEurope/MoscowWed, 05 Nov 2014 18:59:31 +0300 2014, 18:59:31
2

Независимо от того, защищена ли кодовая база или нет, зависит от того, как вы пишете свой код, как вы его тестируете и как вы проверяете и контролируете процесс разработки и развертывания. Языки не являются ни безопасными, ни неуверенными, это то, как вы кодируете.

Большинство инцидентов безопасности из-за вредоносного ввода (sql-инъекции, переполнение буфера), вирусов, руткитов и троянов. Никакой язык не может защитить вас от этого.

Таким образом, запрещение классов языков для того, чтобы быть «небезопасными», не является веской причиной.

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

Это происходит постоянно в контрольных культурах. Я вижу это более или менее ежедневно. Это не имеет никакого смысла, но так оно и есть. Если вы хотите больше узнать об этой актуальной теме, я рекомендую книгу Шнайдера « Альтернатива реинжиниринга ". Вот диаграмма культуры Michael Sahoto /Agilitrix , основанный на книге Шнайдера: введите описание изображения здесь>> </p></body></html>

ответил Martin Wickman 31 J000000Wednesday13 2013, 14:51:58
2

Насколько я могу судить, официальная политика Министерства обороны вообще не запрещает динамические языки.

Стандарты программного обеспечения, разработанные или закупленные Министерством обороны, обнародуются Агентство оборонных информационных систем (DISA). Их Безопасность приложений - безопасность приложений и amp; Разработка Руководство по технической поддержке безопасности (STIG) не запрещает какой-либо конкретный язык. Он не упоминает Ruby, но он упоминает Perl и Python, которые так же динамичны. Он упоминает их в контексте различных тем (в соответствии с установленными стандартами кодирования, избегая уязвимостей инжекции команд и т. Д.).

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

ответил Andrew Medico 6 42014vEurope/Moscow11bEurope/MoscowThu, 06 Nov 2014 00:39:30 +0300 2014, 00:39:30

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132