XEE-атака (billion laughs attack)
XEE-атака (также известна как 'billion laughs'-атака, атака с использованием XML-бомб) – тип атаки на приложение, основанный на обработке внешних данных небезопасно сконфигурированным XML-парсером. Следствием атаки может стать, например, отказ системы в обслуживании (DoS).
Примечание. Обратите внимание, что XEE и XXE – разные типы атак. XXE-атака описана здесь.
Суть XEE-атаки
Стандарт XML предусматривает возможность использования DTD (document type definition). DTD даёт возможность определять и использовать XML-сущности. Сущности могут как ссылаться на какой-то внешний ресурс, так и быть полностью определены внутри документа. В последнем случае они могут быть представлены какой-то строкой или, например, другими сущностями.
XML-файл с примерами подобных сущностей:
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE foo [
<!ENTITY lol "lol">
<!ENTITY lol1 "&lol;&lol;">
]>
<foo>&lol1;</foo>
Здесь определены сущности 'lol' и 'lol1', причём первая определена через строку, а вторая – через другие сущности. Как следствие, значением сущности 'lol1' будет строка 'lollol'.
Вложенность и количество сущностей можно увеличивать. Например, так:
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE foo [
<!ENTITY lol "lol">
<!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
<!ENTITY lol2 "&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;">
]>
<foo>&lol2;</foo>
Сущность 'lol2' раскрывается следующим образом:
lollollollollollollollollollollollollollollollollollollollollollollol
lollollollollollollollollollollollollollollollollollollollollollollol
lollollollollollollollollollollollollollollollollollollollollollollol
lollollollollollollollollollollollollollollollollollollollollollollol
lollollollollollollollol
По подобному принципу, путём увеличения количества вложенных сущностей, создаются так называемые XML-бомбы. Они представляют собой небольшие по размеру файлы, которые при раскрытии сущностей разрастаются до огромных размеров. Отсюда же происходят различные названия такого типа атак:
- XEE (XML Entity Expansion);
- billion laughs (из-за многократного повторения 'lol').
Таким образом, DoS-атака на приложение с использованием XML-бомб возможна, если:
- злоумышленник может передать приложению XML-бомбу;
- XML-парсер, который будет обрабатывать этот файл, имеет небезопасную конфигурацию.
Примеры уязвимого кода
Рассмотрим пример кода, уязвимого к XEE-атаке:
static void XEETarget(String pathToXml)
{
XmlReaderSettings settings = new XmlReaderSettings()
{
DtdProcessing = DtdProcessing.Parse,
MaxCharactersFromEntities = 0
};
using (var xml = File.OpenRead(pathToXml))
{
using (var reader = XmlReader.Create(xml, settings))
{
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Text)
Console.WriteLine(reader.Value);
}
}
}
}
В данном примере с помощью XML-парсера reader происходит чтение XML-файла. Стоит отметить, что данный парсер уязвим к XML-бомбам, т.к. он создан с небезопасными настройками, в которых:
- разрешена обработка DTD (свойство DtdProcessing имеет значение DtdProcessing.Parse);
- не установлено ограничение на размер сущностей (свойство MaxCharactersFromEntities имеет значение 0).
Как следствие, парсер может зависнуть в попытке разобрать XML-бомбу, начать потреблять большое количество памяти и т.п.
Чтобы сделать парсер устойчивым к XEE-атакам, достаточно задать для него хотя бы одну из следующих опций:
- запретить или игнорировать обработку DTD (установить для свойства DtdProcessing значения Prohibit или Ignore соответственно).
- установить ограничение на максимальный размер сущностей.
Пример настроек, в которых разрешена обработка DTD, но при этом ограничен максимальный размер сущностей:
XmlReaderSettings settings = new XmlReaderSettings()
{
DtdProcessing = DtdProcessing.Parse,
MaxCharactersFromEntities = 1024
};
XML-парсер, созданный с такими настройками, выбросит исключение типа XmlException, если при разборе XML-файла размер сущностей превысит допустимый лимит.
Особенности настроек парсеров по умолчанию
Стоит также отметить, что дефолтные настройки некоторых XML-парсеров могут изменяться в разных версиях библиотек. Например, Microsoft поменяли настройки некоторых XML-парсеров между .NET Framework 4.5.1 и .NET Framework 4.5.2, сделав их более безопасными по умолчанию.
Рассмотрим пример:
static void XEETarget(String pathToXml)
{
using (var xml = File.OpenRead(pathToXml))
{
var settings = new XmlReaderSettings()
{
DtdProcessing = DtdProcessing.Parse
};
using (var reader = XmlReader.Create(xml, settings))
{
while (reader.Read())
{
// Process XML
}
}
}
}
Данный код уязвим к XEE-атакам в версиях .NET Framework 4.5.1 и более старых, так как не устанавливает ограничения на размер сущностей (значение свойства MaxCharactersFromEntities - 0). В версиях .NET Framework 4.5.2 и более новых по умолчанию установлено ограничение на размер сущностей, как следствие – данный код в них будет устойчив к XEE.
Дополнительные ссылки
- Как Visual Studio 2022 съела 100 Гб памяти и при чём здесь XML бомбы?
- CWE-776: Improper Restriction of Recursive Entity References in DTDs ('XML Entity Expansion')
- XML External Entity Prevention Cheat Sheet
- OWASP, уязвимости и taint анализ в PVS-Studio C#. Смешать, но не взбалтывать
- Диагностическое правило V5615: Potential XEE vulnerability. Insecure XML parser is used to process potentially tainted data
- XXE-атака
0