Safeguard
Open Source Security

What is Maven Security

Maven security covers vulnerable dependencies, malicious plugins, and build-time risks in Java projects -- from Log4Shell to transitive dependency sprawl.

Priya Mehta
DevSecOps Engineer
Updated 7 min read

Maven security is the practice of protecting Java and JVM-based projects from vulnerabilities and malicious code introduced through Maven Central, pom.xml dependency declarations, and the Maven build lifecycle itself. It covers three overlapping risks: known-vulnerable libraries (like the 2021 Log4Shell flaw, CVE-2021-44228, CVSS 10.0), malicious or compromised packages published to Maven Central or private Nexus/Artifactory repositories, and build-time code execution triggered by plugins declared in pom.xml. Because a typical Maven project resolves dozens of transitive dependencies for every one it declares directly, a single vulnerable or malicious JAR buried four levels deep in the dependency tree can compromise an entire application without a developer ever importing it by name — a team running mvn dependency:tree on a Spring-based service will commonly see spring-security-core maven coordinates and spring-security-web maven coordinates pulled in transitively via spring-boot-starter-security, neither one declared directly, which is exactly the kind of buried dependency this post is about auditing. Maven's central role in enterprise Java — the language behind most banking, insurance, and government backend systems — makes it a high-value target and a persistent audit gap.

What Is Maven Security?

Maven security means controlling what code enters a Java build through three channels: declared dependencies in pom.xml, their transitive dependencies pulled from Maven Central or internal repositories, and the plugins that execute during mvn compile, test, or package. Unlike a simple "scan for CVEs" definition, Maven security also has to account for build-time execution: Maven plugins are not passive files, they are Java code that Maven invokes automatically during the build lifecycle, so a malicious plugin coordinate in a POM can run arbitrary code on a developer's laptop or CI runner before a single unit test executes. Programs like Sonatype's OSS Index and Central's malware-scanning pipeline (introduced in 2023 to flag components before they're indexed) exist specifically because vulnerability scanning alone misses this build-time attack surface. Effective Maven security programs therefore combine software composition analysis (SCA), plugin allowlisting, and SBOM generation rather than relying on a single dependency-vulnerability scanner.

How Do Malicious Maven Plugins Execute Code During a Build?

Malicious Maven plugins execute automatically because the Maven lifecycle runs plugin goals as a normal part of compile, test, package, and install phases, with no sandboxing. A plugin declared in the <build><plugins> section of pom.xml — or pulled in transitively by a parent POM — runs as trusted Java code the moment the relevant lifecycle phase fires, with the same filesystem and network access as the developer or CI service account running the build. This is structurally similar to npm's postinstall script risk, but less widely discussed because Maven's ecosystem has historically had fewer public incidents than npm's. Security teams that only scan resolved JARs for known CVEs after the build completes miss this window entirely: the malicious code has already run by the time a post-build scanner looks at the output. Restricting which plugin groupIds and versions a build is permitted to invoke, via a corporate parent POM or a repository manager's allowlist, closes this gap.

What Was Log4Shell and Why Does It Still Matter for Maven Projects?

Log4Shell was a critical remote code execution vulnerability in Apache Log4j 2, tracked as CVE-2021-44228, disclosed December 9, 2021, and scored CVSS 10.0 — the maximum severity. It affected every Log4j 2 release from 2.0-beta9 through 2.14.1, meaning any Maven project with log4j-core anywhere in its dependency tree, direct or transitive, was exploitable by sending a single crafted string that Log4j's JNDI lookup feature would resolve and execute. It still matters for Maven security specifically because the vulnerable library was rarely a direct dependency — most affected teams inherited it through two or three layers of transitive resolution (a logging framework pulled in by a web framework pulled in by an internal shared library), and standard "check my declared dependencies" reviews didn't catch it. Four years later, Log4Shell remains the canonical example cited in Maven security training because it proved that dependency depth, not just dependency count, determines real exposure.

