to the top
close form
Для получения триального ключа
заполните форму ниже
Team license
Enterprise license
** Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
Запросите информацию о ценах
Новая лицензия
Продление лицензии
--Выберите валюту--
USD
EUR
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
Бесплатная лицензия PVS-Studio для специалистов Microsoft MVP
** Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
Для получения лицензии для вашего открытого
проекта заполните, пожалуйста, эту форму
** Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
Мне интересно попробовать плагин на:
** Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
check circle
Ваше сообщение отправлено.

Мы ответим вам на


Если вы так и не получили ответ, пожалуйста, проверьте папку
Spam/Junk и нажмите на письме кнопку "Не спам".
Так Вы не пропустите ответы от нашей команды.

>
>
>
Как Visual Studio 2022 съела 100 Гб пам…

Как Visual Studio 2022 съела 100 Гб памяти и при чём здесь XML бомбы?

07 Сен 2021

В апреле 2021 года Microsoft анонсировала новую версию своей IDE – Visual Studio 2022, попутно объявив, что она будет 64-битной. Сколько мы этого ждали — больше никаких ограничений по памяти в 4 Гб! Однако, как оказалось, есть нюансы...

0865_VS2022_XMLBomb_ru/image1.png

Кстати, если вы пропустили, вот ссылка на тот пост с анонсом.

Но вернёмся к нашему вопросу из заголовка. Я воспроизвёл эту проблему на последней доступной на момент написания заметки версии Visual Studio 2022 Preview — 17.0.0 Preview 3.1.

Для воспроизведения достаточно:

  • создать проект пустого решения (шаблон Blank Solution);
  • добавить в него XML-файл.

После этого в созданный XML-файл нужно попробовать скопировать следующий текст:

