В компьютерной безопасности атака «миллиард смеха» — это тип атаки типа «отказ в обслуживании» (DoS) , направленной на парсеры XML - документов. [1]
Его также называют XML-бомбой или атакой экспоненциального расширения сущности. [2]
Пример атаки состоит из определения 10 сущностей, каждая из которых определяется как состоящая из 10 предыдущих сущностей, при этом документ состоит из одного экземпляра самой большой сущности, которая расширяется до одного миллиарда копий первой сущности.
В наиболее часто цитируемом примере первой сущностью является строка " lol ", отсюда и название "billion laughs". На момент первого сообщения об этой уязвимости объем памяти компьютера , используемый миллиардом экземпляров строки " lol ", вероятно, превысил бы объем памяти, доступный процессу анализа XML.
Хотя первоначальная форма атаки была нацелена конкретно на XML-анализаторы, этот термин может быть применим и к схожим объектам. [1]
Впервые о проблеме сообщили еще в 2002 году [3] , но широкое обсуждение ее началось в 2008 году [4].
Защита от такого рода атак включает ограничение памяти, выделенной в отдельном парсере, если потеря документа допустима, или символическую обработку сущностей и ленивое их расширение только тогда (и в той степени), когда их содержимое должно использоваться.
< ? xml version= "1.0" ? > <!DOCTYPE lolz [ <!ENTITY lol "lol" > <!ELEMENT lolz ( #PCDATA ) > <!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;" > <!ENTITY lol2 "&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;" > <!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;" > <!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;" > <!ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;" > <!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;" > <!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;" > <!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;" > <!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;" > ]> <lolz > &lol9; </лолз >
Когда XML-анализатор загружает этот документ, он видит, что он включает один корневой элемент, "lolz", который содержит текст "&lol9;". Однако "&lol9;" — это определенная сущность, которая расширяется до строки, содержащей десять строк "&lol8;". Каждая строка "&lol8;" — это определенная сущность, которая расширяется до десяти строк "&lol7;" и так далее. После обработки всех расширений сущностей этот небольшой (< 1 КБ) блок XML фактически будет содержать 10 9 = миллиард "lol", занимая почти 3 гигабайта памяти. [5]
Описанная выше атака «миллиард смеха» может занять экспоненциальное количество пространства или времени. Квадратичная вариация взрыва вызывает квадратичный рост требований к ресурсам, просто повторяя большую сущность снова и снова, чтобы избежать контрмер, которые обнаруживают сильно вложенные сущности. [6] (См. теорию вычислительной сложности для сравнения различных классов роста.)
Атака «миллиард смеха» может существовать для любого формата файла, который может содержать макрорасширения, например, эта YAML- бомба:
a : &a [ "lol" , "lol" , "lol" , "lol" , "lol" , "lol" , "lol" , "lol" , "lol" ] b : &b [ *a , * a , *a , * a , *a , *a , *a , *a ] c : &c [ *b , *b , *b , * b , *b , *b , *b , *b , *b ] d : &d [ *c , *c , *c , *c , *c , * c , *c , *c , *c ] e : & e [ *d , *d , * d , *d , *d , *d , *d , *d , *d ] f : &f [ *e , *e , *e , *e , *e , * e , *e , *e , *e ] g : &g [ *f , *f , * f , *f , *f , *f , *f , *f ] h : &h [ *g , *g , *g , *g , *g , *g , * g , *g , *g ] i : &i [ *h , *h , *h , *h , * h , * h , *h , *h , *h ]
Это приводило к сбою более ранних версий Go , поскольку процессор Go YAML (вопреки спецификации YAML) расширяет ссылки так, как будто они являются макросами. Процессор Go YAML был изменен, чтобы не давать парсингу, если объект результата становится слишком большим.
Корпоративное программное обеспечение, такое как Kubernetes, подверглось этой атаке через свой парсер YAML. [7] [8] По этой причине для данных, поступающих из ненадежных источников, предпочтительным является либо парсер с намеренно ограниченными возможностями (например, StrictYAML), либо форматы файлов, не допускающие ссылок. [9] [ неудавшаяся проверка ]