Опубликовал usa 22-02-2013
Перевел: gazay
Неограниченное расширение сущности может привести к DoS уязвимости в REXML. Этой уязвимости присвоен CVE идентификатор CVE-2013-1821. Мы строго рекомендуем обновить ruby.
Детали
Во время чтения текстовых нод XML документа, парсер REXML может быть вынужден к резервированию экстремально больших строковых объектов, которые могут растратить всю память машины, вызвав недоступность сервиса (DoS).
Опасный код может выглядеть как-то так:
document = REXML::Document.new some_xml_doc
document.root.text
Когда вызывается метод `text`, сущности раскрываются. Атакующий может послать относительно небольшой XML документ так, что когда сущности будут раскрываться, их вложенности будут потреблять экстремально большое количество памяти атакованной системы.
Заметьте, что данная атака похожа на Billion Laughs атаки, хотя и имеет некоторые отличия. Это также относится к CVE-2013-1664 уязвимости Python.
Все пользователи, использующие затронутые релизы, должны либо обновиться, либо использовать один из обходных путей.
Обходные пути
Если вы не можете обновить Ruby, используйте этот манкипатч как обходной путь:
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
Этот манкипатч ограничивает размер вложенностей каждой сущности до 10k на ноду. REXML уже по умолчанию настроен на 10000 вложенностей сущности на документ, так что максимальное количество текста, который может быть сгенерирован из вложенностей сущностей должен быть около 98 мегабайт.
Затронутые сущности
- Все версии ruby 1.9 до ruby 1.9.3 patchlevel 392
- Все версии ruby 2.0 до ruby 2.0.0 patchlevel 0
- транк до ревизии 39384
Благодарности
Спасибо Ben Murphy за сообщение о данной проблеме.
История
- Добавлено о CVE номере 2013-03-11 07:45:00 (UTC)
- Оригинал опубликован 2013-02-22 12:00:00 (UTC)