Jahia 8.1.9.6
Jahia 8.1.9.6 is a patch release centered around security. It tightens the permissions required by a number of operations and restricts several request-handling paths, so it carries more breaking changes than a typical patch. Most deployments should be unaffected, but custom code is more likely to be caught than usual, so review each entry below.
You can find more details about the discovered vulnerabilities in the Security section of Jahia Academy.
Upgrading from a version earlier than 8.1.9.0? Make sure to review Jahia 8.1.9.0 release notes as well as all intermediary patch releases.
Read before you upgrade
Special upgrade instructions
Upgrading from a version older than 8.1.9.3
Jahia 8.1.9.3 introduces a permission change, which is applied during the upgrade from versions older than 8.1.9.3 and part of that work re-indexes content, including a pass over everything held under /sites.
While the migration runs, every write to the JCR is held up across the whole cluster, including logins that use the built-in remember-me option. Ordinary reads continue to be served.
We were made aware that in some situations, the migration can take longer than expected, especially on large sites. The duration depends on the size and complexity of your content repository. You are encouraged to plan accordingly and allocate sufficient time for the upgrade process.
If one of the migration scripts fails, it is renamed with a .failed suffix in the patches folder, the upgrade carries on and the script is never retried, which can leave the repository only partly hardened. Check for such a file after the upgrade, and contact support to have it applied.
Jahia 8.1.9.6 introduces improvements to this migration. If you are upgrading from a version of Jahia below 8.1.9.3, we encourage you to upgrade straight to 8.1.9.6 or above.
If you are already running Jahia 8.1.9.3+, the permission change was already performed in your environment, and you are not affected by this migration.
Commit: 665caba
Breaking changes
Breaking changes are documented on the page of the release that introduced them. If you are upgrading across more than one version, review the breaking changes of every release between the version you are currently running and the version you are upgrading to.
This release tightens a number of permission checks and request-handling rules.
Importing an archive that carries live content requires the Publish permission
Importing an archive that carries live content requires the Publish permission, named publish in a role definition, on the location the import writes under. The permission is read before any live content is applied, so a refused archive leaves the live workspace unchanged.
Am I impacted?
Only if a role that imports such an archive holds no Publish permission on the target location. An export carries live content only when it was taken with that option and its nodes are already published, so an editor round-tripping unpublished content is unaffected. The stock editor, translator and web-designer roles reach the import action and hold no Publish, so they are affected. Forms is affected in the same way: every form export carries live content, so re-importing an exported published form needs Publish on the site's Forms folder, which the stock Forms Manager role holds and the stock Forms Editor and Forms Reviewer roles do not. The root user is unaffected, and so are imports that carry no live content, module content deployment, provisioning scripts, the patches folder, the Karaf console and the initial repository seed, each of which imports with the server's own authority rather than a caller's.
What do I need to do?
Grant Publish on the target location, or run those imports as an editor-in-chief, a reviewer or an administrator. Check any custom role that imports such an archive in the same way.
Commit: 1ee15ce
Guest read access is granted on each site instead of on /sites
Guest read access is now granted on each site rather than on the /sites folder that holds them. Effective permissions are unchanged, apart from one case.
Am I impacted?
Only if you have an entry denying read on /sites itself, in the live workspace. Such an entry no longer has any effect, whichever the user or group you configured.
In addition:
- if you are already running 8.1.9.2 or later and had denied guest read on
/users/guest,/modulesor/mounts, the 8.1.9.2 migration removed that denial when you upgraded and this release does not restore it. - if you are upgrading from a version prior to 8.1.9.2,
/users/guest,/modulesor/mountsare untouched, the permissions on those three paths remain as they were previously.
In some very specific situations, an ACL that was previously ignored might become effective after the upgrade and log ERROR messages to the console. For instance, if you had granted read to the guest group, g:guest, on the repository root /, and a site is restricted with DENY u:guest.
What do I need to do?
Review any entry that denies read on /sites in the live workspace, since it no longer takes effect.
If the migration logs ERROR messages for a site that carries DENY u:guest, and since the system cannot not know what was your intended configuration, make sure to review the log message and update the permission action if required to match your desired configuration.
Commit: 665caba
Request URI decoding pinned to UTF-8
The charset used to decode the request URI before URL rewrite rules are matched is now pinned to UTF-8, instead of being taken from the request's own Content-Type. Previously the decoded form of a URI depended on the charset its caller happened to declare, so the same URL could be read differently from one request to the next.
Am I impacted?
Only if a request declares a non-UTF-8 charset in its Content-Type and its URI carries percent-encoded non-ASCII bytes. There is no change for a request that declares no charset (the vast majority, including all normal GET navigation), nor for any ASCII-only URI whatever the declared charset. A client that sends a UTF-8-encoded URI while declaring a legacy charset is fixed by this change. A client that percent-encodes the URI in the legacy charset it declares, and relies on a rewrite rule matching the decoded non-ASCII form, may find that rule stops matching.
What do I need to do?
Re-encode those URLs in UTF-8, which is what browsers send. Setting urlRewriteDecodeUsing = header,utf-8 restores the previous behaviour, and with it the dependency on the charset each caller declares.
Commit: dfc1626
Content-editing requests can no longer manage users, groups, roles, permissions or mounts
Content-editing requests are restricted so they can no longer create or modify users, groups, roles, permissions or mounts, nor the folders that hold them.
Am I impacted?
Only if you have custom code that edited any of those through a content request. Separately, setting a user's password now requires a prior authorization scoped to that same user node, so custom code that creates a user node itself and sets its password directly will be refused with JCRUserPasswordUpdateAuthorizationException.
What do I need to do?
Use the corresponding APIs instead. Create users through JahiaUserManagerService.createUser, which authorizes the initial password itself and works whatever session you pass, or call UserPasswordUpdateInterceptor.authorizePasswordUpdate for the target user first. Creating a user through the supported service, including as a site administrator, is unaffected. Note that it now returns null when it cannot create the user, where it used to fail with a ClassCastException. If you need to adjust which types, properties and mixins are covered, they are listed under jahia.render.action.restricted* in jahia.properties.
Commit: e6f46d2
Spring Web Flow restrictions
Two changes: a flow now runs only for the content view that declares it, and view-parameter names are bound as plain property paths, with any name that is not a plain binding path refused.
Am I impacted?
Only if you have a custom integration that drives a flow from outside a content view.
What do I need to do?
If such an integration stops working, set jahia.webflow.requireRenderedFlowOrigin = false in jahia.properties as a temporary compatibility fallback and plan to return to the default. If a custom flow view stops rendering, set jahia.webflow.useSpringBeanBinding = false.
Form tokens are issued only for forms rendered by the form taglib
The taglib carries a form's data on the fragment it renders, and the tag left in the markup is only a lookup handle.
Am I impacted?
Only if your own templates or custom modules write a jahia:token-form tag directly instead of using <template:tokenizedForm>. Such a tag has no form data behind it, so it no longer receives a form token and the form it belongs to will fail to submit.
What do I need to do?
Replace hand-written jahia:token-form markup with <template:tokenizedForm>, which carries the form data for you.
Commit: 1376e3e
Studio-only and hidden components with a Web Flow view are restricted
A component carrying jmix:studioOnly or jmix:hiddenType, and for which a module provides a Spring Web Flow view, is now displayed only from the template definitions of the module that provides it.
Am I impacted?
Only if such a component is placed elsewhere, for example directly in page content. It is then no longer displayed. This holds even when the page resolves an ordinary view for it, because the restriction follows the content type rather than the resolved view. A component carrying one of those mixins for which no module provides a Web Flow view is unaffected.
What do I need to do?
If a component you rely on stopped being displayed, contact the provider of the module that defines it.
Operations now requiring a permission
Two operations now require an explicit permission:
- Applying an import archive requires the Manage Web Projects permission.
- Importing users requires the Manage Users permission.
How to upgrade
Customers can always use the In-Place or Blue-Green upgrade procedure regardless of their current version. The rolling upgrade prerequisites below only apply to the rolling upgrade procedure.
Rolling upgrade to Jahia 8.1.9.6
Rolling upgrade to 8.1.9.6 from any version earlier than 8.1.9.0 is not supported.
Rolling upgrade from any 8.1.9.x version to 8.1.9.6 is supported, but requires the following modules to be upgraded on the cluster before starting the Jahia node upgrade:
- content-security-policy 2.6.0 (download)
- graphql-dxm-provider 2.24.0 (download)
- jcrestapi 3.4.1 (download)
- ldap 4.8.0 (download)
- macros 8.5.0 (download)
- personal-api-tokens 1.10.0 (download)
- rolesmanager 8.10.0 (download)
- security-filter-tools 2.6.1 (download)
- siteSettings 8.7.1 (download)
- tasks 8.3.0 (download)
- tools 4.8.0 (download)
- userDashboard 8.8.1 (download)
Note: Depending of the version of Jahia you are upgrading from, some modules might already be in the required version.
If you are upgrading from a version older than 8.1.9.3, read the special upgrade instructions above before planning a rolling upgrade: the migration that runs during that upgrade holds up every write across the cluster, and a rolling upgrade neither avoids that pause nor keeps the site available while it runs.
Failing to upgrade these modules beforehand WILL result in instability during the rolling upgrade window when nodes are running different Jahia versions. Downgrading IS NOT supported.
If you are using Jahia installer, you can download fixAppliers corresponding to your Jahia version here.
Components updated in Jahia 8.1.9.6
Modules
| Component | Jahia 8.1.9.4 | Jahia 8.1.9.6 |
|---|---|---|
| content-security-policy 📝 | 2.4.0 | 2.6.0 |
| graphql-dxm-provider 📝 | 2.22.0 | 2.24.0 |
| jcrestapi 📝 | 3.2.0 | 3.4.1 |
| rolesmanager 📝 | 8.9.0 | 8.10.0 |
| siteSettings 📝 | 8.7.0 | 8.7.1 |
| tools 📝 | 4.7.0 | 4.8.0 |
Only components whose version changed in Jahia 8.1.9.6 are listed above.
The full list of Jahia modules and their versions can be found in the Jahia 8.1.9.6 tag in GitHub.
Database drivers
No changes to database drivers in this version.
The full list of Database drivers and their versions can be found in the Jahia 8.1.9.6 tag in GitHub.
Libraries
| Component | Jahia 8.1.9.4 | Jahia 8.1.9.6 |
|---|---|---|
| Apache log4j2 📝 | 2.17.2 | 2.26.1 |
| Apache Tomcat 📝 | 9.0.118 | 9.0.121 |
Only components whose version changed in Jahia 8.1.9.6 are listed above.
The full list of embedded Jahia libraries can be found in the Jahia 8.1.9.6 tag in GitHub.
Changelog
Security
-
🛡️ Restricted imports of an archive that carries live content to holders of the Publish permission. (Commit: 1ee15ce)
The permission, named
publishin a role definition, is required on the location the import writes under, and it is read before any live content is applied, so a refused archive leaves the live workspace unchanged. An export carries live content only when it was taken with that option and its nodes are already published. -
🛡️ Changed guest read access so it is granted on each site rather than on the
/sitesfolder that holds them. (Commit: 665caba)Effective permissions are unchanged, apart from one case: an entry denying read on
/sitesitself, in the live workspace, no longer has any effect, whichever principal it names. The permission changes released in 8.1.9.2 are also far cheaper to apply. -
🛡️ Restricted user imports to holders of the Manage Users permission. (Commit: aa45f4e)
-
🛡️ Applying an import archive now requires the Manage Web Projects permission. (Commit: e7c46a2)
-
🛡️ The /cms/text-extract endpoint now requires an authenticated caller holding the systemToolsAccess permission, consistent with the other controllers in the same handler map. Callers who can use the text extraction tool today are unaffected. (Commit: 19bb162)
-
🛡️ Restricted content-editing requests so they can no longer create or modify users, groups, roles, permissions or mounts, nor the folders that hold them. Setting a user's password now requires a prior authorization scoped to that same user node. (Commit: e6f46d2)
-
🛡️ Restricted Spring Web Flow screens so a flow runs only for the content view that declares it. (Commit: 2a7b568)
A custom integration that drives a flow from outside a content view is affected. If such an integration stops working after the upgrade, set
jahia.webflow.requireRenderedFlowOrigin = falseinjahia.propertiesas a temporary compatibility fallback, then plan to return to the default. -
🛡️ Bind Spring Web Flow view-parameter names as plain property paths, and refuse a name that is not a plain binding path. Set
jahia.webflow.useSpringBeanBinding = falseinjahia.propertiesif a custom flow view stops rendering after the upgrade. (Commit: 4e004af) -
🛡️ A component that carries
jmix:studioOnlyorjmix:hiddenType, and for which a module provides a Spring Web Flow view, is now displayed only from the template definitions of the module that provides it. (Commits: 988b650, fd42342) -
🛡️ Request paths where a segment begins or ends with whitespace, literal or percent-encoded, are now rejected. (Commit: 1a23588)
Whitespace inside a segment, as in a file name, is unaffected, and repository content cannot match: a JCR name may not begin or end with a space. Disable with
security.malformedRequest.blockSegmentEdgeWhitespaceif a deployment relies on such paths. -
🛡️ Added a malformed request filter. (Commit: 021545b)
-
🛡️ Form tokens are now issued only for forms rendered by the form taglib. A discarded form tag is reported once per interval, and control characters and Unicode line separators are replaced in log entries before they are written. (Commit: 1376e3e)
-
🛡️ Hardened the automatic unpublish that follows a deletion in Live so it applies only to content the user may edit. (Commit: f0aac4c)
-
🛡️ Consistently escape the UI theme value in engine view markup. (Commit: 13aeba8)
-
🛡️ Fixed the text extraction and version history tool reports so repository paths and messages are displayed as text. (Commit: 7d54f1c)
-
🛡️ A log entry built from an exception now stays on the lines the log wrote: the message of the exception, and of each nested exception, is escaped the same way as a log message. (Commit: 7ab1c69)
-
🛡️ The charset used to decode the request URI before URL rewrite rules are matched is now pinned to UTF-8, instead of being taken from the request's own
Content-Type. NewurlRewriteDecodeUsingproperty. (Commit: dfc1626)
Core
-
🐛 A publication that deletes a node and adds a sibling in the same batch now publishes the sibling. (Commit: dfefffc)
Before, a node was taken for a descendant of a deleted node when its path only started with the deleted path, so a new sibling whose name starts with the name of the deleted node was dropped from the publication and no error was written. The check now requires a path separator, so only a real descendant of the deleted node is skipped.
-
🐛 A page created from a page model now copies that model only when it is a page model of the page's own site; any other
j:templateNamereference is ignored and logged instead of copied. Sub content of the model that the user creating the page cannot read is likewise skipped rather than copied. (Commit: e4be0de) -
🐛 Fixed the unbounded growth of the throttle state that Jahia uses to run a piece of code at most once per interval. An entry whose interval has elapsed is now removed. (Commit: 182b889)
Two behaviours change for a caller: a callback that throws now consumes its interval, where before it left no entry and ran again on the next call, and a key called again with a shorter interval keeps the deadline that the last allowed call set, so a lowered interval applies from the next allowed execution onward.
-
🐛 Render filters are now finalized whenever they were prepared, so the per-render resources they reserve are always released. (Commit: ac9b331)
Custom
RenderFilterimplementations should note thatfinalizeis now called for every prepared filter, in preparation order, regardless of the filter's conditions at that point.
Libraries
- 📦 Bump tomcat from 9.0.118 to 9.0.121. (Commit: 5aec3b4)
- 📦 Updated log4j from 2.17.2 to 2.26.1 for the log4j artifacts the webapp ships and builds against. Karaf's own logging backend on this line stays on pax-logging 1.11.13, which embeds log4j 2.17.1. (Commit: 6645624)
Legend (icons): ✨ Improvements & new features, 🐛 Bugs, 🛡️ Security fixes, 📚 Documentation, 📦 Packaging, 🛠 Change to Jahia build, ⚙️ Changes to CI, ♻️ chores