Jahia 8.1 - Security update

December 21, 2021

Jahia 8.1 is a feature release focusing on improving the security of the platform. Many libraries used by Jahia have been updated to benefit from their latest security fixes, and we have also improved the security filter so it can be accurately configured.

While we are confident the impact on your modules should be very limited, here is a step-by-step procedure to prepare and validate your upgrade. 

Step 1. Identifying the modules to update to reflect new dependencies upgrades

The following libraries have been updated and require you to update and recompile your modules if you are relying on them:

  • GraphQL v13
  • Guava 30
  • Hibernate 5.5
  • Hibernate Validator 6.2.0 and validation-api
  • HttpClient 5

Follow one of the options below to identify which of your modules are relying on these libraries, thus needing to be updated.

Option 1: By analyzing each module before the upgrade

Before upgrading, you can verify for each of your modules their import packages, and see if any is concerned by our library upgrades:

  • Install bnd tools (command line)
  • Execute one of the following commands:
    • bnd print -i <jar file>
    • java -jar biz.aQute.bnd-{VERSION}.jar print -i <jar file>
  • Check if any import is part of the list of the updated libraries:
    • httpclient3: org.apache.commons.httpclient.*
    • guava: com.google.commons.*
    • graphql: graphql.*
    • hibernate validator: org.hibernate.validator.*
    • bean validation: javax.validation.*
    • hibernate: org.hibernate.*

Option 2: By using a karaf command: headers

This method requires you to first deploy your modules on the target Jahia version: 8.1.0 in our case. Then, you can:

  • Deploy your modules on a target Jahia version: 8.1.0
  • Run the following command in the karaf OSGi console:
    headers <module name or bundle id>
  • Check for any red entry in the Import-Package section
The diag command can also give some information about the reasons why the module cannot be started.

Step 2. Updating the modules you identified

Once you have listed the modules you need to update (in step 1a.), you can apply the required changes accordingly:

GraphQL dependencies have been updated to the following versions:

  • Graphql-java v13
  • Graphql-java-servlet v9.1
  • Graphql-java-annotations v7.2.1

with graphql-dxm-provider upgraded to 2.7.0 for the dependency upgrades.

Semantic versioning requires the import-package directive to be regenerated, but no code change should be expected in most of the cases.

Any code references to graphql.servlet.GraphQLContext will need to be refactored. When trying to get a reference to servlet request/response from the GraphQL environment context, you can use (assuming you have a graphql-dxm-provider 2.7.0 dependency):

  • org.jahia.modules.graphql.provider.dxm.util.ContextUtil.getHttpServletRequest(environment.getContext())
    or
  • org.jahia.modules.graphql.provider.dxm.util.ContextUtil.getHttpServletResponse(environment.getContext())

The version of guava bundled with jahia is now 30.1.1-jre . Modules depending on the provided guava will have to be recompiled with this new version. Semantic versioning requires the import-package directive to be regenerated, but no code change should be expected. 

Jahia now uses Hibernate 5.5.3  Modules depending on the provided hibernate library will have to be recompiled with this new version. Semantic versioning requires the import-package directive to be regenerated, but no code change should be expected in most of the cases.

Hibernate Validator has been upgraded to 6.2.0 and validation-api-1.1.0.Final.jar has been replaced by jakarta.validation-api-2.0.2.jar. Modules depending on the provided hibernate validator and/or the bean validation API will have to be recompiled with this new version. Semantic versioning requires the import-package directive to be regenerated, but no code change should be expected in most of the cases.

The impact is that security vulnerable operations are dropped or disabled with this new version:

  • @SafeHtml constraint dropped
  • Expression Language disabled for custom violations by default
  • Expression Language Bean methods execution disabled for constraints by default

HttpClient 3 has been replaced by HttpClient 5 in Jahia. Please note that HttpClient 4 is still available for use.

                If a module is using and importing HttpClient 3 from the core ( org.apache.commons.httpclient.* ), it will no longer run. The code has to be updated to work with HttpClient 5. See the Http Components Client documentation.

