openjdk.ruOpenJDK на русском

JEP 185: Restrict Fetching of External XML Resources

Ограничение загрузки внешних XML-ресурсов

ОтветственныйJoe Wang
ТипFeature
ОбластьSE
СтатусClosed / Delivered
Выпуск8
Компонентxml / jaxp
JSR206 MR
Обсуждениеcore dash libs dash dev at openjdk dot java dot net
ТрудоёмкостьL
ДлительностьL
РецензентыAlan Bateman, Lance Andersen
ОдобренBrian Goetz
Создан2013/04/09 20:00
Обновлён2017/06/14 17:46
Задача8046175

Аннотация

Расширить API JAXP, добавив возможность ограничить набор сетевых протоколов, по которым могут загружаться внешние ресурсы.

Цели

Определить стандартные свойства, ограничивающие набор сетевых протоколов, по которым могут загружаться внешние ресурсы. Новые свойства должны без проблем работать вместе с существующей функцией безопасной обработки (secure processing), а также с другими существующими функциями и свойствами.

Что не является целью

Это предложение касается обработки внешних ресурсов. Мы не собираемся перерабатывать существующую архитектуру безопасности или менять функции и свойства, которые уже поддерживаются реализацией, но не описаны в API.

Мотивация

Функция безопасной обработки JAXP ограничивает ресурсы XML-процессоров, чтобы противостоять некоторым видам атак типа «отказ в обслуживании». Однако она не ограничивает способы, которыми могут загружаться внешние ресурсы, хотя это тоже полезно при безопасной обработке XML-документов. Текущая реализация JAXP поддерживает свойства, специфичные для реализации, с помощью которых можно ввести такие ограничения, но нужен стандартный способ это сделать.

Описание

JAXP 1.5 добавляет три новых свойства уровня API, которые ограничивают внешние соединения определёнными протоколами, указанными по имени:

  • javax.xml.XMLConstants.ACCESS_EXTERNAL_DTD: список протоколов, по которым можно обращаться к внешним DTD и внешним ссылкам на сущности.

  • javax.xml.XMLConstants.ACCESS_EXTERNAL_SCHEMA: список протоколов, по которым могут разрешаться внешние ссылки на схемы, заданные атрибутом schemaLocation элементов import и include.

  • javax.xml.XMLConstants.ACCESS_EXTERNAL_STYLESHEET: список протоколов, по которым могут разрешаться внешние ссылки, заданные в конструкциях таблиц стилей, таких как инструкции обработки, функции document(), элементы import и элементы include.

Кроме того, добавляются три соответствующих системных свойства, чтобы разработчики могли менять настройки, не меняя код:

  • javax.xml.accessExternalDTD для ACCESS_EXTERNAL_DTD

  • javax.xml.accessExternalSchema для ACCESS_EXTERNAL_SCHEMA

  • javax.xml.accessExternalStylesheet для ACCESS_EXTERNAL_STYLESHEET

Наконец, эти свойства можно задать в существующем файле конфигурации ${java.home}/lib/jaxp.properties, чтобы определить поведение для всех запусков JDK или JRE. Записи в файле имеют формат property-name=value, например:

javax.xml.accessExternalDTD=file,http

Значения свойств

Значение любого из этих свойств — список протоколов, разделённых запятыми. Протокол — это часть URI, содержащая схему, а в случае протокола JAR — jar и часть со схемой, разделённые двоеточием. Синтаксис схемы:

scheme = alpha *( alpha | digit | "+" | "-" | "." )
where alpha = a-z and A-Z.

Синтаксис протокола JAR:

jar[:scheme]

Протоколы, в том числе ключевое слово jar, не зависят от регистра. Любые пробельные символы в значении, как они определены в Character.isSpaceChar(), игнорируются. Примеры протоколов: file, http и jar:file.

Значения по умолчанию: ограничивать ли соединения по умолчанию, решает реализация. Возможны варианты:

  • пустая строка не разрешает доступ;
  • конкретный протокол, например file, разрешает доступ только по этому протоколу; или
  • ключевое слово all разрешает доступ по всем протоколам.

Когда включён FEATURE_SECURE_PROCESSING, реализациям рекомендуется по умолчанию ограничивать внешние соединения, хотя это может вызвать проблемы у приложений, которые обрабатывают XML/XSD/XSL с внешними ссылками.

