Custom Code & Security
The process engine offers numerous extension points for customization of process behavior by using Java Code, Expression Language, Scripts and Templates. While these extension points allow for great flexibility in process implementation, they open up the possibility to perform malicious actions when in the wrong hands. It is therefore advisable to restrict access to API that allows custom code submission to trusted parties only. The following concepts exist that allow submitting custom code (via Java or REST API):
- Deployment: Most of the custom logic is submitted with the deployment of a process, case, or decision model. For example, an execution listener invocation is defined in the BPMN 2.0 XML.
- Queries: Queries offer the ability to include expressions for certain parameters (currently task queries only). This enables users to define reusable queries that can be repeatedly executed and dynamically adapted to changing circumstances. For example, a task query
taskService.createTaskQuery().dueBeforeExpression(${now()}).list();uses an expression to always return the tasks currently due. Camunda Tasklist makes use of this feature in the form of task filters.
Only trusted users should be authorized to interact with these endpoints. How access can be restricted is outlined in the next sections.
CIB seven in a Trusted Environment
When CIB seven is deployed in an environment where only trusted parties can access the system (for example due to firewall policies), no untrusted party can access the APIs for submitting custom code and the following suggestions need not be adhered to.
Deployments
Access to performing deployments can be restricted by using the authorization infrastructure and activating authentication checks for any endpoint a potentially untrusted party may access. The crucial permission for making deployments is Deployment/Create. Untrusted users should not be granted this permission.
Queries
Query access cannot be generally restricted with authorizations. Instead, a query’s result is reduced to entities a user is authorized to access. Thus, authorization permissions cannot be used to guard expression evaluation in queries.
The process engine configuration offers two flags to toggle expression evaluation in adhoc and stored queries. Adhoc queries are directly submitted queries. For example, taskService.createTaskQuery().list(); creates and executes an adhoc query. In contrast, a stored query is persisted along with a filter and executed when the filter is executed. Expressions in adhoc queries can be disabled by setting the configuration property enableExpressionsInAdhocQueries to false. Accordingly, the property enableExpressionsInStoredQueries disables expressions in stored queries. If an expression is used although expression evaluation is disabled, the process engine raises an exception before evaluating any expression, thereby preventing malicious code from being executed.
The following configuration combinations exist:
enableExpressionsInAdhocQueries=true,enableExpressionsInStoredQueries=true: Expression evaluation is enabled for any query. Use this setting if all users are trusted.enableExpressionsInAdhocQueries=false,enableExpressionsInStoredQueries=true: Default Setting. Adhoc queries may not use expressions, however filters with expressions can be defined and executed. Access to filter creation can be restricted by the granting the authorization permissionFilter/Create. Use this setting if all users authorized to create filters are trusted.enableExpressionsInAdhocQueries=false,enableExpressionsInStoredQueries=false: Expressions are disabled for all queries. Use this setting if none of the above settings can be applied.
Task Filter Expression Whitelist
As of 2.0.14, 2.1.10 and 2.2.4, JUEL expressions in task filter criteria and ad-hoc task queries (e.g. assigneeExpression) are restricted to a whitelist by default.
This closes the expression injection issue from Camunda Security Notice 157 for stored filters, ad-hoc task queries and or() branches.
Allowed by default (n = any non-negative number):
${currentUser()},${currentUserGroups()},${now()}${dateTime()},${dateTime().withMillis(n)},${dateTime().withTimeAtStartOfDay()}${dateTime().withTimeAtStartOfDay().plusDays(n).minusSeconds(n)}${dateTime().plusDays(n)},${dateTime().plusDays(n).withTimeAtStartOfDay()},${dateTime().plusWeeks(n)}- plain literal values
All other expressions, e.g. ${dateTime().minusMonths(2)}, are rejected with HTTP 400. In the Tasklist, such a filter shows an error instead of the task list.
Finding Affected Filters
Before updating, find stored filters that use expressions:
SELECT ID_, NAME_, OWNER_, QUERY_ FROM ACT_RU_FILTER WHERE QUERY_ LIKE '%${%' OR QUERY_ LIKE '%#{%';
Also check custom TaskQuery code for *Expression values.
Allowing More Expressions
Set allowedFilterExpressions to a semicolon-separated list. It replaces the defaults, so include the defaults you still need.
Numbers in brackets act as wildcards: ${dateTime().minusMonths()} also allows minusMonths(2).
- CIB seven Run / Spring Boot:
camunda.bpm.generic-properties.properties.allowedFilterExpressions - Tomcat (
bpm-platform.xml) resolves${…}as a placeholder; WildFly (standalone.xml) needs$${…}.
Switches
| Property | Default | Effect |
|---|---|---|
enableFilterExpressionWhitelist |
true (since 2.0.14 / 2.1.10 / 2.2.4) |
Whitelist on. false restores the old behavior (not recommended). |
enableExpressionsInStoredQueries |
true |
false disables expressions in stored filters completely. |
enableExpressionsInAdhocQueries |
false |
Expressions in ad-hoc task queries stay off; if enabled, the whitelist applies. |