As a temporary solution, it is still possible to embed HttpClient 3 in the module itself but we strongly encourage you to have a plan to migrate to HttpClient 5 in the near future. 

Transitive dependencies

It is possible that some of your modules are using HttpClient as a transitive dependency. If it is the case and that you explicitly excluded it in the pom.xml file (see example), you need to either remove the exclusion, so the module will provide its own version of the library, or you need to update your module to use a newer version of the library that needs this dependency..

Choose one of the following procedures to regenerate the import-package directives after recompilation.

Preferred way: update the parent version to 8.1.0.0

The easiest and preferred way to ensure that your modules are built using the updated versions of the previous libraries is to update the parent version to 8.1.0.0 in the pom.xml file:

    <parent>
        <artifactId>jahia-modules</artifactId>
        <groupId>org.jahia.modules</groupId>
        <version>8.1.0.0</version>
    </parent>

When updating the parent version to 8.1.0.0, it is not necessary to explicitly specify the import packages.

If you are using the Jahia 8.1.0.0 alpha version, you need to use 8.1.0.0-SNAPSHOT as the parent version. In such a case, you will have to wait for the official release to be able to use 8.1.0.0 and release your modules.

 Alternative: specify an import package in the pom.xml

If your modules need to remain compatible with Jahia 8.0, you can add an import-package statement in their pom. Here is an example for graphql-annotations:

<properties>
    <import-package>
        graphql.annotations.annotationTypes;version="[6.1,9)"
    </import-package>
</properties>

Please note that when using this method, you need to ensure that there are no breaking changes, or changes that will affect your module, between the versions included in the specified range.

Temporary solution: package the old version of the library in your module

You can also decide on packaging the old version of the libraries you use in your modules, to prevent any incompatibility with the versions provided by Jahia. However, by doing so, you will not benefit from future updates.

Step 3. Other library upgrades that may require your attention

We have not identified breaking changes affecting Jahia in the following new libraries but depending on your usage we advise you to consult the release notes and test your modules before migrating.

Jahia now uses the Groovy 3 script engine.
We have not identified breaking changes affecting Jahia, however if you are relying on Groovy scripts, you may be impacted by breaking changes. In such case we advise you to consult the Groovy 3 release notes, and to execute your scripts in a pre-production environment to validate their compatibility with Groovy 3.0.

This does not apply to Jahia Cloud customers

After upgrading to Jahia 8.1, a new configuration file log4j2.xml is added for log4j2 to the folder /WEB-INF/etc/config/. Ensure that custom logging-entries are migrated to the new file, and that the old one gets properly removed.

Plexus-utils has been updated from 3.0.22 to 3.1.0. There is a breaking change in org.codehaus.plexus.util.PropertyUtils.loadProperties as it no longer catches all exceptions inside, but throws them out. For instance if the properties file to be loaded does not exist, an exception will be thrown while it was previously ignored.

We have upgraded Spring Webflow from 2.4.1 to 2.4.8.
If you are using Spring Webflow in your modules, you will need to manually test them in order to identify the potential changes you would need to do in your code.

Am I using Spring Webflow?

You can use the following two methods to know if you are using Spring Webflow in your modules.

  • Using the Jahia Tools
    Using the JSP pre-compilation servlet in the Jahia tools, you can easily find the components relying on Spring Webflow. Go to the JSP pre-compilation servlet in the Jahia tools (/modules/tools/precompileServlet ). All the JSP are listed at the bottom of the page. In the page (alternatively, you can run a compilation of the JSP and retrieve the list of JSP in catalina.out), search for .flow. You will then be able to identify which node types are using Webflow. For instance, you will find lines like:
    modules/siteSettings/jnt_siteSettingsManageUsers/html/siteSettingsManageUsers.flow/createUser.jsp
    
    Which means that jnt:siteSettingsManageUsers, of the “siteSettings” module is using Webflow
  • Searching your codebase
    Alternatively, you can search in your codebase (e.g. in your Github organization) for the following declaration in flow.xml files:
    <flow xmlns="http://www.springframework.org/schema/webflow"
    
    You should then find a list of all the modules using Webflow.

