Как я могу защищаться в Ruby? - PullRequest
5 голосов
/ 28 августа 2008

Вот прекрасный пример проблемы: Классификатор разбитых камней Rails .

** Оригинальный вопрос: **

Одна вещь, которая касается меня как специалиста по безопасности, - это то, что Ruby не имеет параллели с приватностью пакетов Java. То есть это недопустимый Ruby:

public module Foo
  public module Bar
    # factory method for new Bar implementations
    def self.new(...)
      SimpleBarImplementation.new(...)
    end
    def baz
      raise NotImplementedError.new('Implementing Classes MUST redefine #baz')
    end
  end

  private class SimpleBarImplementation
    include Bar
    def baz
      ...
    end
  end
end

Было бы очень хорошо, если бы можно было предотвратить использование Foo :: BarImpl. Таким образом, люди, которые полагаются на библиотеку, знают, что никто не перепутал ее. Представьте, если кто-то изменил реализацию MD5 или SHA1 на вас! Я могу вызывать freeze для этих классов, но я должен делать это на индивидуальной основе, и другие скрипты могут изменить их, прежде чем я закончу защищать свое приложение, если я не очень осторожен о заказе груза.

Java предоставляет множество других инструментов для защитного программирования, многие из которых невозможны в Ruby. (См. Книгу Джоша Блоха для хорошего списка.) Это действительно проблема? Должен ли я просто перестать жаловаться и использовать Ruby для легких вещей, а не надеяться на «готовые к работе» решения?

(И нет, базовые классы в Ruby по умолчанию не заморожены. См. Ниже:)

require 'md5'
# => true
MD5.frozen?
# => false

Ответы [ 9 ]

9 голосов
/ 29 августа 2008

Не думаю, что это проблема.

Да, мифический «кто-то» может заменить реализацию MD5 чем-то небезопасным. Но для того, чтобы сделать это, мифологически кто-то должен иметь возможность вставить свой код в процесс Ruby. И если он может сделать это, то он, вероятно, мог бы также внедрить свой код в процесс Java и, например, переписать байт-код для операции MD5. Или просто перехватывать нажатия клавиш и вообще не беспокоиться о том, чтобы возиться с криптографическим кодом.

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

require 'awesome'
# Do something awesome.

Но что, если кто-то использует это так:

require 'evil_cracker_lib_from_russian_pr0n_site'
# Overrides crypto functions and sends all data to mafia
require 'awesome'
# Now everything is insecure because awesome lib uses 
# cracker lib instead of builtin

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

Возвращаясь к вашему примеру с Java: это правда, что в Java вы можете сделать свой криптографический код private и final, а что нет. Однако кто-то может все же заменить вашу криптографическую реализацию! Фактически, кто-то действительно так и сделал: многие реализации Java с открытым исходным кодом используют OpenSSL для реализации своих криптографических процедур. И, как вы, наверное, знаете, в течение многих лет Debian поставлял неработающую небезопасную версию OpenSSL. Итак, все Java-программы, работавшие в Debian в течение последних двух лет, на самом деле выполняли с небезопасным шифрованием!

4 голосов
/ 29 августа 2008

Java предоставляет множество других инструментов для защитного программирования

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

Однако, похоже, вы на самом деле говорите о «защите своего кода от других программистов».

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

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

В любом случае, если такие вещи вас беспокоят, ruby ​​не является для вас языком программирования. По своему замыслу здесь предусмотрена система обезьяноподготовки, и ее запрещение противоречит самой сути функции.

1 голос
/ 01 декабря 2008

У Раганвальда есть недавнее сообщение об этом. В конце концов он строит следующее:

class Module
  def anonymous_module(&block)
   self.send :include, Module.new(&block)
  end
end

class Acronym
  anonymous_module do
    fu = lambda { 'fu' }
    bar = lambda { 'bar' }
    define_method :fubar do
      fu.call + bar.call
    end
  end
end

Это предоставляет fubar как открытый метод для Acronym s, но сохраняет внутренние кишки (fu и bar) закрытыми и скрывает вспомогательный модуль от внешнего вида.

1 голос
/ 02 октября 2008

Вы можете взглянуть на проект «Песочница» Lucky Stiff, который вы можете использовать, если беспокоитесь о потенциально опасном выполнении кода. http://code.whytheluckystiff.net/sandbox/

Пример (онлайн TicTacToe): http://www.elctech.com/blog/safely-exposing-your-app-to-a-ruby-sandbox

1 голос
/ 02 октября 2008

Если вы используете патч обезьян, вы можете использовать модуль Immutable (или одну из аналогичных функций).

Неизменное

1 голос
/ 02 октября 2008

Проверьте Неизменный Гарри Долли.

Вы можете предотвратить переопределение отдельных методов.

1 голос
/ 29 августа 2008

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

Я не говорю, что мы должны строить для наименьшего общего знаменателя, но мы должны быть реалистами, что есть лоты посредственных программистов, которые потянут любую библиотеку, которая выполнит свою работу, не обращая внимания на безопасность. Как могут обратить внимание на безопасность? Может быть, взяли класс алгоритмов и структур данных. Возможно они взяли класс компиляторов. Они почти наверняка не взяли класс протоколов шифрования. Они определенно не все читали Шнайера или кого-либо еще, кто практически должен просить и умолять даже с очень хорошими программистами учитывать безопасность при создании программного обеспечения.

Меня это не беспокоит:

require 'evil_cracker_lib_from_russian_pr0n_site'
require 'awesome'

Я беспокоюсь о awesome, требующем foobar и fazbot, и foobar, требующем has_gumption, и ... в конечном итоге два из этих конфликтов каким-то неясным образом отменяют важный аспект безопасности.

Одним из важных принципов безопасности является «глубокая защита» - добавление этих дополнительных уровней безопасности поможет вам случайно не выстрелить себе в ногу. Они не могут полностью предотвратить это; ничего не может. Но они помогают.

1 голос
/ 28 августа 2008

Я полагаю, что в Ruby есть такая особенность - она ​​важнее, чем проблема безопасности. Дафтайп тоже.
Например. Я могу добавить свои собственные методы в класс Ruby String вместо того, чтобы расширять или оборачивать его.

0 голосов
/ 18 ноября 2008

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

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

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

...