Safeguard
DevSecOps

jackson-core Maven: What It Is and Where the Risk Lives

jackson-core is the low-level streaming engine behind Jackson, added via Maven. Here is what the artifact does, why it is safer than jackson-databind, and how to keep the whole stack patched.

Marcus Chen
DevSecOps Engineer
5 min read

jackson-core is the low-level streaming and token-parsing engine that underpins the whole Jackson JSON ecosystem for Java, and you add it as a Maven dependency under the com.fasterxml.jackson.core group. It does the raw work of reading and writing JSON tokens. Crucially, it is not where Jackson's famous deserialization vulnerabilities live; those sit one layer up in jackson-databind.

Understanding that split is the single most useful thing for anyone assessing Jackson's security, because it tells you which artifact to watch closely.

The Maven coordinates

The Jackson project is split into layered artifacts, all under the same group id. In a pom.xml you reference jackson-core like this:

<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-core</artifactId>
  <version>2.18.2</version>
</dependency>

You will also see it searched as "jackson core maven" or "maven jackson-core." The three core artifacts you will encounter are:

  • jackson-core: the streaming parser and generator (low-level token I/O).
  • jackson-annotations: the annotation definitions used to configure binding.
  • jackson-databind: the high-level data binding that maps JSON to and from Java objects, and depends on the other two.

Most applications never depend on jackson-core directly. It arrives transitively because you added jackson-databind, or because a framework like Spring Boot pulled the whole stack in.

Why the layer matters for security

Here is the distinction that changes how you triage Jackson advisories. jackson-core parses tokens; it does not decide what Java classes to instantiate from those tokens. That decision, called deserialization, lives in jackson-databind. The historically severe Jackson vulnerabilities, the remote-code-execution class, all stem from data binding turning attacker-controlled JSON into arbitrary Java objects.

The dangerous pattern was polymorphic deserialization enabled globally. When an application called the default-typing APIs (enableDefaultTyping, later activateDefaultTyping), jackson-databind would honor a type hint embedded in the JSON and instantiate whatever class it named. Attackers chained this with "gadget" classes on the classpath to reach code execution. jackson-core, sitting below all of that, was never the vector.

So when a Jackson CVE lands, your first question is which artifact it affects. A jackson-databind advisory tied to polymorphic typing is a high-priority patch. A jackson-core advisory tends to be a parser-robustness issue, more often a denial-of-service style problem from malformed or deeply nested input than a code-execution one.

Keeping the version current the right way

Because the Jackson artifacts version together, the clean way to manage them is Jackson's BOM (bill of materials) rather than pinning each artifact by hand:

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>com.fasterxml.jackson</groupId>
      <artifactId>jackson-bom</artifactId>
      <version>2.18.2</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>

Importing the BOM means all your jackson artifacts move together to a consistent, tested set of versions when you bump one number. Mixing a new jackson-databind against an old jackson-core is a classic source of subtle runtime errors, and the BOM prevents it. Stay on a currently maintained 2.18.x line (or newer) and treat the whole family as one unit.

The transitive-version trap

The most common real-world Jackson problem is not a headline CVE at all. It is version skew. Your build pulls jackson-databind from three different frameworks, Maven's nearest-wins resolution picks one, and you end up running a version you never intended, sometimes an older, vulnerable one.

Two defenses:

  1. Run mvn dependency:tree and search for jackson to see every version in play and who brought it.
  2. Use the BOM plus dependencyManagement to force a single, current version across the whole graph.

Because these flaws arrive transitively, you cannot rely on reading your own pom.xml. An SCA tool such as Safeguard can flag a vulnerable jackson-databind that a framework dragged in four levels deep and tell you which direct dependency to bump. For the deserialization specifics, our jackson-databind security guide goes deeper on the gadget-chain class and safe configuration.

Safe usage checklist

For any service in the Jackson ecosystem:

  • Avoid enabling default typing globally. If you need polymorphic types, use @JsonTypeInfo with an explicit allow-list via a PolymorphicTypeValidator.
  • Keep the whole jackson family on a maintained version through the BOM.
  • Scan transitively and gate CI on high-severity jackson-databind advisories.
  • Do not deserialize untrusted JSON into broad base types you do not control.

Handled this way, jackson-core is one of the least worrying dependencies in a Java stack. The attention belongs on jackson-databind and on keeping every Jackson artifact moving together. Our software composition analysis product covers automating that across many services.

FAQ

What is the difference between jackson-core and jackson-databind?

jackson-core is the low-level streaming engine that reads and writes JSON tokens. jackson-databind is the high-level layer that maps JSON to and from Java objects. The severe deserialization vulnerabilities live in jackson-databind, not jackson-core.

Do I need to add jackson-core to my pom.xml directly?

Usually not. It arrives transitively when you depend on jackson-databind or a framework like Spring Boot. You reference it directly only in narrow cases where you use the streaming API without data binding.

How do I keep all my Jackson versions consistent?

Import the Jackson BOM in your dependencyManagement section and let it govern the versions of every jackson artifact. Bumping the BOM version moves the whole family together to a tested, consistent set, avoiding the version-skew that causes runtime errors.

Is jackson-core affected by the Jackson remote-code-execution issues?

No. Those stem from polymorphic deserialization in jackson-databind, which decides what Java classes to instantiate. jackson-core only parses tokens and does not perform that binding, so it was never the vector for those code-execution flaws.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.