Nuxeo Core Developer Guide

Secure Coding

Updated: June 5, 2024

The following process and rules help to ensure that no security problem is introduced on code change. Moreover, the goal is to continuously improve the quality, including the security.


The coding workflow itself provides a Security Code Review post hoc:

  • Code is open-source and so it is reviewed by the community. Especially, Nuxeo source code is often used by security companies and university teams to run against their security analysis tools who then submit us the potential vulnerabilities they may find.
  • Security Hotfixes: there is no absolutely secured code but known vulnerabilities and weaknesses: when a new one is discovered, it is immediately fixed as an emergency, customers are warned about it, then the fix is made available for all users through a public Security Hotfix.
  • LTS/FT release cycle + code freeze durations: code lives for a long time in the Fast Track cycle (and for a short while in "code freeze" within Fast Track) so the Nuxeo and community developers should have enough spare time to properly review it and raise issues.

Automatic Code Review:

Since the security also depends on the underlying third-party libraries, they must be kept consistent and up-to-date:

  • All Nuxeo code shares the same “dependency management” to ensure that we use the same library versions everywhere.
  • Third-party libraries available updates are watched with and, reported by nuxeo-master-versions QA job.
  • Third-party release notes are regularly reviewed to point at security updates and apply them.
  • Nuxeo subscribes to its third-party libraries notifications (usually user-mailing-lists) and receive dedicated alerts

The current documentation provides a Security Code Review beforehand:

  • The developers are encouraged to use FindBugs.
  • The following best practices are not only recommended but required and the expected overall quality is high: you must strictly abide by those Coding Rules.

Java Code

No Arbitrary File Read / Write

All calls to new File must be audited to make sure that there is no possibility of pointing to a random or user-controlled file. Actually there is rarely a reason to use new File; if needed for temporary files then see the next section.

Temporary Files

Temporary files should be created using File.createTempFile or Files.createTempFile with the default temporary directory and a prefix that is not controlled by user input. 

ZIP Files

When unzipping a file hierarchy from a user-supplied ZIP file to a temporary filesystem location, the ZipEntry's name must not be trusted to contain valid characters as an attacker is able to rewrite it. In particular the name must be checked for path-traversal components like .. or /:

Sanitizing ZIP Files

public void extract(ZipInputStream in, ZipEntry entry, File base) {
    String name = entry.getName();
    if (name.contains("..") || name.contains("/") || name.contains("\\")) {
        log.error("SECURITY: ZIP entry contains invalid name: " + name);
    if (!entry.isDirectory()) {
        File file = new File(base, entry.getName());

No XML External Entity Processing

XML External Entity Processing (XXE) is a class of security issues due to invalid processing of external entities in user-supplied XML files, where the entities may access invalid external resources.

The recommendations for Java code detailed in the above page must be followed. In particular:

DocumentBuilder Protection

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;

DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance()
documentBuilderFactory.setFeature("", true);
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
Document document = documentBuilder.newDocument();

SAXParser Protection

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.XMLReader;

SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
saxParserFactory.setFeature("", true);
SAXParser saxParser = saxParserFactory.newSAXParser();
XMLReader xmlReader = saxParser.getXMLReader();

Note that, unrelated to security, the feature can also often be passed to improved the speed of the parsing.

The following is not mentioned in the above OWASP page but must also be followed:

XSLT Transformer Protection

import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.XMLConstants;

TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();

No SQL Injection

SQL must never be generated "by hand". Always use JDBC PreparedStatement where all user-controlled input is passed as statement parameters. Or, better, use an additional abstraction layer like Nuxeo's NXQL or Hibernate's HQL.

No Breaking of Layering

Nuxeo security relies on code using the proper layers. In Nuxeo, security happens at different levels, which must not be bypassed:

  • Authentication is done at the Servlet layer through a pluggable authentication system. Any custom servlet must be configured to use the same servlet filters as the standard Nuxeo servlets.
  • Authorization is done at the CoreSession layer through built-in checks of the security on the document for the currently authenticated user. This CoreSession layer must not be bypassed:
    • The lower-level Session must not be accessed, or all access must be aware that security checks have to be done at a higher layer.
    • The UnrestrictedSessionRunner or changing to a system user through CoreInstance.openCoreSession must be used only when there is no security risk on the document(s) being accessed.


The Cross Site Scripting page describes rules that must be followed when generating HTML to avoid XSS and CSRF security issues.