Небольшое исправление для CVE-2016-3720 с более старыми версиями jackson-all-1.9.11 и в jackson 2.x, которые не исправлены
Объяснение CVE-2016-3720 https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2016-3720 является расплывчатым, но при чтении кода я обнаружил следующие проблемы. Даже после устранения проблем инструмент проверки зависимостей OWasp по-прежнему сообщает, что файл JAR уязвим для атаки. Я думаю, что это имеет ложный положительный результат после применения исправления.
CVE-2016-3720 раскрывает атаку внедрения XML-сущностей в библиотеку Джексона. https://www.owasp.org/index.php/XML_External_Entity_(XXE)_Processing Атака инъекцией сущности XML может создать бесконечный цикл при разборе файла XML.
Который в конечном итоге поглотит всю память на сервере приложений, или может добавить ссылку на внешний сайт (об этой проблеме сообщается).
К сожалению, исходный код более старой версии Jackson недоступен на Github, исходные версии проекта возвращаются только к уровню jackson-databind-2.0.0-RC1.
Если вы используете более старую версию Spring, то, возможно, вы не сможете обновить ее до новейшей версии Jackson 2.x, так что теперь у вас возникла дилемма безопасности. Как исправить уязвимость, не обновляя Spring.
6 ответов
Это то, что вам нужно сделать:
Используя веб-декомпилятор ( www.javadecompilers.com), вы можете получить весь исходный код для jar-файла jackson-all-1.9.11.jar . (Это будет работать на любой версии Джексона)
The fixes are fairly simple!
In the 1.9.x version the following 2 files allow XML entity injection.
org/codehaus/jackson/xc/DomElementJsonDeserializer.java
org/codehaus/jackson/map/ext/DOMDeserializer.java
When you update the jar be sure to update the additional nested inner classes.
org/codehaus/jackson/map/ext/DOMDeserializer.class
org/codehaus/jackson/map/ext/DOMDeserializer$DocumentDeserializer.class
org/codehaus/jackson/map/ext/DOMDeserializer$NodeDeserializer.class
org/codehaus/jackson/xc/DomElementJsonDeserializer.class
In the 2.x.x version the package name has changed.
These files need to be modified
com/fasterxml/jackson/databind/ext/DOMDeserializer.java
com/fasterxml/jackson/dataformat/xml/XmlFactory.java
В версии 1.9 решение для прекращения внедрения Entity заключается в добавлении следующей строки к двум файлам.
.setFeature(javax.xml.XMLConstants.FEATURE_SECURE_PROCESSING, true);
Здесь можно добавить его в декомпилированный код, затем перекомпилировать файлы и обновить файлы JAR.
public abstract class DOMDeserializer<T>
extends FromStringDeserializer<T> {
static final DocumentBuilderFactory _parserFactory;
static {
_parserFactory = DocumentBuilderFactory.newInstance();
/* CVE-2016-3720 */
try {
_parserFactory.setFeature(javax.xml.XMLConstants.FEATURE_SECURE_PROCESSING, true);
} catch (ParserConfigurationException e) {
e.printStackTrace();
}
// Move this line from the static block lower in the file.
_parserFactory.setNamespaceAware(true);
}
public DomElementJsonDeserializer() {
super(Element.class);
try {
DocumentBuilderFactory bf = DocumentBuilderFactory.newInstance();
bf.setNamespaceAware(true);
/* CVE-2016-3720 */
bf.setFeature(javax.xml.XMLConstants.FEATURE_SECURE_PROCESSING, true);
this.builder = bf.newDocumentBuilder();
}
catch (ParserConfigurationException e) {
throw new RuntimeException();
}
}
В версии 2.x вам нужно немного изменить этот файл. Добавьте строку:
xmlIn.setProperty("javax.xml.stream.isSupportingExternalEntities", Boolean.FALSE);
package com.fasterxml.jackson.dataformat.xml;
public class XmlFactory
extends JsonFactory {
protected XmlFactory(ObjectCodec oc, int xpFeatures, int xgFeatures, XMLInputFactory xmlIn, XMLOutputFactory xmlOut, String nameForTextElem) {
super(oc);
this._xmlParserFeatures = xpFeatures;
this._xmlGeneratorFeatures = xgFeatures;
this._cfgNameForTextElement = nameForTextElem;
if (xmlIn == null) {
xmlIn = XMLInputFactory.newInstance();
xmlIn.setProperty("javax.xml.stream.isSupportingExternalEntities", Boolean.FALSE);
}
Я надеюсь, что вы нашли это полезным.
Питер
Исходный код Jackson 1 доступен по адресу https://github.com/FasterXML/jackson-1. Я создал запрос извлечения: https://github.com/FasterXML/jackson-1/pull/1
Мы можем использовать это для решения уязвимой проблемы.
repositories {
maven {
url "https://packages.atlassian.com/maven-3rdparty"
}
}
implementation group: 'org.codehaus.jackson', name: 'jackson-mapper-asl', version: '1.9.14-atlassian-6'
Даже после устранения проблем инструмент проверки зависимостей OWasp по-прежнему сообщает, что файл JAR уязвим для атаки. Я думаю, что это имеет ложный положительный результат после применения исправления.
Обратите внимание, что OWASP DC не сканирует код. Он использует доказательства, такие как имя JAR, чтобы связать его с данными в NVD, поэтому, если имя банки указывает на уязвимую версию, он будет идентифицировать ее как уязвимую. Когда вы создали банку, в которой, как вы утверждаете, устранена уязвимость, вы можете использовать файл подавления с таким содержимым, как:
<?xml version="1.0" encoding="UTF-8"?>
<suppressions xmlns="https://www.owasp.org/index.php/OWASP_Dependency_Check_Suppression">
<suppress>
<notes>There I fixed that</notes>
<sha1>YOUR-JAR-SHA1-HERE</sha1>
<cve>CVE-2016-3720</cve>
</suppress>
</suppressions>
Обратите внимание, что если вы уже используете файл подавления, вы просто добавляете новый <suppress>
запись в существующий файл.
Одно примечание ко второй части: вместо модификации исходного кода, можно передать явно инстанцированный XmlFactory
(с помощью XmlMapper
). Конструктор доступен с 2.4. Это избавляет от необходимости управлять модифицированными банками.
Если вы застряли на Jackson 1.9.13, вместо десериализации JAR и повторной упаковки вы можете добавить эту функцию путем отражения:
static {
mitigateCVE20163720Vulnerability();
}
@SneakyThrows
static void mitigateCVE20163720Vulnerability() {
var field = org.codehaus.jackson.map.ext.DOMDeserializer.class.getDeclaredField("_parserFactory");
field.setAccessible(true);
var documentBuilderFactory = (DocumentBuilderFactory) field.get(null);
documentBuilderFactory.setFeature(javax.xml.XMLConstants.FEATURE_SECURE_PROCESSING, true);
}