Decorative site banner
Project icon

com.io7m.jxe

  • About
  • Releases
  • Manual
  • Sources
  • License
  • Issues
Maven Central Version Maven Snapshot Code Coverage

jxe


The jxe package implements a set of classes intended to both provide more secure defaults and to eliminate much of the boilerplate required to set up the standard JDK SAX parsers.

Features


  • Hardened SAX parsers: Prevent path traversal attacks, prevent entity expansion attacks, prevent network access!
  • Dispatching XSD schema resolvers; XML documents specify namespaces and the resolvers find their respective XSD schemas from a provided whitelist of locations. Reject non-validated XML!
  • Written in pure Java 17.
  • OSGi ready.
  • JPMS ready.
  • ISC license.
  • High-coverage automated test suite.

Motivation


The jxe package provides a sane API for setting up secure-by-default validating SAX parsers that dynamically locate schemas for incoming documents from a whitelisted set of locations without those documents knowing or caring where those schemas are actually located.

The package is capable of setting up extremely strict validating parsers. For example, many applications that receive XML have the following requirements on incoming data:

  • XML documents must be validated against one of a small set of schemas. Data that has not been validated must be rejected.
  • Documents must declare the namespace to which their data belongs, but must not be required to actually state the physical location of the schema. This is security sensitive: A document should not be able to tell a parser where to find a schema, because hostile documents could cause the parser to read a schema that trivially accepts all data. This would allow the document to essentially pass through without having to conform to the structure that an application expects. Documents that do not declare a namespace must be rejected.
  • The XML parser must not access the network except to explicitly permitted locations. This is security sensitive: A hostile document could declare a dependency on a schema that could cause the parser to contact attacker-controlled servers.
  • The XML parser must be robust in the face of attacks such as entity expansion attacks.
  • The XML parser must prevent path traversal attacks: Documents must not be able to cause files outside of a particular directory to be accessed.

Usage


The jxe package allows applications to enforce all of the above requirements via a very simple API:

// Incoming documents *must* be in the "urn:com.io7m.example:simple:1:0" namespace URI schema_namespace = URI.create("urn:com.io7m.example:simple:1:0"); // When a document states that it is in the "urn:com.io7m.example:simple:1:0" namespace, // the parser will open the schema at the URL returned by getResource("simple_1_0.xsd"). // All other namespaces will be rejected. JXESchemaDefinition schema = JXESchemaDefinition.of( schema_namespace, "simple_1_0.xsd", Example.class.getResource("simple_1_0.xsd"))); // Declare an immutable map of schemas. In this example, there is only the // one schema declared above. final JXESchemaResolutionMappings schemas = JXESchemaResolutionMappings.builder() .putMappings(schema_namespace, schema) .build(); // Create a provider of hardened SAX parsers. JXEHardenedSAXParsers parsers = new JXEHardenedSAXParsers(); // Specify a directory containing documents. The parser will not be allowed // to access paths that are ancestors of the given directory. This prevents // path traversal attacks such as trying to xinclude "../../../../etc/passwd". Path document_directory = ...; // Create an XInclude aware SAX parser. XMLReader reader = parsers.createXMLReader( document_directory, JXEXInclude.XINCLUDE_ENABLED, schemas); // Use the SAX parser. reader.setContentHandler(...); reader.parse(...);

Releases & Development Snapshots


Releases


You can subscribe to the atom feed to be notified of project releases.

The most recently released version of the package is 2.0.0.

2.0.0 Release (2024-09-06Z)

  • Require passing in a supplier of SAX parser factories instead of a single factory. (Backwards incompatible)
  • Simplify and improve schema handling in the case of multiple schemas.
  • Work correctly when running on Xerces-J. (Tickets: 21)

The compiled artifacts for the release (and all previous releases) are available on Maven Central.

Maven Modules


<dependency> <group>com.io7m.jxe</group> <artifactId>com.io7m.jxe.core</artifactId> <version>2.0.0</version> </dependency><dependency> <group>com.io7m.jxe</group> <artifactId>com.io7m.jxe.tests</artifactId> <version>2.0.0</version> </dependency><dependency> <group>com.io7m.jxe</group> <artifactId>com.io7m.jxe.tests.xerces</artifactId> <version>2.0.0</version> </dependency>

Previous Releases


The changelogs for the most recent previous releases are as follows:

1.1.0 Release (2024-09-01Z)

  • Update junit.version:5.10.2 → 5.10.3.
  • Update org.slf4j:slf4j-api:2.0.13 → 2.0.14.
  • Update org.slf4j:slf4j-api:2.0.14 → 2.0.15.
  • Update org.slf4j:slf4j-api:2.0.15 → 2.0.16.
  • Update junit.version:5.10.3 → 5.11.0.
  • Update ch.qos.logback:logback-classic:1.5.6 → 1.5.7.
  • Update nl.jqno.equalsverifier:equalsverifier:3.16.1 → 3.16.2.
  • Allow for passing in a SAX parser factory explicitly.

1.0.3 Release (2024-05-07Z)

  • Update org.immutables:value:2.10.0 → 2.10.1.
  • Update org.slf4j:slf4j-api:2.0.10 → 2.0.13.
  • Update nl.jqno.equalsverifier:equalsverifier:3.15.5 → 3.16.1.
  • Update ch.qos.logback:logback-classic:1.4.14 → 1.5.6.
  • Update junit.version:5.10.1 → 5.10.2.
  • Move to new organization.

1.0.2 Release (2023-08-09Z)

  • 1.0.1 had a broken deployment; no changes.

1.0.1 Release (2023-08-09Z)

  • Update test dependencies.
  • Use latest build plugins.

Development Snapshots


At the time of writing, the current unstable development version of the package is 2.0.1-SNAPSHOT.

Development snapshots may be available in the Central Portal Snapshots repository. Snapshots are published to this repository every time the project is built by the project's continuous integration system, but snapshots do expire after around ninety days and so may or may not be available depending on when a build of the package was last triggered.

Manual


This project does not have any user manuals or other documentation beyond what might be present on the page above.

Sources


This project uses Git to manage source code.

Repository: https://www.github.com/io7m-com/jxe

$ git clone --recursive https://www.github.com/io7m-com/jxe

Issues


This project uses GitHub Issues to track issues.

License


Copyright © 2023 Mark Raynsford <code@io7m.com> https://www.io7m.com Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

Last Updated 2025-08-09T14:57:47Z