Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
В этой статье описываются проблемы безопасности, связанные с LINQ to XML, и приведены рекомендации по устранению рисков безопасности.
Общие сведения о безопасности LINQ to XML
Технология LINQ to XML разрабатывалась в большей степени для повышения удобства программирования, чем для серверных приложений с жесткими требованиями к безопасности. Большинство XML-сценариев состоит из обработки доверенных XML-документов, а не тех XML-документов, не заслуживающих доверия, которые передаются на сервер. Технология LINQ to XML оптимизирована для таких сценариев.
Если нужно обработать не заслуживающие доверия данные из неизвестного источника, рекомендуется использовать экземпляр класса XmlReader, настроенного на предотвращение путем фильтрации известных атак XML типа «отказ в обслуживании».
Если вы настроили XmlReader для устранения атак типа "отказ в обслуживании", вы можете использовать это средство чтения, чтобы заполнить дерево LINQ to XML и по-прежнему воспользоваться преимуществами повышения производительности программиста LINQ to XML. Многие приемы устранения рисков включают создание агентов чтения, настроенных на решение проблем безопасности, а затем создание экземпляра XML-дерева с помощью такого настроенного агента чтения.
XML по своей природе уязвим для атак типа «отказ в обслуживании» из-за того, что XML-документы не ограничены по размеру, глубине, длине имен элементов и так далее. Независимо от компонента, с помощью которого обрабатывается XML, следует всегда быть готовым к очистке домена приложения, если он потребляет излишне много ресурсов.
Устранение атак XML, XSD, XPath и XSLT
Технология LINQ to XML построена на основе объектов XmlReader и XmlWriter. LINQ to XML поддерживает XSD и XPath через методы расширения в пространствах имен System.Xml.Schema и System.Xml.XPath. Используя XmlReaderклассы и XPathNavigatorXmlWriter классы в сочетании с LINQ to XML, можно вызвать XSLT для преобразования деревьев XML.
Если вы работаете в менее безопасной среде, существует ряд проблем безопасности, связанных с XML и использованием классов в System.Xml, System.Xml.SchemaSystem.Xml.XPathи System.Xml.Xsl. Эти проблемы включают в себя, но не ограничиваются следующими:
- Языки XSD, XPath и XSLT основаны на использовании строк, поэтому в них могут быть определены операции, которые занимают много времени и требуют большого объема памяти. Это ответственность программистов приложений, которые принимают строки XSD, XPath или XSLT из ненадежных источников для проверки того, что строки не являются вредоносными, или отслеживать и устранять вероятность того, что оценка этих строк приведет к чрезмерному потреблению системных ресурсов.
- Схемы XSD (включая встроенные схемы) по сути уязвимы для атак типа "отказ в обслуживании"; Не следует принимать схемы из ненадежных источников.
- XSD и XSLT могут включать ссылки на другие файлы, что может привести к возникновению атак, охватывающих несколько зон и доменов.
- Внешние сущности в DTD могут привести к атакам, распространяющимся на несколько зон и доменов.
- DTD уязвимы для атак типа «отказ в обслуживании».
- Подверженными атакам типа «отказ в обслуживании» становятся XML-документы с чрезмерно глубокой структурой, поэтому следует ограничивать глубину вложенности элементов в XML-документах.
- Не принимать вспомогательные компоненты, такие как NameTable, XmlNamespaceManagerи XmlResolver объекты, из ненадежных сборок.
- С целью снижения угрозы атак, которые могут быть связаны с обработкой больших документов, рекомендуется считывать данные в виде фрагментов.
- Предпосылкой возникновения многих атак может стать применение блоков скриптов в таблице стилей XSLT.
- Перед конструированием динамических выражений XPath следует выполнять тщательную проверку.
Проблемы безопасности LINQ to XML
Проблемы безопасности в этой статье не представлены в определенном порядке. Важны все вопросы, поэтому их необходимо решать должным образом.
Успешная атака с целью повышения прав доступа предоставляет вредоносной сборке более полный контроль над средой. Успешная атака с целью повышения прав доступа может привести к раскрытию данных, отказу в обслуживании и так далее.
Приложения не должны раскрывать данные пользователям, которые не уполномочены видеть эти данные.
Проведение атаки типа «отказ в обслуживании» приводит к тому, что синтаксический анализатор XML или средства LINQ to XML начинают потреблять чрезмерный объем памяти или ресурсов ЦП. Атаки типа «отказ в обслуживании» считаются менее серьезными, чем атаки с целью повышения прав доступа или атаки, направленные на раскрытие данных. Однако они важны в сценарии, в котором серверу необходимо обрабатывать XML-документы из ненадежных источников.
Не предоставляйте сообщения об ошибках ненадежным вызывающим абонентам
В описании ошибки раскрываются такие сведения, как преобразуемые данные, имена файлов или подробности реализации. Сообщения об ошибках не должны предоставляться вызывающим пользователям, которые не являются доверенными. Необходимо перехватывать все ошибки и создавать собственные сообщения об ошибках.
Не вызывайте CodeAccessPermissions.Assert в обработчике событий
Сборка может иметь меньшее или большее количество разрешений. Сборка с большими разрешениями имеет более полный контроль над компьютером и средой.
Если в коде сборки с большими разрешениями вызывается метод CodeAccessPermission.Assert в обработчике события, а затем полученное XML-дерево передается вредоносной сборке, имеющей меньшие разрешения, то в последней сборке может быть активизировано событие. Так как событие запускает код, который находится в сборке с большими разрешениями, вредоносные сборки будут работать с повышенными привилегиями.
Корпорация Майкрософт рекомендует ни в коем случае не вызывать метод CodeAccessPermission.Assert в обработчике события.
Не принимать DTD из ненадежных источников
Сущности в DTD изначально являются небезопасными. Вредоносный XML-документ, содержащий DTD, позволяет средству синтаксического анализа использовать всю память и время ЦП, что приводит к атаке типа "отказ в обслуживании". Поэтому в LINQ to XML обработка DTD отключена по умолчанию. Не следует принимать DTD из ненадежных источников.
Примером использования DTD из ненадежных источников служит веб-приложение, позволяющее пользователям Интернета передавать XML-файл, ссылающийся на определение DTD и DTD-файл. При проверке этого файла на наличие вредоносного определения DTD может произойти атака типа «отказ в обслуживании» на сервер. Другим примером приема DTD из ненадежных источников является применение ссылки на DTD в общем сетевом ресурсе, также разрешающем анонимный FTP-доступ.
Избегайте чрезмерного выделения буфера
Разработчики приложений должны учитывать, что применение слишком крупных источников данных может привести к исчерпанию ресурсов и возникновению атаки типа «отказ в обслуживании».
Если злонамеренный пользователь предоставляет или передает очень большой XML-документ, это может стать причиной чрезмерного потребления системных ресурсов LINQ to XML. Это равнозначно атаке типа «отказ в обслуживании». Чтобы предотвратить это, можно задать XmlReaderSettings.MaxCharactersInDocument свойство и создать средство чтения, которое затем ограничено размером документа, который он может загрузить. Затем с помощью средства чтения создается XML-дерево.
Например, если известно, что максимальный ожидаемый размер XML-документов из не заслуживающего доверия источника меньше 50 КБ, присвойте свойству XmlReaderSettings.MaxCharactersInDocument значение 100 000. При этом обработка XML-документов не будет нарушена, но уменьшится риск атаки типа «отказ в обслуживании», при которой могут передаваться документы, требующие большого объема памяти.
Избегайте избыточного расширения сущностей
Одна из известных атак типа «отказ в обслуживании» при использовании DTD основана на документе, вызывающем чрезмерное раскрытие сущности. Чтобы предотвратить это, можно задать XmlReaderSettings.MaxCharactersFromEntities свойство и создать средство чтения, которое затем ограничено количеством символов, которые приводят к расширению сущности. Затем с помощью средства чтения создается XML-дерево.
Ограничение глубины иерархии XML
Одной из возможных атак типа «отказ в обслуживании» является предоставление документа с избыточной глубиной иерархии. Чтобы предотвратить это, можно упаковать в собственный XmlReader класс, который подсчитывает глубину элементов. Если эта глубина превышает заранее определенную приемлемую величину, можно завершить обработку вредоносного документа.
Защита от ненадежных реализаций XmlReader или XmlWriter
Администраторы должны убедиться, что все внешние реализации XmlReader и XmlWriter имеют строгие имена и зарегистрированы в конфигурации компьютера. Это позволяет предотвратить загрузку злонамеренного кода под видом модуля чтения или записи.
Периодически освобождаемые объекты, ссылающиеся на XName
Чтобы защититься от атак определенных типов, разработчики приложений должны регулярно освобождать все объекты, имеющие ссылку на объект XName в домене приложения.
Защита от случайных XML-имен
Приложения, которые принимают данные из ненадежных источников, следует рассмотреть возможность проверки возможности случайных имен XML и пространств имен с помощью XmlReader оболочки в пользовательском коде. При обнаружении таких случайно сформированных XML-имен или пространств имен приложение может завершить обработку вредоносного документа.
Может потребоваться ограничить количество имен в каждом конкретном пространстве имен (включая имена вне пространства имен) до приемлемого предела.
Сериализация объектов LINQ to XML в XML-текст перед передачей данных в ненадежный компонент
LINQ to XML можно использовать для создания конвейеров обработки, в которых различные компоненты приложения загружают, проверяют, запрашивают, преобразуют, обновляют и сохраняют XML-данные, передаваемые между компонентами в виде xml-деревьев. Это может способствовать оптимизации производительности, поскольку издержки загрузки и сериализации объектов в XML-текст возникают только в конечных точках конвейера. Однако разработчики должны знать, что все заметки и обработчики событий, созданные одним компонентом, доступны для других компонентов. Это может привести к появлению различных уязвимых мест, если одни компоненты заслуживают доверия в меньшей степени, чем другие. Чтобы построить безопасные конвейеры из компонентов, в меньшей степени заслуживающих доверия, необходимо сериализовать объекты LINQ to XML в XML-текст перед их передачей менее доверенному компоненту.
Определенный уровень безопасности предоставляется средой CLR. Например, компонент, который не включает частный класс, не может получить доступ к заметкам, ключом которых является этот класс. Однако заметки можно удалить компонентами, которые не могут их читать. Это может использоваться в качестве атаки для злонамеренного изменения данных.