Уязвимость объектов через DL и Fiddle в Ruby (CVE-2013-2065)

Опубликовал usa 14-05-2013
Перевел: gazay

Уязвимость в DL и Fiddle в Ruby, где испорченные строки могут быть использованы системными вызовами, не смотря на установленный в Ruby уровень $SAFE. Этой уязвимости назначен CVE идентификатор CVE-2013-2065.

Влияние

Нативные функции, действующие в Ruby с DL или Fiddle, не проверяют испорченности выставленных значений поступающих в объекты. Как результат, испорченные объекты могут быть приняты как обычные, когда как должна быть брошена ошибка SecurityError.

Пример DL кода будет выглядеть как-то так:

def my_function(user_input)
  handle    = DL.dlopen(nil)
  sys_cfunc = DL::CFunc.new(handle['system'], DL::TYPE_INT, 'system')
  sys       = DL::Function.new(sys_cfunc, [DL::TYPE_VOIDP])
  sys.call user_input
end

$SAFE = 1
my_function "uname -rs".taint

Пример Fiddle кода будет выглядеть как-то так:

def my_function(user_input)
  handle    = DL.dlopen(nil)
  sys = Fiddle::Function.new(handle['system'],
                             [Fiddle::TYPE_VOIDP], Fiddle::TYPE_INT)
  sys.call user_input
end

$SAFE = 1
my_function "uname -rs".taint

Все пользователи, использующие затронутые релизы, должны либо обновить, либо использовать один из обходных путей немедленно.

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

def my_function(input)
  handle    = DL.dlopen(nil)
  sys = Fiddle::Function.new(handle['system'],
                             [Fiddle::TYPE_VOIDP], Fiddle::TYPE_INT)
  sys.call input
end

$SAFE = 1
user_input = "uname -rs".taint
my_function DL::CPtr[user_input].to_i

В этом случае позиция в памяти передана и загрязненность объекта не может быть определена DL / Fiddle. В данном случае, пожалуйста проверяйте загрязненность пользовательского ввода перед тем как передавать позицию в памяти:

user_input = "uname -rs".taint
raise if $SAFE >= 1 && user_input.tainted?
my_function DL::CPtr[user_input].to_i

Обходные пути

Если вы не можете обновить Ruby, данный манкипатч может быть использован как обходной путь:

class Fiddle::Function
  alias :old_call :call
  def call(*args)
    if $SAFE >= 1 && args.any? { |x| x.tainted? }
      raise SecurityError, "tainted parameter not allowed"
    end
    old_call(*args)
  end
end

Затронутые версии

  • Все версии ruby 1.9 до ruby 1.9.3 patchlevel 426
  • Все версии ruby 2.0 до ruby 2.0.0 patchlevel 195
  • транк ветка до ревизии 40728

ruby 1.8 версии не затронуты

Благодарность

Спасибо Vit Ondruch за сообщение о данной проблеме.

История

  • Оригинал опубликован 2013-05-14 13:00:00 (UTC)

Последние новости

Вышел Ruby 4.0.0

Мы рады сообщить о выпуске Ruby 4.0.0. Ruby 4.0 представляет «Ruby Box» и «ZJIT», а также добавляет множество улучшений.

Опубликовал naruse 25-12-2025

Новый облик документации Ruby

Вслед за редизайном ruby-lang.org, у нас есть еще новости в честь 30-летия Ruby: docs.ruby-lang.org получил полностью новый облик с Aliki — новым стандартным шаблоном RDoc....

Опубликовал Stan Lo 23-12-2025

Вышел Ruby 4.0.0 preview3

Мы рады сообщить о выпуске Ruby 4.0.0-preview3. Ruby 4.0 представляет Ruby::Box и «ZJIT», а также содержит множество улучшений.

Опубликовал naruse 18-12-2025

Больше новостей...