I am using Webflow, do I need to update my code?

If you specified bindings for every view in your flow.xml file (https://docs.spring.io/spring-webflow/docs/current/reference/htmlsingle/index.html#view-binder) then you do not have to update your code.

If you have not specified bindings, unfortunately, there is no other way to know if you need to update your code than testing every form. To do so, we advise you to deploy the webflow filter module on your preproduction environment, and then ensure that your forms are correctly working. If it’s not the case, then you’ll need to update your code.

How should I update my code?

If you need to update the code of your Webflow forms: We recommend to specify bindings for every view in your flow xml file : https://docs.spring.io/spring-webflow/docs/current/reference/htmlsingle/index.html#view-binder
Otherwise, if you use default mapping (so, not specifying any binder element), webflow will check the validity of expression in the parameter names before interpreting them. It will verify that the expression is correctly defining a readable property on the targeted bean, and not doing any dangerous calls. You should ensure that every parameter in your forms has a valid getter. Note that having a setter only is not enough for webflow to validate the parameter.
 

Step 4. New version of the security filter

The Jahia API security config and filter module has been improved to protect APIs in a more safe and configurable way.

Consult the Academy documentation and Github readme file to learn more about the configuration of the security filter.

  • The module comes with a legacy mode, which is unchanged from previous versions. This mode is useful, as it will help you sequence your upgrade operation, as you can focus on upgrading Jahia to 8.1.0 before adjusting the security filter configuration.
  • To simplify the configuration, you can also enable some additional logging, which will compare for each API call the behavior (allowed/denied) between the legacy and the new configuration.

In other words, when upgrading to Jahia 8.1, we suggest to:

  • Enable the legacy mode
  • Enable the migration reporting logs

This way, your system will work as before while logging the difference you will have if you were to switch to the new configuration. So you can adjust your configuration along the way, until you do not see calls that would be denied when they should not. This is a better approach than a try and fail approach.

Step 5. Augmented Search: New version of our Elasticsearch connector

You are only concerned by this section if you are currently relying on Elasticsearch Connector 7.

 To help with consistency and facilitate future upgrades we decided to retire Elasticsearch Connector 7 in favor of Elasticsearch Connector (without the ‘7’). New versions of Elasticsearch Connector give you access to more recent versions of the Elasticsearch client (Elasticsearch Connector 3.0.0 ships with Elasticsearch client v7.13.2).

Upgrading your modules to use Elasticsearch Connector should be straight forward since the latest version of Elasticsearch Connector 7 (v7.4.5) and the recent versions of Elasticsearch Connector (v.3.0.0) have an almost identical codebase. 

How to upgrade to Elasticsearch connector?

  • In your modules relying on elasticsearch-connector-7:
    • Change the dependency in the pom.xml
    • Rename packages from org.jahia.modules.elasticsearchconnector7 to org.jahia.modules.elasticsearchconnector
    • Change database type from ELASTICSEARCH7 to ELASTICSEARCH, when filtering services, for example:
      Collection<servicereference<elasticresthighlevelclient>&gt; serviceReferences = 
           bundleContext.getServiceReferences(ElasticRestHighLevelClient.class,
                 String.format("(&(databaseType=ELASTICSEARCH)(databaseId=%s))", settings.getEsConnectionId())); </servicereference<elasticresthighlevelclient>
      
  • Deploy the latest version of elasticsearch-connector and your modules in your environment
  • Remove the elasticsearch-connector-7 module(s)

Step 6. Apache2 front-end

You are only concerned by this section if you are currently relying on Apache2 as a front-end

WS protocol being introduced, in Jahia 8.1, you will need to add the following lines to the configuration of your VirtualHost: 

LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so

#...

ProxyPass /modules/graphqlws  ws://SERVER_NAME:PORT/modules/graphqlws
ProxyPassReverse /modules/graphqlws ws://SERVER_NAME:PORT/modules/graphqlws