Back to Blog
critical SEVERITY7 min read

How SSRF via Vulnerable Dependency Versions Happens in Node.js and How to Fix It

A permissive semver range in `package.json` allowed npm to install axios versions vulnerable to SSRF (CVE-2024-39338). By bumping the minimum version from `^1.6.0` to `^1.7.4`, all downstream consumers of this SDK are now protected from server-side request forgery attacks. This critical fix required changing just one line in the dependency manifest.

O
By Orbis AppSec
•Technically reviewed by Anupam Mediratta•Published September 3, 2026•Reviewed September 3, 2026

Answer Summary

CVE-2024-39338 is a Server-Side Request Forgery (SSRF) vulnerability in axios versions prior to 1.7.4, classified as CWE-918. In a Node.js `package.json`, specifying `"axios": "^1.6.0"` allows npm to resolve any version from 1.6.0 to <2.0.0, including vulnerable releases. The fix is to update the semver range to `"axios": "^1.7.4"`, ensuring only patched versions are installed.

Vulnerability at a Glance

cweCWE-918
fixUpdated minimum axios version from `^1.6.0` to `^1.7.4` in `package.json`
riskAttackers can exploit SSRF to access internal services, cloud metadata endpoints, or bypass firewalls
languageJavaScript / Node.js
root causePermissive caret semver range `^1.6.0` allowed installation of axios versions with known SSRF vulnerability (CVE-2024-39338)
vulnerabilityServer-Side Request Forgery (SSRF) via vulnerable dependency

Introduction

In a Node.js SDK's package.json at line 22, we discovered a critical dependency version issue that left every downstream consumer of the library exposed to Server-Side Request Forgery (SSRF). The culprit? A single caret character and a version number:

"axios": "^1.6.0"

This seemingly innocuous semver range told npm: "install any axios version from 1.6.0 up to, but not including, 2.0.0." The problem is that axios versions before 1.7.4 contain CVE-2024-39338, a well-documented SSRF vulnerability. Because this file belongs to a published library—not just an internal application—every project that depends on this SDK inherits the risk. A fresh npm install could silently resolve to axios 1.6.8 or 1.7.2, both of which are exploitable.

This matters for any developer who maintains Node.js packages or consumes third-party SDKs: your package.json version ranges are part of your attack surface.

The Vulnerability Explained

What is CVE-2024-39338?

CVE-2024-39338 is a Server-Side Request Forgery vulnerability in axios, one of the most widely-used HTTP client libraries in the JavaScript ecosystem (over 50 million weekly npm downloads). In vulnerable versions, an attacker can manipulate request URLs to cause the server to make unintended HTTP requests to internal resources.

How the Semver Range Creates the Problem

npm's caret (^) operator follows semantic versioning rules. When package.json specifies:

"dependencies": {
    "axios": "^1.6.0"
}

npm will resolve to the latest compatible version at install time. But here's the critical nuance: if a consumer's lockfile is stale, regenerated, or absent, npm could resolve to any version in the range >=1.6.0 <2.0.0. Versions 1.6.0 through 1.7.3 all contain the SSRF vulnerability.

A Concrete Attack Scenario

Imagine a backend service that uses this SDK to interact with an external API. The SDK internally uses axios to make HTTP requests. Here's how an attacker could exploit this:

  1. Reconnaissance: The attacker identifies that a target application uses this SDK (via exposed package-lock.json, error messages, or HTTP headers).
  2. Version check: They determine the installed axios version is 1.7.2 (within the ^1.6.0 range but below the patched 1.7.4).
  3. SSRF exploitation: The attacker crafts input that causes the SDK's axios instance to make a request to an internal endpoint—for example, http://169.254.169.254/latest/meta-data/ on AWS to retrieve instance metadata and IAM credentials.
  4. Escalation: With stolen cloud credentials, the attacker pivots to access S3 buckets, databases, or other cloud resources.

Because this is a library (note the microbundle dev dependency for bundling), the blast radius extends to every application that depends on it. The library authors may not even be aware that their consumers are running vulnerable axios versions.

Why This Is Critical

  • Supply chain amplification: A single vulnerable dependency in a published library propagates to all consumers.
  • Silent vulnerability: Developers installing the SDK have no indication they're getting a vulnerable axios version.
  • Cloud metadata exposure: SSRF is particularly dangerous in cloud environments where metadata endpoints are accessible from the server.

The Fix

The fix is surgical: update the minimum acceptable axios version from 1.6.0 to 1.7.4 in package.json at line 23.

Before (Vulnerable)

"dependencies": {
    "axios": "^1.6.0"
}

This allows npm to install any axios version from 1.6.0 to <2.0.0, including versions vulnerable to CVE-2024-39338.

After (Fixed)

"dependencies": {
    "axios": "^1.7.4"
}

This ensures npm will only resolve to axios 1.7.4 or later (up to <2.0.0), all of which contain the SSRF patch.

Why This Specific Change Works

  1. Floor elevation: By raising the minimum from 1.6.0 to 1.7.4, every version in the new range (>=1.7.4 <2.0.0) has the CVE-2024-39338 fix applied.
  2. Backward compatibility preserved: The caret operator still allows minor and patch updates, so consumers benefit from future bug fixes without manual intervention.
  3. No source code changes required: Because this is a dependency version constraint—not a code change—there is zero risk of behavioral regression. The SDK's source files remain untouched.
  4. Downstream propagation: When library consumers run npm update or regenerate their lockfiles, they'll automatically get a safe axios version.

