Вразливість DoS розширення сутності в REXML (XML бомба, CVE-2013-1821)

Опублікував usa 22-02-2013
Переклав: Andrii Furmanets

Необмежене розширення сутності може призвести до вразливості DoS в REXML. Цій вразливості присвоєно ідентифікатор CVE CVE-2013-1821. Ми настійно рекомендуємо оновити ruby.

Деталі

При читанні текстових вузлів з XML документа, парсер REXML може бути примушений до виділення надзвичайно великих об’єктів рядків, які можуть споживати всю пам’ять на машині, спричиняючи відмову в обслуговуванні.

Зачеплений код виглядатиме приблизно так:

document = REXML::Document.new some_xml_doc
document.root.text

Коли викликається метод `text`, сутності будуть розширені. Зловмисник може надіслати відносно малий XML документ, який, коли сутності вирішуються, споживатиме надзвичайні обсяги пам’яті на цільовій системі.

Зверніть увагу, що ця атака схожа на, але відрізняється від атаки Billion Laughs. Це також пов’язано з CVE-2013-1664 Python.

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

Обхідні шляхи

Якщо ви не можете оновити Ruby, використовуйте цей monkey patch як обхідний шлях:

class REXML::Document
  @@entity_expansion_text_limit = 10_240

  def self.entity_expansion_text_limit=( val )
    @@entity_expansion_text_limit = val
  end

  def self.entity_expansion_text_limit
    @@entity_expansion_text_limit
  end
end

class REXML::Text
  def self.unnormalize(string, doctype=nil, filter=nil, illegal=nil)
    sum = 0
    string.gsub( /\r\n?/, "\n" ).gsub( REFERENCE ) {
      s = self.expand($&, doctype, filter)
      if sum + s.bytesize > REXML::Document.entity_expansion_text_limit
        raise "entity expansion has grown too large"
      else
        sum += s.bytesize
      end
      s
    }
  end

  def self.expand(ref, doctype, filter)
    if ref[1] == ?#
      if ref[2] == ?x
        [ref[3...-1].to_i(16)].pack('U*')
      else
        [ref[2...-1].to_i].pack('U*')
      end
    elsif ref == '&'
      '&'
    elsif filter and filter.include?( ref[1...-1] )
      ref
    elsif doctype
      doctype.entity( ref[1...-1] ) or ref
    else
      entity_value = DocType::DEFAULT_ENTITIES[ ref[1...-1] ]
      entity_value ? entity_value.value : ref
    end
  end
end

Цей monkey patch обмежить розмір підстановок сутності до 10k на вузол. REXML вже за замовчуванням дозволяє лише 10000 підстановок сутності на документ, тому максимальна кількість тексту, яку можна згенерувати підстановкою сутності, буде близько 98 мегабайтів.

Зачеплені версії

  • Всі версії ruby 1.9 до ruby 1.9.3 рівня патчу 392
  • Всі версії ruby 2.0 до ruby 2.0.0 рівня патчу 0
  • до ревізії trunk 39384

Подяка

Дякуємо Ben Murphy за повідомлення про цю проблему.

Історія

  • Додано про номер CVE 2013-03-11 07:45:00 (UTC)
  • Спочатку опубліковано 2013-02-22 12:00:00 (UTC)

Останні новини

Вийшов Ruby 4.0.0

Ми раді повідомити про випуск Ruby 4.0.0. Ruby 4.0 представляє “Ruby Box” та “ZJIT”, а також додає багато покращень.

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

Більше новин...