<?xml version="1.0"?>
<!DOCTYPE lolz [
 <!ENTITY lol "lol">
 <!ELEMENT lolz (#PCDATA)>
 <!ENTITY lol1 "&lol;&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;&lol4;">
 <!ENTITY lol6 "&lol5;&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;">
 <!ENTITY lol10 "&lol9;&lol9;&lol9;&lol9;&lol9;&lol9;&lol9;&lol9;&lol9;&lol9;">
 <!ENTITY lol11 
   "&lol10;&lol10;&lol10;&lol10;&lol10;&lol10;&lol10;&lol10;&lol10;&lol10;">
 <!ENTITY lol12 
   "&lol11;&lol11;&lol11;&lol11;&lol11;&lol11;&lol11;&lol11;&lol11;&lol11;">
 <!ENTITY lol13 
   "&lol12;&lol12;&lol12;&lol12;&lol12;&lol12;&lol12;&lol12;&lol12;&lol12;">
 <!ENTITY lol14 
   "&lol13;&lol13;&lol13;&lol13;&lol13;&lol13;&lol13;&lol13;&lol13;&lol13;">
 <!ENTITY lol15 
   "&lol14;&lol14;&lol14;&lol14;&lol14;&lol14;&lol14;&lol14;&lol14;&lol14;">
]>
<lolz>&lol15;</lolz>

Теперь идём заваривать кофе, возвращаемся и наблюдаем за тем, как Visual Studio отжирает всё больше и больше ОЗУ.

0865_VS2022_XMLBomb_ru/image2.png

Могут возникнуть 2 вопроса:

  • Зачем делать какие-то странные XML и добавлять их в проекты?
  • Что здесь вообще происходит?

Что ж, давайте разбираться. Для этого нам нужно будет вспомнить, какие опасности может нести неаккуратная обработка XML-файлов, а также узнать, как со всем этим связан статический анализатор PVS-Studio.

SAST в PVS-Studio

Мы продолжаем активно развивать PVS-Studio как SAST решение. Если говорить про C# анализатор, то основной фокус по этому фронту – поддержка OWASP Top 10 2017 (последняя доступная на данный момент версия – с нетерпением ждём обновления). К слову, если вы пропустили, не так давно мы добавили taint анализ, о чём можно почитать здесь.

Собственно, для тестирования работы анализатора я и создал (точнее, попытался создать) соответствующий синтетический проект. Дело в том, что одна из категорий OWASP Top 10, над которой сейчас ведётся работа, – A4:2017-XML External Entities (XXE). Она затрагивает уязвимость приложений к различным атакам посредством неправильной обработки XML-файлов. Что подразумевается под неправильной обработкой? Например, излишнее доверие к входным данным (извечная проблема многих уязвимостей) и отсутствие должных ограничений в парсерах XML.

В итоге, если файлы окажутся скомпрометированы, это может вылиться в разные неприятные последствия. Здесь можно выделить 2 основные проблемы: раскрытие каких-то данных и отказ в обслуживании. Обе имеют соответствующие CWE:

CWE-611 оставим на другой раз, сегодня нас интересует CWE-776.

XML бомбы (billion laughs attack)

Я поясню только основную суть проблемы. Если у вас есть желание изучить проблему глубже – топик легко гуглится, не обессудьте.

Стандарт XML предусматривает использование DTD (document type definition). DTD даёт возможность использовать так называемые XML-сущности.

Синтаксис определения сущностей прост:

<!ENTITY myEntity "Entity value">

Получить значение сущности в дальнейшем можно следующим образом:

&myEntity;

Нюанс состоит в том, что сущности могут раскрываться не только в строки (как в нашем случае — "Entity value"), но и в последовательности других сущностей. Например:

<!ENTITY lol "lol">
<!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">

В итоге при раскрытии сущности 'lol1' мы получим строку следующего вида:

lollollollollollollollollollol

Можно пойти дальше и определить сущность 'lol2', раскрыв её уже через 'lol1':

<!ENTITY lol2 "&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;">

Тогда при раскрытии одной лишь сущности 'lol2' мы получим следующий выхлоп:

lollollollollollollollollollollollollollollollollollollollollollollollol
lollollollollollollollollollollollollollollollollollollollollollollollol
lollollollollollollollollollollollollollollollollollollollollollollollol
lollollollollollollollollollollollollollollollollollollollollollollollol
lollollollol

Погрузимся на уровень ниже и определим сущность 'lol3'?

<!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">

Выхлоп при её раскрытии:

lollollollollollollollollollollollollollollollollollollollollollollollol
lollollollollollollollollollollollollollollollollollollollollollollollol
lollollollollollollollollollollollollollollollollollollollollollollollol
lollollollollollollollollollollollollollollollollollollollollollollollol
lollollollollollollollollollollollollollollollollollollollollollollollol
lollollollollollollollollollollollollollollollollollollollollollollollol
lollollollollollollollollollollollollollollollollollollollollollollollol
lollollollollollollollollollollollollollollollollollollollollollollollol
lollollollollollollollollollollollollollollollollollollollollollollollol
lollollollollollollollollollollollollollollollollollollollollollollollol
lollollollollollollollollollollollollollollollollollollollollollollollol
lollollollollollollollollollollollollollollollollollollollollollollollol
lollollollollollollollollollollollollollollollollollollollollollollollol
lollollollollollollollollollollollollollollollollollollollollollollollol
lollollollollollollollollollollollollollollollollollollollollollollollol
lollollollollollollollollollollollollollollollollollollollollollollollol
lollollollollollollollollollollollollollollollollollollollollollollollol
....

Собственно, сгенерированный по такому принципу XML-файл мы и использовали в начале статьи. Думаю, теперь понятно, откуда название "billion laughs". Получается, что если XML-парсер настроен неправильно (обрабатывает DTD и не имеет ограничений на максимальный размер сущностей), то при обработке подобной 'бомбы' ничего хорошего не случится.

Если говорить про C#, уязвимый код проще всего продемонстрировать на примере типа XmlReader:

var pathToXmlBomb = @"D:\XMLBomb.xml";
XmlReaderSettings rs = new XmlReaderSettings()
{
  DtdProcessing = DtdProcessing.Parse,
  MaxCharactersFromEntities = 0
};

using var reader = XmlReader.Create(File.OpenRead(pathToXmlBomb), rs);
while (reader.Read())
{
  if (reader.NodeType == XmlNodeType.Text)
    Console.WriteLine(reader.Value);
}

Сконфигурировав экземпляр XmlReader подобным образом, вы как бы говорите злоумышленнику этим кодом: "Давай, подорви меня!".

Причины две:

  • разрешена обработка DTD;
  • снято ограничение на максимальное количество символов из сущностей, то есть разрастание файла никак не ограничено.

По умолчанию, кстати, обработка DTD сущностей запрещена: свойство DtdProcessing имеет значение Prohibit, а на максимальное количество символов из сущностей стоит ограничение (начиная с .NET Framework 4.5.2). Так что в современном .NET всё меньше возможностей прострелить себе ногу. Хотя при неаккуратном конфигурировании парсеров это всё ещё возможно.

Возвращаясь к Visual Studio 2022

Похоже, что в Visual Studio 2022 при копировании нашей XML бомбы сработали как раз оба условия:

  • запустилась обработка DTD;
  • не стояло никаких ограничений, из-за чего объём потребляемой памяти пробил потолок.

Если посмотреть, что происходит в процессе в это время, можно найти подтверждение нашим предположениям.

0865_VS2022_XMLBomb_ru/image3.png

В списке потоков видно, что основной поток как раз обрабатывает XML. К слову, из-за этого повис весь GUI и IDE никак не реагировала на попытки потыкать её палочкой.

Если посмотреть call stack потока VS Main, можно увидеть, что он как раз занят обработкой DTD (исполняется метод ParseDtd).

0865_VS2022_XMLBomb_ru/image4.png

В ходе экспериментов у меня возник вопрос: а зачем Visual Studio вообще запускает процессинг DTD, почему просто не отображает XML как есть? Ответ пришёл в ходе экспериментов с 'XML-бомбочкой' (суть та же, но нагрузка поменьше).

Похоже, всё дело в том, чтобы отображать в редакторе "на лету" возможные значения сущностей.

0865_VS2022_XMLBomb_ru/image5.png

Небольшие значения обрабатываются успешно, но разрастание XML приводит к проблемам.

Конечно, такая проблема не могла обойтись без написания мной баг-репорта.

Заключение

Вот так неожиданным образом удалось посмотреть, как на практике могут выглядеть уязвимости к XML-бомбам. Самое интересное, что удалось пощупать это не на каком-то абстрактном примере, а на вполне знакомом и популярном приложении.

Мы планируем добавить поиск кода, уязвимого к проблемам обработки XML-файлов, в PVS-Studio 7.15. Если же интересно посмотреть, что анализатор умеет уже сейчас, предлагаю загрузить его и попробовать на своих проектах. ;)

