CVE-2018-17186
Description
Apache Syncope allows administrators with workflow definition entitlements to exploit XML External Entity (XXE) vulnerabilities via malicious BPMN definitions, enabling file read, write, and code execution.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Apache Syncope allows administrators with workflow definition entitlements to exploit XML External Entity (XXE) vulnerabilities via malicious BPMN definitions, enabling file read, write, and code execution.
Vulnerability
CVE-2018-17186 is an XML External Entity (XXE) vulnerability in Apache Syncope. An administrator with workflow definition entitlements can inject malicious DTDs into BPMN definitions processed by the Flowable engine in syncope-core. The affected versions are < 2.0.11 and >= 2.1.0, < 2.1.2 [1][4]. The vulnerability arises because the XML stream reader (XMLInputFactory) does not disable DTD and external entity processing, as shown in the fix commit [3] that sets IS_SUPPORTING_EXTERNAL_ENTITIES and SUPPORT_DTD to FALSE.
Exploitation
An attacker must have administrator-level access with entitlements to create or edit workflow (BPMN) definitions. By crafting a malicious BPMN XML file that includes external entity references, the attacker can trigger XML parsing that resolves external entities. The attack does not require user interaction beyond administrative access. The specific code paths include FlowableDeployUtils and ReconciliationReportParser [3].
Impact
Successful exploitation allows the attacker to perform arbitrary file read on the server, write files to the filesystem, and potentially execute arbitrary code. This compromises the confidentiality, integrity, and availability (CIA) of the Affected Syncope instance. The attacker gains the privileges of the Syncope server process, which typically has broad system access [1][2].
Mitigation
Apache Syncope released patched versions to address this vulnerability: upgrade to version 2.0.11 or 2.1.2, depending on the release line [4]. No workaround is provided in the references. All users running affected versions should upgrade immediately. The vulnerability is not listed in the CISA Known Exploited Vulnerabilities (KEV) catalog.
AI Insight generated on May 22, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
org.apache.syncope:syncope-coreMaven | < 2.0.11 | 2.0.11 |
org.apache.syncope:syncope-coreMaven | >= 2.1.0, < 2.1.2 | 2.1.2 |
Affected products
2- Apache Software Foundation/Apache Syncopev5Range: Apache Syncope releases prior to 2.0.11 and 2.1.2
Patches
2a0f35f45f8caEnsuring all XML input processing is safe - disable DTD and external entities
3 files changed · +18 −9
client/console/src/main/java/org/apache/syncope/client/console/widgets/reconciliation/ReconciliationReportParser.java+7 −2 modified@@ -32,10 +32,15 @@ public final class ReconciliationReportParser { - private static final XMLInputFactory INPUT_FACTORY = XMLInputFactory.newInstance(); + private static final XMLInputFactory XML_INPUT_FACTORY = XMLInputFactory.newInstance(); + + static { + XML_INPUT_FACTORY.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, Boolean.FALSE); + XML_INPUT_FACTORY.setProperty(XMLInputFactory.SUPPORT_DTD, Boolean.FALSE); + } public static ReconciliationReport parse(final Date run, final InputStream in) throws XMLStreamException { - XMLStreamReader streamReader = INPUT_FACTORY.createXMLStreamReader(in); + XMLStreamReader streamReader = XML_INPUT_FACTORY.createXMLStreamReader(in); streamReader.nextTag(); // root streamReader.nextTag(); // report streamReader.nextTag(); // reportlet
ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/impl/FlowableDeployUtils.java+8 −1 modified@@ -41,6 +41,13 @@ public final class FlowableDeployUtils { private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + private static final XMLInputFactory XML_INPUT_FACTORY = XMLInputFactory.newInstance(); + + static { + XML_INPUT_FACTORY.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, Boolean.FALSE); + XML_INPUT_FACTORY.setProperty(XMLInputFactory.SUPPORT_DTD, Boolean.FALSE); + } + public static Deployment deployDefinition( final ProcessEngine engine, final String resourceName, final byte[] definition) { @@ -58,7 +65,7 @@ public static void deployModel(final ProcessEngine engine, final ProcessDefiniti getResourceAsStream(procDef.getDeploymentId(), procDef.getResourceName()); InputStreamReader isr = new InputStreamReader(bpmnStream)) { - xtr = XMLInputFactory.newInstance().createXMLStreamReader(isr); + xtr = XML_INPUT_FACTORY.createXMLStreamReader(isr); BpmnModel bpmnModel = new BpmnXMLConverter().convertToBpmnModel(xtr); Model model = engine.getRepositoryService().newModel();
ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/support/DomainProcessEngineFactoryBean.java+3 −6 modified@@ -18,16 +18,14 @@ */ package org.apache.syncope.core.flowable.support; -import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; -import java.util.List; import java.util.Map; import javax.sql.DataSource; import org.apache.commons.lang3.StringUtils; import org.flowable.engine.ProcessEngine; import org.flowable.common.engine.impl.cfg.SpringBeanFactoryProxyMap; import org.flowable.common.engine.impl.interceptor.EngineConfigurationConstants; -import org.flowable.engine.form.AbstractFormType; import org.flowable.engine.impl.util.EngineServiceUtil; import org.flowable.idm.spring.SpringIdmEngineConfiguration; import org.flowable.spring.SpringExpressionManager; @@ -84,9 +82,8 @@ public DomainProcessEngine getObject() throws Exception { EngineConfigurationConstants.KEY_IDM_ENGINE_CONFIG, ctx.getBean(SpringIdmEngineConfiguration.class)); } - List<AbstractFormType> customFormTypes = new ArrayList<>(); - customFormTypes.add(new DropdownFormType(null)); - conf.setCustomFormTypes(customFormTypes); + conf.setEnableSafeBpmnXml(true); + conf.setCustomFormTypes(Arrays.asList(new DropdownFormType(null))); engines.put(domain, conf.buildProcessEngine()); }
a0f35f45f8caEnsuring all XML input processing is safe - disable DTD and external entities
3 files changed · +18 −9
client/console/src/main/java/org/apache/syncope/client/console/widgets/reconciliation/ReconciliationReportParser.java+7 −2 modified@@ -32,10 +32,15 @@ public final class ReconciliationReportParser { - private static final XMLInputFactory INPUT_FACTORY = XMLInputFactory.newInstance(); + private static final XMLInputFactory XML_INPUT_FACTORY = XMLInputFactory.newInstance(); + + static { + XML_INPUT_FACTORY.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, Boolean.FALSE); + XML_INPUT_FACTORY.setProperty(XMLInputFactory.SUPPORT_DTD, Boolean.FALSE); + } public static ReconciliationReport parse(final Date run, final InputStream in) throws XMLStreamException { - XMLStreamReader streamReader = INPUT_FACTORY.createXMLStreamReader(in); + XMLStreamReader streamReader = XML_INPUT_FACTORY.createXMLStreamReader(in); streamReader.nextTag(); // root streamReader.nextTag(); // report streamReader.nextTag(); // reportlet
ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/impl/FlowableDeployUtils.java+8 −1 modified@@ -41,6 +41,13 @@ public final class FlowableDeployUtils { private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + private static final XMLInputFactory XML_INPUT_FACTORY = XMLInputFactory.newInstance(); + + static { + XML_INPUT_FACTORY.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, Boolean.FALSE); + XML_INPUT_FACTORY.setProperty(XMLInputFactory.SUPPORT_DTD, Boolean.FALSE); + } + public static Deployment deployDefinition( final ProcessEngine engine, final String resourceName, final byte[] definition) { @@ -58,7 +65,7 @@ public static void deployModel(final ProcessEngine engine, final ProcessDefiniti getResourceAsStream(procDef.getDeploymentId(), procDef.getResourceName()); InputStreamReader isr = new InputStreamReader(bpmnStream)) { - xtr = XMLInputFactory.newInstance().createXMLStreamReader(isr); + xtr = XML_INPUT_FACTORY.createXMLStreamReader(isr); BpmnModel bpmnModel = new BpmnXMLConverter().convertToBpmnModel(xtr); Model model = engine.getRepositoryService().newModel();
ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/support/DomainProcessEngineFactoryBean.java+3 −6 modified@@ -18,16 +18,14 @@ */ package org.apache.syncope.core.flowable.support; -import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; -import java.util.List; import java.util.Map; import javax.sql.DataSource; import org.apache.commons.lang3.StringUtils; import org.flowable.engine.ProcessEngine; import org.flowable.common.engine.impl.cfg.SpringBeanFactoryProxyMap; import org.flowable.common.engine.impl.interceptor.EngineConfigurationConstants; -import org.flowable.engine.form.AbstractFormType; import org.flowable.engine.impl.util.EngineServiceUtil; import org.flowable.idm.spring.SpringIdmEngineConfiguration; import org.flowable.spring.SpringExpressionManager; @@ -84,9 +82,8 @@ public DomainProcessEngine getObject() throws Exception { EngineConfigurationConstants.KEY_IDM_ENGINE_CONFIG, ctx.getBean(SpringIdmEngineConfiguration.class)); } - List<AbstractFormType> customFormTypes = new ArrayList<>(); - customFormTypes.add(new DropdownFormType(null)); - conf.setCustomFormTypes(customFormTypes); + conf.setEnableSafeBpmnXml(true); + conf.setCustomFormTypes(Arrays.asList(new DropdownFormType(null))); engines.put(domain, conf.buildProcessEngine()); }
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
4- github.com/advisories/GHSA-qfjv-998w-q48fghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2018-17186ghsaADVISORY
- github.com/apache/syncope/commit/a0f35f45f8ca5c98853ae8477fb2db81a84709aghsaWEB
- syncope.apache.org/securityghsax_refsource_MISCWEB
News mentions
0No linked articles in our index yet.