Safe BPMN XML parsing in Flowable: what enableSafeBpmnXml protects
The setting that governs how a Flowable engine parses uploaded BPMN XML is enableSafeBpmnXml. It hardens the XML parser so that a crafted model cannot trigger the attacks that XML parsers are known for, such as external entity resolution and entity expansion. It works alongside deployment controls rather than replacing them: the setting limits what the parser will do with a file, while your deployment controls decide who may submit a file at all. Teams need to think about it whenever a model reaches the engine through any upload path, including the REST deployment endpoints, an admin console, a model editor that lets non-engineers submit XML, or an integration that pushes definitions from another system.
Before you rely on this control, confirm the exact property name, its default value and its precise behavior in the Flowable configuration documentation for the version you run. Flowable 8.0.0 was released on February 27, 2026, and configuration details can differ between major versions, so do not assume a setting from an older guide applies unchanged. Ask your implementation team to record the property, the version it was checked against and the environment where it is set, so the setting survives upgrades and is visible to your security reviewers. Note that the setting is not a substitute for input validation of other model content, such as scripts and expressions, which carry their own risks.
Plan for the cases the setting does not cover. Decide which roles may deploy process definitions, whether uploads go through a reviewed pipeline instead of direct engine access, and how deployments are logged so that a suspicious model can be traced to a person or system. Run a test deployment of deliberately malformed and oversized XML in a non-production environment, and confirm that the engine rejects it with a clear error and that the failure is recorded. Those checks give you evidence that the control works on your platform, which is more useful to an auditor or a security team than a configuration screenshot alone.
Which XML attacks the setting is meant to stop
A BPMN upload is XML that the engine parses on the server, so the parser becomes the attack surface. The cards below describe the main XML attack classes, what an attacker gains from each, and which layer of your deployment reduces the exposure. The safe parsing setting is one layer; parser configuration, deployment permissions and network egress rules cover the others.
External entity file disclosure
An XML document can declare an external entity that points at a local file, so the parser substitutes the file contents into the model it reads. An attacker who can deploy a model may be able to read server configuration or credential files and see them echoed back through errors or deployed definitions. Confirm with the Flowable release you run that enableSafeBpmnXml blocks external entity resolution, and check the setting is on in every environment, not only production.
Server-side request forgery
An external entity can also name a URL, so the parser makes an outbound request from the engine host. That lets an attacker probe internal hosts, cloud metadata endpoints or services that trust the engine's network position. Reduce this with the parser setting and with egress rules that stop the engine host from reaching sensitive internal addresses, then test both layers from the engine's own network segment.
Entity expansion resource exhaustion
Nested entity definitions can expand into a very large document from a small upload, consuming memory and CPU until the engine slows or fails. Because deployment is a shared engine operation, one oversized model can affect every process running on that node. Confirm the parser limits in your Flowable version, set container memory and CPU limits, and load test a deliberately nested sample in a non-production environment.
External DTD and schema fetches
A document can reference an external document type definition or schema that the parser downloads at parse time. This adds network calls to the deployment path, can hang threads while a remote host responds, and can pull content from a source you did not approve. Decide which external references, if any, your modeling pipeline needs, and block the rest at the parser and at network egress.
Parser errors that leak internal detail
Malformed XML can trigger parser exceptions that include file paths, class names, library versions or fragments of the input. An attacker who can submit repeated broken models can use these messages to map the stack. Check how the engine and your REST layer return deployment errors to callers, and limit who receives detailed error output, since that decision sits in your application configuration.
Who may deploy models
Safe parsing reduces what a valid-looking model can do, but any identity that deploys process definitions still changes what runs on your engine. Restrict deployment rights to a named group, record who deployed each version, and require review before a model reaches production. Treat the deployment path as privileged even when the parser setting is correct, because the engine does not decide who is allowed to upload.
Choosing how to configure safe parsing for each upload path
This table compares three ways to control BPMN XML intake: enabling enableSafeBpmnXml alongside your own upload checks, relying on network and file-type controls alone, and restricting deployment to a pipeline with no direct upload. Read each row against your own upload paths, then confirm the open points with Flowable before you choose.
| Option | Best fit | Main trade-off | Question to confirm with Flowable |
|---|---|---|---|
| enableSafeBpmnXml with application upload restrictions | Shared engine where business users upload models through the REST app or your own UI | Protection depends on the setting being applied on every engine that parses models, and your upload checks still need design and testing | Which parser entry points does the setting cover, and does it apply to every deployment path in the version we run? |
| Network and file-type checks only | Low-risk internal tooling with no model uploads and a narrow, trusted user group | File-type checks do not inspect XML content, so a valid BPMN file can still carry hostile constructs if it reaches the parser | Does Flowable provide any parser hardening beyond the setting, and which XML features are still reachable without it? |
| Pipeline-only deployment with no direct upload | Closed CI-driven estate where models are reviewed and deployed by a controlled release process | Business users must go through developers or release staff, which slows model changes and moves the control into pipeline access rights | Does the deployment API accept models from accounts outside the pipeline, and how do we restrict those accounts? |
| Combined approach | Regulated multi-tenant platform that accepts some uploads and needs audit evidence of who deployed what | Highest setup and review effort, with separate configuration to keep consistent across environments | Can we set the parser control and deployment rights in one place for all environments, and what evidence does the engine record for each deployment? |
Enabling safe BPMN XML parsing in Flowable step by step
This sequence takes a Flowable engine that accepts uploaded models from an open exposure to a controlled one, where every model entry point is known, the safe parsing setting is on, deployment rights are limited, and the protection has been tested with hostile samples before production.
Inventory every path that accepts BPMN and CMMN XML
Your platform team lists each route by which a model reaches the engine: the REST deployment endpoint, any admin or modeling UI, the Git or CI pipeline that pushes definitions, scheduled imports, and any integration that calls the deployment API. For each path, record who or what calls it, the credentials used, and whether the XML is authored by developers or by business users. The output is a written inventory that every later step checks against. Done when no path is left unlisted and each one has an owner.
Confirm the Flowable version and platform baseline
Your engineers record the Flowable engine version, the Java runtime, and the Spring and Jakarta EE stack in use, then compare them with the Flowable release notes and the Flowable configuration documentation for the release you run. Major versions change the Java, Spring and Jakarta baseline, so confirm that the version in production matches the one you tested against. Done when the baseline is written down and each deployment path in the inventory runs on a version you have confirmed supports the setting.
Set enableSafeBpmnXml in the engine configuration
Platform engineers enable the enableSafeBpmnXml property in the engine configuration, following the Flowable configuration documentation for how the property is applied in your deployment style (Spring Boot properties, a Java configuration bean, or the REST application configuration). Changes go through your normal change control and are deployed to a non-production environment first. Done when the running configuration shows the property set, and a restart or redeploy has taken effect in the engine logs.
Restrict who can call deployment endpoints
Security engineers limit deployment rights to named service accounts or roles, remove deployment access from general user groups, and confirm that the REST deployment endpoint requires authentication over HTTPS. Admin UIs and pipelines receive only the privileges they need. Verify with a valid user that a deployment succeeds, and with an unprivileged user that the same request is denied and recorded in the logs. Done when both results are captured and the deny event appears in your log pipeline.
Test with malicious and valid sample models
In a non-production environment, the security team builds a test set of valid BPMN and CMMN models and a set of hostile files, such as XML containing external entity declarations, oversized or deeply nested structures, and malformed documents. Each file is submitted through every path in the inventory. Valid models must deploy, and hostile files must be rejected with a logged error rather than causing a fault or a lookup outside the engine. Done when every hostile sample is rejected, every valid sample deploys, and the results are stored with the change record.
Confirm rejection and logging in production
After the non-production results are accepted, the change is promoted, and the same test set is run in production using a dedicated test model that is removed afterward, or a staging copy of production settings if production testing is not permitted. Operations confirms that alerts fire on denied deployments and that the log entries identify the caller and the source path. Done when the production check shows the expected rejection and alerting, and the inventory is updated with the final owner for each path.
Platform requirements to confirm before you turn it on
The parsing control depends on the Flowable version, the Java runtime and the framework stack around the engine, so confirm all three before you plan rollout. Flowable 7 moved to Java 17, Spring Boot 3 and Jakarta EE, according to the Flowable 7.0.0 release notes. Flowable 8.0.0 changed the baseline again: its release notes describe an upgrade to Spring Framework 7 and Spring Boot 4 with no backward compatibility for Spring Boot 3, Jackson 3 as the default JSON library with a Jackson 2 compatibility layer, and removal of JUnit 3 and 4 support. Those changes touch the XML parsing libraries and the way configuration is wired, so a setting that works on one baseline may need different placement on the other. Check the Flowable 8.0.0 release notes against your current stack before you assume anything carries over.
The embedding model decides where the setting lives and who owns it. A plain Java SE application or a servlet container such as Tomcat or Jetty sets engine configuration in code or in its own bootstrap files, so your application team owns the change. A Spring Boot application uses the Flowable starters, so the setting is expressed through Spring configuration and is reviewed alongside your application properties. The Flowable REST application is a separate deployable, so the setting belongs to whoever packages and operates that service, and your platform team needs to know it exists. Document which model you run and name the owner for each deployment that accepts models. Mixed estates, where one engine is embedded and another runs as the REST application, need a separate check for each.
Who may deploy models in each environment
Developers deploy models often, so this environment usually has the broadest deployment rights. Those rights should still belong to named individuals, and the environment should hold no production data or credentials. Developers also tend to copy configuration between machines, so confirm that the parsing setting is enabled here as well, which keeps tests close to production behavior.
- Deployment rights: Give each developer rights on a personal or team-scoped account rather than a shared administrator login.
- Uploads: Allow uploads only where the team needs to test the REST deployment path, and keep the parsing setting on during those tests.
- Approvals: Route model changes through merge requests in source control so a reviewer sees each BPMN file before it reaches a shared dev engine.
- Separation: Use separate databases, hostnames and credentials for this engine, and never import production process instances into it.
Check that development credentials cannot authenticate to staging or production hosts, and that the development engine is not reachable from outside your network.
Staging is where a model is proven before release, so its deployment path should resemble production. Uploads should come from the delivery pipeline's service account, not from people working by hand. Approval should be a separate step from the developer who wrote the model, and the environment should be configured the way production is configured, including the parsing setting.
- Deployment rights: Limit deployment to the pipeline's service account, with a small group of named platform or security staff able to run it manually during incidents.
- Uploads: Permit uploads only from the pipeline, and reject direct uploads from application users.
- Approvals: Require a second reviewer from the security or platform team to approve each promotion, and record the approver in the pipeline log.
- Separation: Keep staging on its own database and identity source, with test data that contains no live customer records.
Confirm that the staging configuration matches production in every setting that affects parsing and authorization, so test results mean something when the model is promoted.
Production should accept deployments from one controlled path only. End users and business applications should never upload BPMN or CMMN files, and interactive deployment should be an exception with its own record. Every deployment should trace to an approved change, and access to the deployment interface should be reviewed on a schedule that your change process sets.
- Deployment rights: Restrict deployment to the release pipeline and a small set of named operators, with no shared accounts.
- Uploads: Disable user-facing upload features, and keep the parsing setting enabled on every production node.
- Approvals: Record the change ticket, the reviewer and the model version for each deployment, and keep those records with the engine's own deployment history.
- Separation: Place the engine on a network segment that only the pipeline, the application tier and approved administrators can reach, and log administrative access.
Check which REST privileges and identity groups can call deployment endpoints, and confirm that they match the operator list in your change records.
A shared engine serves several business units or customers, so deployment rights must be scoped to the tenant that owns each model. In this model, the parsing setting protects the engine from hostile files, but it does not decide whether one tenant may replace another tenant's process. That decision belongs to your application's authorization checks, and the engine's own checks should be confirmed against the Flowable configuration documentation for your version.
- Deployment rights: Grant tenant administrators deployment rights only within their own tenant identifier, and keep platform operators outside tenant-level roles.
- Uploads: Decide per tenant whether uploads are offered at all, and default to pipeline-only deployment for tenants that do not need self-service.
- Approvals: Require the owning tenant and the platform team to approve each deployment, and store both approvals with the model version.
- Separation: Separate tenant data in queries and in deployment records, and test that one tenant's credentials cannot list or deploy another tenant's definitions.
Ask for a written list of which checks the engine performs and which your application must perform, and test a cross-tenant deployment attempt before go-live.
Operational risks that remain after parsing is hardened
Turning on safe BPMN XML parsing narrows one attack path, but it does not decide who may deploy, which route a model takes into the engine, or what a deployed model is allowed to execute. The cards below cover risks that persist after the setting is enabled, each with a control owner and the evidence to keep.
Over-broad deployment rights on REST endpoints
Any account that holds deployment privileges on the Flowable REST API can push a new process definition, so the setting only limits what a model can contain, not who can send one. Review which roles map to the REST access privilege and which accounts hold it, and confirm that deployment rights sit with a small group in your platform or change team. Control owner: platform engineering lead. Evidence to keep: the role-to-privilege mapping and a dated access review.
Uploads that bypass the application layer
If the engine is reachable directly, a deployment can skip the approval, scanning or pipeline checks your application applies to models. Confirm which network paths reach the engine's deployment endpoints and whether any service account can call them without going through your controlled process. Control owner: security architect. Evidence to keep: a network diagram showing every path to the engine and the firewall or gateway rules that restrict deployment calls.
Scripts and expressions with engine privileges
An accepted model can still contain script tasks, expressions or delegates that run with the engine's own privileges. The XML guard does not judge what those scripts do once deployed. Inventory which models use scripting, confirm whether the secure scripting configuration is in place, and require developer review for any model a non-developer authored. Control owner: application owner with a security reviewer. Evidence to keep: a script inventory per deployed definition and the review sign-off for each.
Missing audit of who deployed what
Without a record tying each deployed definition to a person or pipeline run, an incident response team cannot tell whether a suspicious model came from an approved change. Check that deployment events are logged with the caller identity and that the logs leave the engine host. Confirm the retention period with your logging team. Control owner: security operations lead. Evidence to keep: deployment logs with caller identity, timestamps and definition keys, forwarded to your central log store.
Drift between environments
If the setting is on in production but off in test or a developer sandbox, models that pass testing may be rejected in production, or unsafe models may be accepted somewhere that was never hardened. Compare the configuration of every environment, including containers and Helm values, against one reviewed baseline. Control owner: release manager. Evidence to keep: the baseline configuration file, the diff output from each environment and the date of the last comparison.
Questions teams ask before enabling safe BPMN XML parsing
What does enabling safe BPMN XML parsing cost?
The setting is a configuration change, so the cost sits in the work around it. You pay internal engineers to find where each Flowable engine reads its configuration, a non-production test environment where uploaded models can be exercised, and, if you want one, an external review of the deployment path. Some costs are one-time, such as the first configuration and test pass. Others recur, such as retesting after each Flowable upgrade and reviewing deployment permissions when staff change. A fixed-scope quote should list each component separately, state which environments are in scope, name the engines covered, and say what is included for retesting after an upgrade. Ask for these items in writing before work starts.
How long does configuring and testing the setting take?
Duration depends mainly on how many engines you run, how many environments must be checked, how many people can deploy models, and how many existing models need review. A single engine with a small, known set of deployers is much smaller work than several engines spread across teams and environments. The model review is often the least predictable part, because it depends on how many models you have and who wrote them. Ask for a schedule tied to milestones in the written scope, such as configuration confirmed, test cases passed, and deployment controls signed off, so you can see progress without relying on a single end date.
What does the work need from our team?
Three things matter most. First, someone who owns the Flowable configuration and the pipeline that deploys process definitions, so changes can be made and reviewed. Second, someone who knows who uploads or deploys models today, since those people are the ones the controls affect. Third, access to a non-production environment that matches production closely enough for the test results to mean something. Your security team should also agree who approves the deployment permissions and how exceptions are recorded. Without these people in place early, the configuration tends to be set but not checked, which leaves the main risk open.
Can our own team enable safe BPMN XML parsing without outside help?
Yes, if your team can change the engine configuration and has a non-production environment to test in. The setting itself is documented in the Flowable configuration docs, and the exact property name and where it is set depend on how you embed Flowable, whether as a Spring Boot application, in a servlet container, or through the REST application. Confirm the property name and its placement against the version you run before you change anything. Outside help is most useful for the surrounding controls: deciding who may deploy, reviewing existing models for risky content, and building test cases that show the engine rejects what it should. Your team can decide how much of that to take on.
How do we verify the setting actually took effect?
Check the effective configuration of each running engine, not only the file in your source repository, because container images, environment variables or deployment overrides can change what the engine loads. Then test behavior. In a non-production environment, deploy a model that contains a construct the setting is meant to block and confirm the engine refuses it. Keep the test model, the output and the configuration snapshot as evidence. Illustrative example: a team that changes the setting in a Helm values file but leaves an older environment variable in place would pass a source review and fail a deployment test. Repeat the checks after every change to the configuration or the deployment pipeline.
What changes when we upgrade Flowable?
Upgrades can change the platform the engine depends on, so review the release notes for every version between your current release and your target. Flowable 8.0.0, released on February 27, 2026, moved to Spring Framework 7 and Spring Boot 4 without backward compatibility for Spring Boot 3, made Jackson 3 the default JSON library, and removed JUnit 3 and 4 support. Flowable 7.0.0 moved the baseline to Java 17, Spring Boot 3 and Jakarta EE. Confirm in the release notes whether the setting's name, default or behavior changed, and whether the XML parser dependencies changed underneath it. Then repeat the verification steps from the previous question on the upgraded version before reopening deployment access.
Limits to confirm in your environment before relying on this control
The enableSafeBpmnXml setting narrows what an uploaded model can do, but its coverage depends on your Flowable release, how you embed the engine and what your own extensions do with XML. The cards below list the points to confirm with Flowable and check in the running system before you treat uploads as safe.
Release and embedding model support
Confirm that the Flowable release you run supports enableSafeBpmnXml in the way your embedding model uses it. Check the setting in the Spring Boot starter, the standalone engine configuration and the REST application separately, because each one builds the process engine configuration differently. Ask Flowable which release introduced the guard and whether any default changed in later releases such as 8.0.0. Record the exact release and configuration source in your change record.
Coverage across BPMN, CMMN and DMN
Determine whether the setting applies to every XML entry point you expose, not only BPMN deployment. Ask Flowable whether CMMN and DMN definitions parsed through the same deployment path are covered, and test each type with a crafted document containing an external entity reference. Also check paths that deploy definitions indirectly, such as REST deployment, the deployment API called from code, and any import tool your team uses.
Custom parsers and extensions
If your team has added custom BPMN parsers, listeners or XML-based extensions, confirm whether they create their own XML readers. A custom reader may bypass the protections the engine applies to its default factories. Review every place your code calls an XML parser, and ask Flowable which factories the safe setting configures. Test your extensions with the same malicious inputs you use for the stock engine.
Testing without exposing production
Build a test harness that deploys hostile samples to a non-production engine with the same release, configuration and deployment path as production. Record whether each sample is rejected, parsed, or causes errors or slow responses. Keep the samples in version control under restricted access, and avoid running them against shared or customer-facing environments. Repeat the test after each upgrade and configuration change.
Database and log exposure
Check whether rejected or accepted uploads leave their content in the database, the history tables, deployment resources, or application logs. Verify the log level for the engine and the web layer, and whether stack traces echo parts of the submitted XML. Confirm who can read the deployment resource table and any audit records. Uploaded models may contain embedded secrets, so treat these stores with the same controls you apply to the models themselves.
Change tracking between releases
Ask Flowable how it documents changes to XML parsing defaults, security fixes and removed components between releases. Read the release notes for each version you may move to, and note any changes to parser libraries, Spring or Jackson baselines that could affect XML handling. Subscribe to the project's release announcements and assign an owner to review them before each upgrade. Retest the controls whenever the release changes.
How DeployOpen scopes, delivers and supports safe BPMN XML parsing
DeployOpen approaches safe BPMN XML parsing in Flowable as a fixed-scope piece of work inside your own infrastructure. We agree the scope in writing, configure and test the parser and deployment controls against your Flowable version, then hand over the settings, evidence and runbooks your team needs to keep the engine locked down.
How we scope
- We confirm which Flowable engine, version and runtime host accept uploaded or externally sourced BPMN XML.
- We list every deployment path, including REST, API and pipeline routes, that must be covered by the controls.
- We agree in writing which parser settings, deployment permissions and test cases are in scope before work starts.
How we build
- We enable and verify the enableSafeBpmnXml setting in your configuration and confirm the parser behavior on your exact version.
- We test representative malicious and malformed XML samples against a non-production engine and record the results.
- We review who holds deployment privileges and align them with your change approval process and identity provider.
How we hand over
- You receive the final configuration, the deployment permission model and the test scripts used to verify parsing behavior.
- We document the platform requirements and version constraints that must hold after future Flowable upgrades.
- Documentation is written for your engineers and security team, so they can repeat the checks without us.
How we support
- Ongoing support, upgrades and continuous testing are available as retainers, separate from the initial fixed-scope work.
- Support can cover re-running the parser tests after Flowable upgrades or dependency changes in your stack.
- Ask any provider to confirm response terms, service levels and who performs changes in writing before you sign.