Как всегда, приглашаю подписываться на мой Twitter, чтобы не пропустить ничего интересного.

Популярные статьи по теме
Под капотом SAST: как инструменты анализа кода ищут дефекты безопасности

Дата: 26 Янв 2023

Автор: Сергей Васильев

Сегодня речь о том, как SAST-решения ищут дефекты безопасности. Расскажу, как разные подходы к поиску потенциальных уязвимостей дополняют друг друга, зачем нужен каждый из них и как теория ложится на…
Что такое катастрофический возврат и как регулярное выражение может стать причиной ReDoS-уязвимости?

Дата: 03 Ноя 2022

Автор: Андрей Москалёв

Регулярные выражения – очень полезный и удобный инструмент для поиска и замены текста. Однако в некоторых случаях они могут привести к зависанию системы или даже стать причиной уязвимости к ReDoS-ата…
Чем опасны уязвимые зависимости в проекте и как с этим помогает SCA?

Дата: 06 Сен 2022

Автор: Никита Липилин

Современные приложения почти всегда используют сторонние библиотеки. Если библиотека содержит уязвимость, то уязвимым может оказаться и использующее её приложение. Но как определить наличие таких про…
Атака Trojan Source: скрытые уязвимости

Дата: 15 Апр 2022

Автор: Гость

Мы представляем новый тип атаки для внедрения в исходный код вредоносных изменений, по-разному выглядящих для компилятора и человека. Такая атака эксплуатирует тонкости стандартов кодирования символо…
Почему моё приложение при открытии SVG-файла отправляет сетевые запросы?

Дата: 18 Фев 2022

Автор: Сергей Васильев

Вы решили сделать приложение, работающее с SVG. Набрали библиотек, запаслись энтузиазмом, и в итоге всё удалось. Но вот незадача! Внезапно вы обнаруживаете, что приложение отправляет странные сетевые…

Комментарии (0)

Следующие комментарии next comments
close comment form
Unicorn with delicious cookie
Мы используем куки, чтобы пользоваться сайтом было удобно.
Хорошо