Protecting your system and data

November 14, 2023

This topic provides a brief overview of security considerations, ways for reducing risks and protecting your system and data. This topic discusses user authentication and data, template and actions protection, and other miscellaneous security issues.

User authentication and data

This section describes how user data is protected and which security-related concerns can arise in regard to user authentication.

Password encryption

Passwords for Jahia users are stored in the JCR repository one way encrypted. The default hash algorithm for user passwords is: SHA-256 (with random 32 byte salt and 4096 iterations). For the root user and the Jahia Tools user we use even more stronger hash: PBKDF2 (Password-Based Key Derivation Function 2) with random 64 byte salt, 32 byte hash size and 8192 iterations.

The password hashing algorithm could be changed for all user and also separately for "powerful" users (root and Jahia Tools user).

Add into <digital-factory-config>/jahia/jahia.custom.properties the following entry to adjust the password hash function, used by default:

jahia.passwordService.defaultDigester=pwdDigesterSHA256RandomSalt32x4096

This password digester is used for all users in Jahia. A restart of Jahia is required for changes to be effective. After the changes all further user password (for new users or when password is modified for existing users) will use that new hash algorithm. The existing passwords will still continue to work. A password hash is prefix with an ID of the hashing algorithm, which was used for its encryption.

Out of the box, the following hash algorithms are available in Jahia (in the order of their strength: from weak to very strong):

  • pwdDigesterSHA1RandomSalt32x4096
  • pwdDigesterSHA256RandomSalt32x4096
  • pwdDigesterSHA512RandomSalt32x4096
  • pwdDigesterPBKDF2RandomSalt64Key32x8192

Their IDs are self speaking and depict the hashing algorithm used.

Note, please, the stronger the algorithm is, the slower it is in hashing and verifying the passwords (on user login). The default one (pwdDigesterSHA1RandomSalt32x4096) provides a good balance between strength and speed.

You could also define and use a custom algorithm in the following way. The example below shows how to define a new password hasher that uses SHA-384 with random 32 byte salt and 4096 iterations.

Add the following Spring been definitions into <digital-factory-config>/jahia/applicationcontext-custom.xml file:

    <bean id="pwdDigesterSHA384RandomSalt32x4096" class="org.jahia.services.pwd.JasyptPasswordDigester">
        <constructor-arg index="0" value="s384"/>
        <constructor-arg index="1">
            <bean class="org.jahia.services.pwd.ProccessorAwarePooledStringDigester">
                <property name="algorithm" value="SHA-384"/>
                <property name="saltSizeBytes" value="32"/>
                <property name="iterations" value="4096"/>
                <property name="unicodeNormalizationIgnored" value="true"/>
            </bean>
        </constructor-arg>
    </bean>

Note, the bean ID and the constructor argument with index 0 should be unique identifiers of your hash algorithm for Jahia.

Add into <digital-factory-config>/jahia/jahia.custom.properties the following entry to adjust the password hash function and use your new one by default:

jahia.passwordService.defaultDigester=pwdDigesterSHA384RandomSalt32x4096

Restart your Jahia to make the changes effective.

Jahia Tool Manager password

The Jahia Tool Manager password is specified in the jahia.properties (PBKDF2 hash). Due to security considerations, this password can be only reset manually directly in the jahia.properties file. After you do that, you need to restart the server. Jahia Tools Area provides a utility JSP for encrypting clear text passwords: http://localhost:8080/tools/pwdEncrypt.jsp

Resetting root user password

Here is the procedure for resetting the password of the root user in DX 7.0:

  1. Create a plain text file named root.pwd in the data directory: <jahia-web-app-root>/WEB-INF/var (DX 7.0.0.0 and 7.0.0.1) or <jahia-install-dir>/digital-factory-data (for DX 7.0.0.2+) with a new root user password in clear text
  2. Restart the server
  3. You can now login with your new password as root

The following is the procedure for resetting the password of the root user in Jahia 6.6:

  1. Create a plain text file <jahia-web-app-root>/WEB-INF/etc/config/root.pwd with a new root user password in clear text
  2. Restart the server
  3. You can now login with your new password as root

Locking a user account

User account can be locked in Jahia 6.6 either using a User Management UI in Jahia Administration or using the Content Manager and setting the j:accountLocked property on the corresponding user node to true.

Sensitive user data

Non-public user profile data (user node properties) are not exposed for an unauthorized access.

