Атака XXE миллиард смеха, похоже, не была смягчена, как ожидалось, рекомендованным Sonar решением для предотвращения атак XXE.

Угрозы безопасности XXE на данный момент нет. Он занимает 4-е место в списке десяти основных угроз безопасности веб-приложений OWASP, поэтому я ожидаю, что стандартные XML-библиотеки Java предотвратят такие атаки. Однако, когда я использую класс Validator способом, рекомендованным Sonar, синтаксические анализаторы правил XML не должны быть уязвимы для атак XXE (java:S2755) (ссылка на правило):

String xsd = "xxe.xsd";
String xml = "billionlaughs.xml";
StreamSource xsdStreamSource = new StreamSource(xsd);
StreamSource xmlStreamSource = new StreamSource(xml);

SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = schemaFactory.newSchema(xsdStreamSource);
schemaFactory.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, "");
schemaFactory.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
// validators will also inherit of these properties
Validator validator = schema.newValidator();

validator.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, "");   // Compliant
validator.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");   // Compliant

StringWriter writer = new StringWriter();
validator.validate(xmlStreamSource, new StreamResult(writer));

с Java 11, при этом миллиардсмех.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE lolz [
<!ENTITY lol "lol">
<!ENTITY lol2 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
<!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;">
]>
<lolz>&lol9;</lolz>

Я получаю следующее исключение:

Exception in thread "main" org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; JAXP00010001: The parser has encountered more than "64000" entity expansions in this document; this is the limit imposed by the JDK.
    at java.xml/com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:204)
    at java.xml/com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.fatalError(ErrorHandlerWrapper.java:178)
    at java.xml/com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:400)
    at java.xml/com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:327)
    at java.xml/com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:284)
    at java.xml/com.sun.org.apache.xerces.internal.impl.XMLEntityManager.startEntity(XMLEntityManager.java:1413)
    at java.xml/com.sun.org.apache.xerces.internal.impl.XMLEntityManager.startEntity(XMLEntityManager.java:1337)
    at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanEntityReference(XMLDocumentFragmentScannerImpl.java:1842)
    at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2982)
    at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:605)
    at java.xml/com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:112)
    at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:534)
    at java.xml/com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:888)
    at java.xml/com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:824)
    at java.xml/com.sun.org.apache.xerces.internal.jaxp.validation.StreamValidatorHelper.validate(StreamValidatorHelper.java:176)
    at java.xml/com.sun.org.apache.xerces.internal.jaxp.validation.ValidatorImpl.validate(ValidatorImpl.java:115)
    at trial.Trial.main(Trial.java:35)

Итак, мой вопрос заключается в том, считается ли это правильным способом смягчения атаки миллиарда смехов (в конце концов, существует ограничение в 64000 расширений сущностей), или, может быть, есть другой способ настроить синтаксический анализ XML, чтобы просто не смотреть на раздел <!DOCTYPE ..> .


person John Donn    schedule 03.09.2020    source источник
comment
Что мог бы сделать синтаксический анализатор вместо этого?   -  person Henry    schedule 03.09.2020
comment
@Henry игнорируйте раздел ‹!DOCTYPE ..›, если я этого хочу.   -  person John Donn    schedule 03.09.2020
comment
Потенциально дубликат stackoverflow.com/q/46282711   -  person Marcono1234    schedule 03.09.2020


Ответы (1)


Как десятка лучших OWASP, так и правило SonarSource касается XML Внешние объекты, а атака Billion Laughs построена с использованием XML Внутренние объекты. Внутренние сущности определяются как:

[...] Отдельного физического объекта хранения нет, а содержимое объекта указано в объявлении.

С тех пор Java имеет по крайней мере Java 1.5 предел расширения сущности, с которым вы столкнулись.

Тем не менее рекомендуемые меры по снижению риска необходимы для защиты от атак XML External Entity. Вы можете проверить это самостоятельно, используя один из примеров, представленных на сайте OWASP или в правиле SonarSource. Например, пусть ваш валидатор проверит следующее (при условии, что ваша ОС — Linux):

<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
<foo>&xxe;</foo>

И затем пусть ваш код выводит значение вашего StringWriter writer впоследствии. Вы увидите, что без смягчения он содержит содержимое файла /etc/passwd.


Как описано в памятке OWASP XML по предотвращению внешних сущностей, в некоторых случаях вы также можете полностью отключите DTD (определение типа документа), чтобы запретить использование как внешних, так и внутренних объектов.

person Marcono1234    schedule 03.09.2020
comment
Итак, дело в том, что атака «миллиард смеха» — это не XXE. .. в некоторых случаях вы также можете полностью отключить DTD .. - не вижу, как это сделать для валидатора. - person John Donn; 03.09.2020