Important Caveat

Existing consumers with a package-lock.json that already resolved to an older axios version will need to run npm update axios or delete their lockfile and reinstall. The fix in package.json ensures that new installations and lockfile regenerations will always get a patched version.

Key Takeaways

  • A permissive semver range like ^1.6.0 is an implicit trust statement that every version from 1.6.0 to <2.0.0 is safe—verify this assumption regularly against CVE databases.
  • Library maintainers bear responsibility for their consumers' security: this SDK's package.json directly controlled which axios versions downstream applications could install.
  • CVE-2024-39338 in axios <1.7.4 enables SSRF, which is especially dangerous in cloud environments where instance metadata endpoints (169.254.169.254) can leak IAM credentials.
  • The fix was a one-character, two-digit change (^1.6.0 → ^1.7.4)—proof that critical security improvements don't always require complex code refactoring.
  • npm audit alone isn't enough for libraries: audit checks your resolved lockfile, but library consumers resolve versions independently. The version range in package.json is the only control library authors have.

How Orbis AppSec Detected This

  • Source: The package.json dependency declaration at line 23, where the axios version range ^1.6.0 allows resolution to versions containing CVE-2024-39338.
  • Sink: Any axios HTTP request call within the SDK or its consumers, where SSRF payloads could be processed by a vulnerable axios version (versions <1.7.4).
  • Missing control: No minimum version floor was set above the patched axios release (1.7.4). The semver range permitted installation of 18 months' worth of vulnerable axios releases.
  • CWE: CWE-918 — Server-Side Request Forgery (SSRF)
  • Fix: Updated the axios dependency range from ^1.6.0 to ^1.7.4 in package.json, ensuring only versions with the CVE-2024-39338 patch can be installed.

Orbis AppSec automatically detected this vulnerability and opened a pull request with the fix. Try Orbis AppSec on your repositories to find and fix issues like this automatically.

Conclusion

This vulnerability is a textbook example of how supply chain security failures cascade. A single permissive version range in a library's package.json silently exposed every downstream consumer to a well-known SSRF vulnerability (CVE-2024-39338). The fix—bumping "axios": "^1.6.0" to "axios": "^1.7.4"—is minimal in size but critical in impact.

For library maintainers: treat your package.json version ranges as security boundaries, not just compatibility hints. For application developers: audit your transitive dependencies, not just your direct ones. And for everyone: automate dependency scanning so that known CVEs never silently enter your production builds.

Prevention and further reading

View the Security Fix

Check out the pull request that fixed this vulnerability

View PR #84

Related Articles

critical

ffmpeg.Probe() Protocol Abuse in the GetSnapshot Thumbnailer

The local storage driver's thumbnail helpers — `GetSnapshot()` and `resizeImageToBufferWithFFmpegGo()` — handed user-controlled paths to `ffmpeg.Input()` and `ffmpeg.Probe()` with no restriction on which FFmpeg protocols those processes could open. A file that passed the existing `sanitizeFilePath` check (absolute, cleaned, regular file) could still be an HLS playlist or concat script pointing at `http://`, `subfile:` or `file:` targets, turning thumbnail generation into SSRF and arbitrary file

high

axios 1.18.1 CVE-2026-101898: HTTP/2 Ignores proxy and lookup

A dependency upgrade moved `axios` from 1.18.1 to 1.20.0 to pick up the fix for CVE-2026-101898, in which proxy and DNS resolution settings supplied through axios request configuration were not applied on the HTTP/2 request path. Applications that rely on `config.proxy`, `HTTP_PROXY`/`NO_PROXY` environment variables, or a custom `lookup` function as an SSRF or egress control could have those controls silently skipped for HTTP/2 requests.

critical

Cloudflare Worker Reverse Proxy SSRF via String Concatenation

A Cloudflare Worker reverse proxy built its upstream request URL by string-concatenating an environment variable with the incoming request's pathname and search string, letting a crafted path or query redirect requests to attacker-chosen hosts. The fix replaces concatenation with the `URL` object's `pathname` and `search` setters, which normalize input against the configured origin instead of blindly appending it.

high

fast-uri 3.1.2 IDN Host Bypass: CVE-2026-13676 Upgrade

A dependency tree in this repository resolved `fast-uri` 3.1.2, a version affected by CVE-2026-13676, in which improper Unicode hostname canonicalization lets a crafted URI parse to one host while the HTTP client connects to another. Because `fast-uri` is what `ajv` uses to parse and resolve URIs for `format: "uri"` validation and `$ref` resolution, any host allowlist built on its parsed output could be bypassed. The fix upgrades the resolved copy to `fast-uri` 4.1.4 and pins it with an npm `ove

high

boardcards.js parseArgs() SSRF: --board Flag Reaches Metadata IPs

The `parseArgs()` function in boardcards.js accepted a user-controlled `--board` command-line argument and passed it directly to fetch() calls without validating the URL scheme or hostname. An attacker could supply `http://169.254.169.254/latest/meta-data/` or other internal addresses to extract cloud credentials or scan internal networks.

high

fetch() with Automatic Redirects Leaks HTTPS Trust to api.tomys.top

The `withProxy()` fetch wrapper allowed automatic HTTP redirects from `api.tomys.top`, trusting the external API's domain integrity without validating final destinations. A compromised or malicious redirect response could send users to attacker-controlled phishing sites while maintaining HTTPS protocol and hostname checks that falsely appear secure.