Enabling SSL for logged in users

There is an option for "forcing" a switch to an SSL (HTTPS protocol) for a user session, from login to logout. This allows sites with higher security concerns to force secured connections for logged in users.

In order to enable it, please:

  1. Rename the file <jahia-web-app-root>/WEB-INF/etc/config/urlrewrite-ssl.xml.disable into urlrewrite-ssl.xml
  2. Go into Jahia Administration UI and flush output HTML caches
  3. Restart you server
  4. Now the login forms will contain a URL, leading to HTTPS and logout links will do a redirect back to HTTP.

The behavior could be adjusted by changing the URL rewrite rules in the urlrewrite-ssl.xml file.

Template and action protection

This section shows how to configure modules, templates and actions executed on user requests.

Module resources

In all Jahia modules, the following sensitive resources are protected from a direct access via web browser:

  • content definition files (*.cnd)
  • rule files (*.drl and *.dsl)
  • I18N resource bundles and template properties (*.properties)
  • scripting templates for mail notifications (/mails/*.*)
  • all resources under META-INF and WEB-INF folders
  • JSP templates (*.jsp)

So, when developing new modules take care of protecting sensitive files by, for example, placing them into the META-INF folder, which is protected by default.

META-INF is also the default folder for content and rule definition files.

XSS vulnerabilities

When developing custom JSP templates, especially those, requiring user interaction, the following rules of thumb can be used to reduce the risk of simple cross-site scripting XSS attacks, such as JavaScript code injection.

when using values of request parameters in templates markup, they need to be escaped, for example:

<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
...
<label for="username"><fmt:message key="label.username"/></label>
<input type="text" name="username" id="username" value="${fn:escapeXml(param.username)}" />

expect that values, coming from request parameters can be not well-formed or malicious. For example, if your template expects a JCR node path as a request parameter path, you should take care of checking if the path value really corresponds to a node, i.e.:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<%@ taglib prefix="jcr" uri="http://www.jahia.org/tags/jcr" %>
...
<jcr:node path="${param.path}" var="myNode"/>
<c:if test="${not empty myNode}">
   do something
</c:if>
<c:if test="${empty myNode}">
   unknown node path
</c:if>

Protecting render actions

Render actions, which are subclasses of org.jahia.bin.Action, can be protected in several ways from execution by a unauthorized user or in the wrong context.

Valid authenticated user

An execution of an action can require a valid authenticated user. This is the default level of protection for all render actions.

If your action should be "available" for non-authenticated users or a protection is done in a different manner, you can "relax" this constraint by specifying a false value for action's requireAuthenticatedUser property in its Spring bean definition file.

<bean class="org.jahia.modules.forum.actions.AddTopic" >
    <property name="name" value="addTopic"/>
    <property name="requireAuthenticatedUser" value="false"/>
</bean>

Required permissions

You can additionally specify a permission or multiple permissions a user, which is trying to execute this action, should have on the target content node.

For example:

<bean class="org.jahia.modules.blog.AddBlogEntryAction">
    <property name="requiredPermission" value="addBlogEntry"/>
</bean>

An action can require multiple permissions:

    <property name="requiredPermission" value="accessIntranetArea+addBlogEntry"/>

or any of the specified permissions:

    <property name="requiredPermission" value="addBlogEntry|moderateBlog"/>

Required workspace

An action execution can be limited to a particular workspace (default or live).

For example, the publish action is relevant for the default workspace only:

<bean class="org.jahia.modules.defaultmodule.actions.PublishAction">
    <property name="name" value="publish"/>
    <property name="publicationService" ref="jcrPublicationService"/>
    <property name="requiredPermission" value="publish"/>
    <property name="requiredWorkspace" value="default"/>
</bean>

Miscellaneous

This section describes other security issues.

Disabling directory listing for WebDAV servlet

In case a WebDAV client access is not used for managing resources in the JCR content repository, it is recommended that the directory listing is disabled for the WebDAV servlet, mapped to /repository.

For this the following key in digital-factory-config/jahia/jahia.properties (on versions, prior to 7.0.0.2 - WEB-INF/etc/config/jahia.properties) file needs to be set to true:

######################################################################
### WebDAV ###########################################################
######################################################################
# Disable the directory listing for /repository servlet.
# (WebDAV client access won't work in such a case)
repositoryDirectoryListingDisabled = true