Вопрос

Вот прекрасный пример этой проблемы: Классификатор gem ломает Рельсы.

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

Одна вещь, которая беспокоит меня как специалиста по безопасности, заключается в том, что Ruby не имеет параллели с Java package-privacy.То есть, это недопустимый 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
Это было полезно?

Решение

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

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

Другие советы

Я не думаю, что это вызывает беспокойство.

Да, мифический "кто-то" может заменить реализацию 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 за последние пару лет сделал работайте с небезопасной криптографией!

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

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

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

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

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

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

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

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

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

Я не беспокоюсь об этом:

require 'evil_cracker_lib_from_russian_pr0n_site'
require 'awesome'

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

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

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

Неизменяемый

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

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

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

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 в качестве общедоступного метода на Acronyms, но сохраняет внутреннее мужество (fu и bar) приватный и скрывает вспомогательный модуль от постороннего взгляда.

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top