Предоставление полного доступа: ключевое слово all разрешает использовать все протоколы. Например, если задать jdk.xml.accessExternalDTD=all в файле jaxp.properties, система будет работать как раньше, без ограничений на способ загрузки внешних ресурсов.

Задание свойств через API JAXP

Свойства JAXP можно задать через фабрики JAXP следующим образом:

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setAttribute(name, value);

SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser parser = spf.newSAXParser();
parser.setProperty(name, value);

XMLInputFactory xif = XMLInputFactory.newInstance();
xif.setProperty(name, value);

SchemaFactory schemaFactory = SchemaFactory.newInstance(schemaLanguage);
schemaFactory.setProperty(name, value);

TransformerFactory factory = TransformerFactory.newInstance();
factory.setAttribute(name, value);

Область действия и порядок применения

javax.xml.XMLConstants#FEATURE_SECURE_PROCESSING — обязательная функция для XML-процессоров, включая DOM, SAX, проверку по схеме (Schema Validation), XSLT и XPath. Реализациям рекомендуется связывать с этой функцией функции и свойства, относящиеся к безопасности. Когда функция безопасной обработки установлена в true, реализации обязаны ограничивать обработку XML в соответствии с ограничениями реализации. Когда она установлена в false, реализация должна обрабатывать XML без ограничений. Для новых свойств, появившихся в JAXP 1.5, рекомендуется, чтобы при значении true функции безопасной обработки реализации ограничивали внешние соединения, а при значении false разрешали полный доступ.

Свойства, заданные в файле jaxp.properties, действуют на все запуски JDK или JRE и переопределяют значения по умолчанию или значения, которые могли быть заданы через FEATURE_SECURE_PROCESSING.

Системные свойства, если они заданы, действуют только на один запуск и переопределяют настройки по умолчанию, настройки из jaxp.properties или значения, которые могли быть заданы через FEATURE_SECURE_PROCESSING.

Свойства JAXP, заданные через фабрики JAXP или API SAXParser, переопределяют системные свойства, файл jaxp.properties, а также настройку FEATURE_SECURE_PROCESSING.

Новые свойства JAXP не будут влиять на конструкции, которые они должны ограничивать, в следующих ситуациях:

  • Когда для парсера SAX или DOM задан обработчик сущностей (entity resolver), для парсера StAX задан XML-обработчик (XML resolver) или для преобразователя задан URIResolver.

  • Когда схема создаётся явно методом SchemaFactory.newSchema().

  • Когда внешние ресурсы не нужны. Например, эталонная реализация поддерживает следующие функции и свойства, и их можно задать так, чтобы процессор не загружал внешние DTD и не разрешал внешние сущности.

    http://apache.org/xml/features/disallow-doctype-decl            true
    http://apache.org/xml/features/nonvalidating/load-external-dtd  false
    http://xml.org/sax/features/external-general-entities           false
    http://xml.org/sax/features/external-parameter-entities         false

Тестирование

Для каждого сценария будут добавлены новые тесты. Также будет выпущена новая версия JAXP TCK.

Потребуется серьёзное тестирование, чтобы оценить, можно ли настроить JDK так, чтобы он ограничивал соединения по умолчанию.

Риски и допущения

Спецификация JAXP 1.5 не определяет значения свойств по умолчанию. Из-за влияния на совместимость и связанного с этим риска JAXP 1.5 будет изначально интегрирован с конфигурацией по умолчанию, не ограничивающей соединения.

Спецификация JAXP 1.5 требует, чтобы новые свойства ограничивали внешние соединения, когда FEATURE_SECURE_PROCESSING явно установлен в true. Приложения, которые задают FEATURE_SECURE_PROCESSING, скорее всего, заметят несовместимое поведение, и им, возможно, придётся задать новые свойства JAXP, чтобы переопределить FEATURE_SECURE_PROCESSING.

Влияние

  • Другие компоненты JDK: изменение напрямую затрагивает JAX-WS. JAX-WS должен будет использовать новые свойства, чтобы определять, нужно ли разрешать внешние ресурсы. По результатам нашего исследования и обсуждения с ответственными за другие компоненты JDK, никакие другие компоненты напрямую не затронуты.

  • Совместимость: спецификация не влияет на совместимость. Реализация сама решает, сохранять ли совместимость, выбирая по умолчанию режим с ограничением или без ограничения.

  • I18n/L10n: потребуется перевести несколько новых сообщений об ошибках.

  • TCK: потребуется создать новую версию JAXP TCK.