How Do Transitive Dependencies Expand a Maven Project's Attack Surface?

Transitive dependencies expand attack surface because Maven automatically resolves and includes every dependency of every dependency, often pulling in 50-150 JARs for a project that declares 10-15 directly. Each of those inherited JARs carries its own version pin, its own maintainer, and its own vulnerability history, but Maven's nearest-wins conflict resolution can silently select an older, more vulnerable version of a shared library over the one a direct dependency requested. The Apache Struts 2 vulnerability CVE-2017-5638 — the flaw behind the 2017 Equifax breach that exposed the personal data of roughly 147 million people — is a case in point: organizations running Struts as a transitive dependency of an internal framework often didn't know they were affected until forensic dependency-tree analysis after the fact. The same pattern applies to security libraries themselves: spring-security-core and spring-security-web, both usually resolved transitively rather than declared directly, have carried their own CVEs (CVE-2018-1258, an authorization-bypass flaw, is the best-known example), so a Maven coordinate you never wrote by hand can still be the one that needs patching. Running mvn dependency:tree against production artifacts, not just top-level pom.xml files, is the minimum step needed to see what's actually shipping.

What Makes Maven Central Different from npm or PyPI for Supply Chain Risk?

Maven Central differs from npm and PyPI because it requires groupId ownership verification tied to a domain or source-control namespace before a component can be published, which makes classic dependency-confusion and namespace-squatting attacks harder to pull off than on npm. That verification, in place since Maven Central's early Sonatype OSSRH days and carried forward into the Central Publishing Portal that replaced OSSRH in 2024, is why Maven has seen far fewer of the mass-typosquat incidents that hit npm and PyPI repeatedly between 2021 and 2023. It does not, however, protect against abandoned-domain takeover: if an organization lets the domain behind its reverse-DNS groupId (e.g., com.example.utils) lapse, an attacker who re-registers that domain can, in principle, re-establish ownership and push malicious updates to a groupId thousands of projects already trust. Maven Central's stricter publishing gate reduces one risk category while leaving build-time plugin execution and domain-lifecycle risk largely untouched.

How Can Security Teams Detect Vulnerable or Malicious Maven Dependencies?

Security teams detect vulnerable or malicious Maven dependencies by combining SCA scanning of the fully resolved dependency tree — not just declared dependencies — with SBOM generation and behavioral checks on plugin execution. A CycloneDX or SPDX SBOM produced from the actual build output captures every transitive JAR, its exact version, and its known CVEs, giving teams a queryable inventory instead of a point-in-time scan result that goes stale the next time mvn clean install re-resolves a version range. Because Maven allows version ranges and snapshot dependencies that can resolve differently between builds, teams that rely on a single scan at commit time can miss drift introduced weeks later by an upstream release. Pairing SBOM-based inventory with reachability analysis — confirming whether the vulnerable class or method in a flagged JAR is actually called by the application's code paths — is what separates a report of 400 CVEs from a prioritized list of the 12 that are actually exploitable.

How Safeguard Helps

Safeguard ingests or generates SBOMs directly from Maven build output, giving security teams a live, queryable inventory of every direct and transitive JAR instead of a point-in-time scan. Griffin AI, Safeguard's reasoning engine, then correlates that inventory against known CVEs and malicious-package intelligence and runs reachability analysis to confirm whether flagged code — a vulnerable Log4j JNDI lookup, a Struts deserialization gadget, a suspicious plugin goal — is actually invoked by the application, cutting through the noise of theoretical-only findings. For confirmed, exploitable issues, Safeguard opens auto-fix pull requests that bump the affected dependency to a patched version already validated against the project's build, so engineering teams merge a fix instead of triaging a CVE list by hand. That combination — SBOM depth, reachability-based prioritization, and PRs that close the loop — is built for exactly the kind of deep, transitive Maven dependency chains that let issues like Log4Shell hide for years before discovery.

Never miss an update

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