Cabeçalho penumbroso

Axios npm CVE, the real risk is your outbound trust boundary

When teams search for “axios npm cve,” they usually expect a neat answer: one bug, one patch, one upgrade, done. Axios does not behave that way in the real world. The package sits at a boundary where untrusted input turns into outbound behavior. That boundary includes URL resolution, header propagation, cookie-derived token handling, configuration merging, and in Node.js even special handling for non-HTTP schemes. It now also includes something no ordinary vulnerability patch can solve by itself: a March 2026 npm compromise in which two Axios releases were turned into malware installers. (GitHub)

That distinction matters because not every Axios alert describes the same kind of failure. Some records are about server-side request forgery. Some are about sending security-sensitive headers to the wrong host. Some are about denial of service in Node-specific code paths that never send a network packet at all. Some are about configuration objects crashing the process before any request is made. One recent alert was withdrawn because the vulnerable component was a transitive dependency that could be patched independently. Another NVD entry is explicitly marked as disputed. If you flatten all of that into “Axios has a CVE,” you lose the engineering detail that tells you what to fix, what to investigate, and what to ignore. (GitHub)

The right way to read the Axios security record is to stop thinking about package popularity first and start thinking about trust boundaries first. Axios is the layer where developers often assume that a path is only a path, a callback URL is only a string, a cookie-derived token is only sent where it belongs, a content-length limit applies to every kind of input, or a parsed JSON object is safe to pass through as request config. Most of the interesting Axios security problems come from those assumptions breaking under attacker-controlled input. (Axios)

Axios npm CVE is not one record, it is a map of different failure modes

The easiest way to see the pattern is to put the records side by side. Once you do that, the recurring theme is not “Axios is buggy” in the abstract. The theme is that Axios often mediates security-relevant choices about destination, headers, token propagation, parsing, and object merging. Different CVEs hit different parts of that surface. (GitHub)

RecordCategoriaVersões afetadasCore issueFixed version or status
CVE-2023-45857Token leakage>=1.0.0 <1.6.0, >=0.8.1 <0.28.0Axios could expose XSRF-TOKEN by sending X-XSRF-TOKEN to unintended hosts1.6.0, 0.28.0
CVE-2024-39338SSRF>=1.3.2 <=1.7.3Path-relative input could be processed as protocol-relative URL1.7.4
CVE-2024-57965Disputed origin check recordantes de 1.7.8NVD notes a same-origin parsing concern, but also marks the record disputeddisputed, patch trail points to 1.7.8
CVE-2025-27152SSRF and credential leakage<=1.7.9, <=0.29.0Absolute URL can override baseURL, leaking headers or reaching unexpected hosts1.8.2, 0.30.0
GHSA-rm8p-cx58-hcvxTransitive dependency alert[email protected]Briefly tied Axios to [email protected], then withdrawnwithdrawn
CVE-2025-58754Node-specific DoSantes de 0.30.2, before 1.12.0dados: URI handling decoded attacker-controlled payloads into memory0.30.2, 1.12.0
CVE-2026-25639Config merge DoSantes de 0.30.3, before 1.13.5mergeConfig crashed on objects containing own __proto__0.30.3, 1.13.5
March 2026 malicious releasesRegistry compromise1.14.1, 0.30.4Official npm package was used to deliver malware through a hidden dependencymalicious versions removed

Source basis for the table above comes from GitHub advisories, NVD entries, the withdrawn advisory notice, and the official Axios issue plus Microsoft’s incident write-up on the malicious npm releases. (GitHub)

One immediate takeaway is that “upgrade Axios” is not a sufficient security answer. For some records, upgrading is enough. For others, upgrading only removes one bad default while leaving a dangerous calling pattern intact. For the registry compromise, patching alone is the wrong mental model entirely, because affected systems may already have executed malicious install-time code and require incident response rather than ordinary dependency hygiene. (GitHub)

Axios lives where application trust becomes network trust

Axios’ own documentation makes the package’s role clear. The request config surface includes baseURL, allowAbsoluteUrls, withCredentials, xsrfCookieName, xsrfHeaderName, withXSRFToken, maxContentLength, maxBodyLength, redirect handling, proxy settings, and transport behavior. That is not just a convenience wrapper around HTTP; it is a control plane for how input becomes a request. When a package exposes that much policy-adjacent behavior, security issues tend to cluster where developers use convenience features as if they were security boundaries. (Axios)

OWASP’s SSRF guidance describes the kinds of business features that become dangerous when URL handling is sloppy: user-supplied image URLs, webhook callbacks, internal service requests, import or fetch features, and any flow where the application retrieves something on a user’s behalf. Those are exactly the kinds of places where Axios often shows up in production code. The package is not unusual for having these use cases. It is unusual for how often teams forget that they are handing a user influence over a destination, not just over a string. (Série OWASP Cheat Sheet)

The broader lesson is simple. A client library is part of your outbound trust boundary whenever it chooses where to connect, what headers to attach, what tokens to derive from cookies, how to follow redirects, or how to interpret non-HTTP inputs. That is the lens that makes the Axios security record coherent. Without that lens, the CVEs look unrelated. With it, the pattern is obvious. (Axios)

The Axios SSRF story is really one engineering problem with multiple CVEs

Most teams first notice Axios in security feeds because of SSRF. That is reasonable, but incomplete. The Axios SSRF story is best understood as a family of failures in destination control. One record involved path-relative input unexpectedly behaving like a protocol-relative target. The next involved absolute URLs overriding a configured baseURL. In both cases, the common mistake was trusting a convenience mechanism to enforce a security property it was never designed to guarantee. (GitHub)

CVE-2024-39338 and the protocol-relative trap

GitHub’s advisory for CVE-2024-39338 states that affected Axios versions from 1.3.2 through 1.7.3 were vulnerable to SSRF because path-relative URLs could be processed as protocol-relative URLs, with 1.7.4 carrying the fix. The original report describes a common pattern: a developer creates an Axios instance with a trusted baseURL, expects to append a user-specific path, and instead gives an attacker a way to steer the request somewhere else. (GitHub)

The important part is not the exact syntax of the bad input. The important part is the assumption that “I am passing a path segment” is fundamentally weaker than “I have already canonicalized a destination and proven it is allowed.” Once user influence reaches the stage where Axios is still deciding what the real destination is, you are already closer to SSRF than most code reviewers realize. (GitHub)

CVE-2025-27152 and the absolute URL override problem

CVE-2025-27152 made the problem even easier to understand. GitHub’s advisory says that even when baseURL is set, passing an absolute URL causes Axios to send the request to that absolute target, creating a path to SSRF and credential leakage. The advisory’s example is devastatingly practical: an internal Axios client is configured with an X-API-KEY, a caller passes http://attacker.test/ instead of a relative path, and the secret-bearing request leaves for the attacker-controlled host. Patched versions are 1.8.2 e 0.30.0. (GitHub)

That example matters because it shows the two risks that travel together in real systems. First, you can make the server talk to somewhere it should never talk to. Second, you can leak the context that made that request privileged in the first place: API keys, bearer tokens, internal cookies, or custom headers bound to the instance. The impact is not limited to classic metadata endpoints or loopback probes. It also includes data exfiltration to an external host that simply receives the same headers your internal service would have received. (GitHub)

Why baseURL was never a policy engine

Axios’ own docs say that baseURL is prepended unless the URL is absolute, and that allowAbsoluteUrls defaults to verdadeiro. That means the documented default behavior has always treated an absolute URL as authoritative. The allowAbsoluteUrls feature arrived in the 1.8.0 line, and subsequent changelog entries show more targeted fixes in 1.8.2, 1.8.3e 1.8.4 to handle path building and adapter behavior correctly. That is real progress. It is not the same thing as saying baseURL is now a complete security boundary. (Axios)

If your security model depends on “this string should stay under that base URL,” then your security model needs an explicit destination validation step before Axios sees the value. Even with newer versions, you should still treat the client library as a transport layer, not as the only place where policy is enforced. OWASP’s SSRF guidance pushes in the same direction: canonicalize the URL, validate the scheme, validate the host, and use allowlists where possible. (Série OWASP Cheat Sheet)

Here is the pattern many applications still get wrong:

import axios from "axios";

const internalAPIClient = axios.create({
  baseURL: "https://api.internal.example/v1/users/",
  headers: {
    "X-API-KEY": process.env.INTERNAL_API_KEY
  }
});

export async function fetchUserProfile(userInput) {
  // Dangerous: caller controls whether this stays a path
  const res = await internalAPIClient.get(userInput);
  return res.data;
}

And here is the safer version. The point is not to worship one helper function. The point is to make the destination explicit, canonical, and allowlisted before it reaches the transport layer:

import axios from "axios";

const ALLOWED_ORIGINS = new Set([
  "https://api.internal.example"
]);

function buildSafePathFromUserInput(userInput) {
  if (typeof userInput !== "string") {
    throw new TypeError("userInput must be a string");
  }

  // Accept only an application identifier, not a full URL
  if (!/^[A-Za-z0-9_-]+$/.test(userInput)) {
    throw new Error("invalid user identifier");
  }

  return `/v1/users/${userInput}`;
}

function parseAndValidateWebhookURL(candidate) {
  const url = new URL(candidate);

  if (!["https:"].includes(url.protocol)) {
    throw new Error("unsupported protocol");
  }

  if (url.username || url.password) {
    throw new Error("embedded credentials are not allowed");
  }

  if (!ALLOWED_ORIGINS.has(url.origin)) {
    throw new Error("destination not allowed");
  }

  return url;
}

const client = axios.create({
  baseURL: "https://api.internal.example",
  allowAbsoluteUrls: false,
  headers: {
    "X-API-KEY": process.env.INTERNAL_API_KEY
  }
});

export async function fetchUserProfileById(userId) {
  const safePath = buildSafePathFromUserInput(userId);
  const res = await client.get(safePath);
  return res.data;
}

export async function callTrustedWebhook(candidateURL, payload) {
  const safeURL = parseAndValidateWebhookURL(candidateURL);
  const res = await axios.post(safeURL.href, payload, {
    headers: { "Content-Type": "application/json" }
  });
  return res.status;
}

This code follows the logic Node’s WHATWG URL API was designed for: parse the string into structured components and validate those components, rather than trying to infer trust from string prefixes. Node’s documentation explicitly notes the structured decomposition of a WHATWG URL object and the fact that origin includes protocol and host but not embedded credentials, which makes it a useful unit for allowlist checks. (Node.js)

The deeper lesson is that safe URL handling is not an Axios trick. It is an application design choice. You get better security when you model user input as an identifier or path segment whenever possible, and only accept full URLs in flows that genuinely require them. When you do accept full URLs, you should parse them with a standards-based URL parser, validate them against an allowlist, reject dangerous schemes, reject embedded credentials, and decide up front whether redirects and proxies are part of the trust model. (Série OWASP Cheat Sheet)

At this point in the workflow, many teams discover that the hard part is no longer spotting the CVE. It is finding every code path where user influence reaches a destination sink, replaying controlled inputs against scoped targets, preserving evidence, and then retesting after a fix. That is exactly the stage where evidence-first offensive validation tooling becomes more valuable than another scanner alert. Penligent’s public materials describe the platform in terms that map naturally to this stage of work: recent CVE validation, one-click PoC generation, attack-surface testing, and reporting tied to reproducible evidence rather than just package metadata. (Penligente)

Axios npm CVE

CVE-2023-45857 was really about header propagation discipline

The older Axios XSRF issue is easy to misread as “just a front-end bug.” It was more important than that. GitHub’s reviewed advisory for CVE-2023-45857 says that affected versions from 0.8.1 through <0.28.0 e de 1.0.0 through <1.6.0 could expose the XSRF-TOKEN cookie by sending X-XSRF-TOKEN in requests to unintended hosts. NVD’s wording is blunt: Axios 1.5.1 could reveal the confidential XSRF-TOKEN by including it in the X-XSRF-TOKEN header for every request made to any host. The fixes landed in 1.6.0 e 0.28.0. (GitHub)

What made that issue important was not only token exposure. It was the model it revealed. The client library was willing to derive a security-sensitive header from a cookie and attach it beyond the narrow trust boundary many developers assumed existed. That is the same broad category of mistake as the SSRF issues: application context escaping the boundary the programmer thought they had set. In one case it was destination choice. In this case it was header propagation. (GitHub)

Axios’ current repository documentation shows how the model changed. Today, withXSRFToken explicitly controls whether Axios reads the XSRF cookie and sets the XSRF header. The default behavior is same-origin only. The docs also note that in older Axios versions, setting withCredentials: true implicitly caused Axios to set the XSRF header for cross-origin requests, whereas newer Axios separates those concerns and requires withXSRFToken: true if you really want that behavior. (GitHub)

That change created friction for some applications, especially frameworks and backends that had silently relied on the older behavior. You can see the operational consequences in issue discussions from teams that upgraded to fix the vulnerability and then found their old CSRF flow broken. That is not a sign that the fix was wrong. It is a sign that the older behavior was doing more implicit trust propagation than many apps realized. (GitHub)

A safe migration pattern is to make the policy explicit. Do not attach a token-derived header because a request is cross-origin and happens to carry credentials. Attach it only when the destination is one you have intentionally approved for that token.

import axios from "axios";

const TRUSTED_XSRF_ORIGINS = new Set([
  "https://app.example.com",
  "https://api.example.com"
]);

function shouldAttachXSRFHeader(config) {
  const base = config.baseURL ? new URL(config.baseURL) : new URL(window.location.origin);
  const target = new URL(config.url, base);

  return TRUSTED_XSRF_ORIGINS.has(target.origin);
}

const api = axios.create({
  withCredentials: true,
  withXSRFToken: false
});

api.interceptors.request.use((config) => {
  if (shouldAttachXSRFHeader(config)) {
    config.withXSRFToken = true;
  }
  return config;
});

The exact mechanism can vary. The important design point is that the rule lives in your code as a destination policy, not in an old library default you barely remember. That mindset scales better not just for XSRF headers, but for Authorization headers, internal API keys, tenant routing metadata, and custom headers that only make sense for one target origin. (GitHub)

Axios also has dangerous non-network paths that look harmless in review

One reason Axios security issues surprise good engineers is that they often assume all risk comes from “making an HTTP request.” That assumption breaks down in Node.js, where Axios has transport logic that can interpret more than plain HTTP URLs and can do meaningful work before any network call happens. Two recent records are especially good reminders of that. (GitHub)

CVE-2025-58754 and the data URI denial of service

The advisory for CVE-2025-58754 explains that when Axios runs on Node.js and receives a dados: URL, it does not perform HTTP at all. The Node adapter decodes the payload into memory and returns a synthetic response. The bug was that this path ignored maxContentLength e maxBodyLength, which only protected ordinary HTTP responses, so an attacker could hand the application a very large dados: URI and exhaust memory, even when the caller expected streaming semantics. Fixed versions are 0.30.2 e 1.12.0. (GitHub)

That issue is more than an implementation bug. It is a category lesson. If your application accepts “a URL to fetch,” the real question is not only which host it can reach. The question is also which schemes the library understands and what semantics those schemes trigger. A mental model built only around HTTP misses the possibility that an attacker can force decoding, buffering, or parsing behavior inside the client itself. (GitHub)

Here is a simplified example of how a normal-looking feature can turn into a denial-of-service sink:

import axios from "axios";
import express from "express";

const app = express();

app.get("/preview", async (req, res) => {
  const target = req.query.url;

  // Dangerous assumption:
  // "responseType: 'stream'" does not save you from the data: URI path here
  const upstream = await axios.get(target, {
    responseType: "stream",
    timeout: 5000,
    maxContentLength: 2 * 1024 * 1024
  });

  upstream.data.pipe(res);
});

app.listen(3000);

Se alvo is a giant dados: URI, you may not get the streaming behavior you expected. The right fix starts before Axios: reject schemes you do not need, parse the input with novo URL(), and allow only http: e https: in routes that are supposed to perform network fetches.

function validateFetchTarget(candidate) {
  const url = new URL(candidate);

  if (!["http:", "https:"].includes(url.protocol)) {
    throw new Error("unsupported scheme");
  }

  return url.href;
}

OWASP’s SSRF guidance supports the same general approach. Control the schemes, control the destinations, and do not assume that “it looks like a URL field” means every legal URL syntax should be accepted by the feature. (Série OWASP Cheat Sheet)

Axios npm CVE

CVE-2026-25639 and the mergeConfig crash

CVE-2026-25639 is another good example of a bug that reveals the wrong assumption. GitHub and NVD both describe the same condition: before 0.30.3 e 1.13.5, Axios’ mergeConfig function could throw a TypeError when it processed a configuration object containing __proto__ as an own property. The advisory is explicit that an attacker can trigger this using an object created via JSON.parse(), and it is equally explicit that this is not prototype pollution because the application crashes before any assignment occurs. (GitHub)

That clarification is important. Many developers see __proto__ and mentally jump straight to prototype pollution. This record is a different failure mode. It is an availability issue triggered by unsafe config ingestion. If your backend takes user-supplied JSON, parses it, and passes it straight into Axios config or into a merge that later becomes Axios config, an attacker may be able to crash request handling without ever touching a network destination. (GitHub)

Here is the brittle pattern:

import axios from "axios";
import express from "express";

const app = express();
app.use(express.json());

app.post("/proxy", async (req, res) => {
  const userConfig = JSON.parse(JSON.stringify(req.body));

  // Dangerous: attacker controls config shape
  const response = await axios.request({
    method: "GET",
    url: "https://api.example.com/data",
    ...userConfig
  });

  res.json(response.data);
});

app.listen(3000);

And here is the safer one:

import axios from "axios";
import express from "express";

const app = express();
app.use(express.json());

function mapAllowedAxiosOptions(body) {
  const out = {};

  if (body.timeout !== undefined) {
    if (!Number.isInteger(body.timeout) || body.timeout < 0 || body.timeout > 10000) {
      throw new Error("invalid timeout");
    }
    out.timeout = body.timeout;
  }

  if (body.params && typeof body.params === "object" && !Array.isArray(body.params)) {
    out.params = body.params;
  }

  if (body.headers && typeof body.headers === "object" && !Array.isArray(body.headers)) {
    out.headers = {
      "X-Request-Source": "proxy-service"
    };
  }

  return out;
}

app.post("/proxy", async (req, res) => {
  const safeConfig = mapAllowedAxiosOptions(req.body);

  const response = await axios.request({
    method: "GET",
    url: "https://api.example.com/data",
    ...safeConfig
  });

  res.json(response.data);
});

app.listen(3000);

The secure design pattern here is the same as the secure URL pattern earlier: do not let user-controlled data arrive at a powerful interface in its raw form. Map it into a narrow allowlist of fields you are willing to honor, and reject the rest. The patch matters, but the coding pattern matters more. (GitHub)

Not every Axios alert means Axios itself is the broken component

One of the easiest ways to waste time in dependency response work is to treat every alert with the package name in it as a direct package defect. Axios has had a recent example that makes this mistake very obvious.

GitHub published a reviewed advisory tying [email protected] to a critical issue in [email protected], then withdrew it the next day. The withdrawal notice says users of Axios 1.10.0 had the flexibility to use a patched version of form-data without upgrading Axios, because the vulnerability originated in the transitive dependency rather than in Axios itself. The advisory had initially pointed to form-data boundary generation using Math.random() and treated [email protected] as exposed because it resolved that transitive package version. (GitHub)

That incident is useful because it teaches three operational lessons at once. First, an Axios alert may actually be a dependency-tree alert. Second, the right remediation might be a transitive override rather than a package upgrade. Third, scanner output has state, and that state matters. A withdrawn advisory should trigger a deeper look, not a reflexive mass upgrade ticket. (GitHub)

Axios’ own ecosystem gives you a practical mechanism for handling that kind of case. npm’s overrides field exists precisely to replace or pin versions of dependencies in the tree. The npm docs describe it as a way to change dependencies of dependencies, including replacing a package with a version that addresses a security issue or forcing a consistent version everywhere. (npm Docs)

A typical mitigation looks like this:

{
  "dependencies": {
    "axios": "1.10.0"
  },
  "overrides": {
    "form-data": "4.0.4"
  }
}

That does not mean overrides are always the best answer. It means you should distinguish between “Axios code is broken,” “Axios defaults are risky,” and “Axios pulls a bad transitive version.” Those are different problems, and mature teams respond to them differently. (GitHub)

The same caution applies to disputed records. NVD’s entry for CVE-2024-57965 explicitly includes the tag disputed and says some parties believe the change only addressed a SAST warning message rather than a true vulnerability. The record still exists. Scanners may still surface it. But the right engineering response is to read the state of the record, not just the headline. Not all dependency alerts should carry the same urgency or imply the same degree of exploitability. (NVD)

The March 2026 malicious releases changed the meaning of Axios package risk

The March 2026 Axios npm incident is the reason this topic can no longer be reduced to CVEs alone. According to the official Axios issue, versions 1.14.1 e 0.30.4 were compromised and removed from the registry. Microsoft’s write-up states that these versions injected a malicious dependency, [email protected], which executed a postinstall path and fetched platform-specific second-stage payloads from known attacker infrastructure. Microsoft also says the publication metadata differed from the project’s normal CI-backed publishing pattern, including missing trusted publisher binding and missing corresponding repository tag or commit trail for the malicious versions. (GitHub)

Snyk’s incident analysis reaches the same core conclusion from another angle: the Axios source code itself was not altered to add malicious runtime logic. Instead, the attacker added a purpose-built dependency whose job was to trigger install-time execution. The malicious release window was brief, but any developer workstation, CI system, or build environment that performed a fresh install during that window could have been compromised without ever importing Axios in application code. (Snyk)

That is why the registry compromise belongs in the same discussion as the CVEs even though it is not the same kind of defect. From the user’s point of view, both situations appear as “Axios security problem.” From the defender’s point of view, they require different playbooks.

DimensãoProduct vulnerabilityRegistry compromise
Causa raizBug or risky default in package behaviorUnauthorized publish path or maintainer compromise
Primary fixUpgrade to patched version, review calling patternsTreat affected hosts as potentially compromised, rotate secrets, install known-good versions
Investigation scopeSource usage, sinks, inputs, environment exposureBuild logs, lockfiles, hidden lockfiles, host artifacts, credentials, CI runners
Main questionCan attacker-controlled input trigger this path in my appDid any environment install the malicious release during the live window
Good enough responseOften package upgrade plus code hardeningOften incident response, credential rotation, and host review

Source basis for the contrast above comes from GitHub’s official Axios issue, Snyk’s incident analysis, and Microsoft’s mitigation guidance. (GitHub)

Microsoft’s guidance is appropriately blunt: organizations that installed 1.14.1 ou 0.30.4 should rotate secrets and credentials immediately and downgrade to a known-safe version such as 1.14.0 ou 0.30.3. That is not how you respond to a normal package CVE. It is how you respond when install-time malware may already have run on developer or CI infrastructure. (Microsoft)

The practical point is this: if you search for “axios npm cve” because a scanner pinged you, do not stop at patch notes. Confirm whether the alert refers to a library bug, a transitive vulnerability, a disputed record, or a compromised release. The remediation path can swing from a one-line package bump to full credential rotation and endpoint review. (GitHub)

How to verify whether your code is actually exposed

A dependency dashboard can tell you that Axios is present. It cannot tell you whether your application has turned Axios into a security boundary in the dangerous places. That takes code review and targeted validation.

The first thing to look for is any place where Axios receives attacker-influenced destination material. That includes obvious features such as webhook URLs, image download URLs, avatar import URLs, callback URLs, and generic “fetch this URL” endpoints. It also includes less obvious flows where a path segment, tenant identifier, or resource ID is assumed to be harmless even though it still influences URL construction. OWASP’s SSRF guidance is a good mental checklist because the affected business patterns look very similar. (Série OWASP Cheat Sheet)

The second thing to look for is any place where you derive security-sensitive context automatically. If a browser flow still assumes old cross-origin XSRF behavior, or if a Node internal client attaches privileged headers to an Axios instance that can be pointed elsewhere, you have a propagation problem even if you patched the underlying CVE. The bug may be fixed, but the architectural habit remains. (GitHub)

The third thing to look for is config ingestion. Search for code that spreads, merges, or forwards request-like JSON into Axios config objects. If you find ...req.body, Object.assign(defaults, userInput), or any wrapper that accepts arbitrary config keys from outside a trust boundary, review it with CVE-2026-25639 in mind. That record is a strong reminder that configuration APIs are not harmless just because they are not your business payloads. (GitHub)

In teams that already have a mature validation workflow, this is the point where automation becomes useful in a very specific way. The hard part is not reading the advisory. The hard part is enumerating candidate sinks, replaying safe probes against scoped targets, collecting evidence, and making the retest reproducible after a fix. That is where an AI-assisted offensive workflow can be genuinely useful rather than cosmetic. Penligent’s public product positioning around evidence-first testing, CVE validation, one-click PoC generation, and reporting fits that kind of verification loop far more naturally than the older “scanner plus chatbot” model. (Penligente)

Build evidence matters more than package.json alone

The March 2026 compromise also reminded defenders that package response is not only about source repositories. npm’s documentation on lockfiles is especially relevant here. As of npm v7, the lockfile contains enough information to describe a complete package tree, and npm also uses a hidden lockfile at node_modules/.package-lock.json to optimize installation state. If you only inspect the root package-lock.json, you may miss evidence created in local workspaces or ephemeral CI trees. (npm Docs)

That means package investigations should look at more than one layer. Review the committed lockfile, inspect any local or cached install state, and if the environment still exists, inspect the installed dependency tree. In an incident involving install-time malware, the build system’s view of what was resolved and when it was resolved can be as important as the repository’s view of declared dependencies. (npm Docs)

Here are some practical commands worth keeping around:

# Inventory direct and transitive axios versions
npm ls axios

# Search for the malicious March 2026 releases and dependency
grep -RInE 'axios@1\.14\.1|axios@0\.30\.4|plain-crypto-js' \
  package-lock.json npm-shrinkwrap.json yarn.lock pnpm-lock.yaml . 2>/dev/null

# Inspect hidden npm v7+ lockfiles if node_modules still exists
find . -type f -path '*/node_modules/.package-lock.json' -print

# Check whether the suspicious dependency is present locally
find . -type d -name plain-crypto-js 2>/dev/null

Those commands are not magic, and they do not replace host review. They are just good evidence collection. The reason they matter is that npm’s install state can preserve the exact resolved tree, while the malicious Axios incident specifically abused installation behavior rather than application runtime code. (npm Docs)

Version upgrades are necessary, but they are not the whole fix

The most common dependency response mistake is treating version bumps as if they automatically erase the insecure calling pattern that made the package dangerous in context. Axios is a good example because several of its CVEs were fixed by changing how the library resolves destinations or propagates security-sensitive values. That absolutely reduces risk. It does not mean your application now has a well-defined outbound policy. (GitHub)

The safer engineering pattern is to define clear application-level rules and let Axios remain a transport tool underneath them. In practice that means modeling IDs as IDs, not as URLs; validating full URLs with the WHATWG parser before they hit Axios; separating client instances by trust domain; making header propagation explicit; rejecting dangerous schemes before the request layer; and mapping user input into narrow config allowlists instead of passing it straight through. (Node.js)

A small table makes the pattern easier to remember:

Input shapeErro comumBetter control
User ID or slugTreated as if it cannot become a URL boundaryValidate as identifier and build the path yourself
Webhook URLString prefix checks onlyParse with URL, validate scheme, origin, credentials, and port
Generic fetch URLAccept all legal URL schemesAllow only http: e https:
Browser XSRF token flowLet old defaults choose header propagationMake withXSRFToken policy explicit per trusted origin
User JSON configSpread into Axios options wholesaleMap only allowed keys into a clean config object
Transitive package alertForce top-level upgrade every timeCheck whether override or direct transitive patching is more appropriate

The support for these controls comes from Axios’ current config model, the relevant advisories, Node’s URL API, and npm’s override support. (Axios)

Supply chain controls are now part of the Axios security conversation

The March 2026 compromise also exposed a hard truth: you can patch every known Axios CVE and still lose if your package intake and publish controls are weak. That is not an Axios-specific observation anymore. It is a Node ecosystem observation. OWASP’s npm security cheat sheet recommends enforcing lockfiles, minimizing attack surface by ignoring run-scripts where practical, auditing dependencies, and using trusted publishers for secure package publishing. npm’s own documentation says npm ci installs from an existing lockfile and fails if the lockfile and manifest do not match, which makes it the right default for CI when you want deterministic installs rather than silent dependency drift. (Série OWASP Cheat Sheet)

That matters because install-time attacks exploit precisely the gap between “the version I expected” and “the package I actually resolved right now.” npm ci does not solve every supply chain problem, but it closes one of the most common doors: surprise dependency graph changes during CI. OWASP’s guidance and npm’s documentation align on that point. (Série OWASP Cheat Sheet)

The same is true for lifecycle scripts. OWASP’s npm cheat sheet specifically calls out --ignore-scripts as a way to reduce the malicious module attack surface during package installation, because install hooks such as postinstall are a known abuse path. That advice is directly relevant to the malicious Axios releases, which used an injected dependency to execute install-time code. Not every environment can globally disable scripts without breaking legitimate packages, but sensitive review pipelines and quarantine installs often should. (Série OWASP Cheat Sheet)

For publishers, npm’s trusted publishing documentation is now central reading. npm describes trusted publishing as OIDC-based publishing from CI/CD workflows, eliminating the need for long-lived npm tokens. The docs also note automatic provenance generation and frame trusted publishing as the preferred security model over traditional tokens. That matters even more after Microsoft reported that the malicious Axios releases were published outside the project’s normal trusted-publisher-backed flow. (npm Docs)

GitHub’s provenance write-up helps explain why this is strategically important. Package provenance links a published artifact back to the repository, source commit, and build instructions that produced it. That does not stop every compromise, but it gives consumers a verifiable line from published package to source and build context, which is exactly the line defenders want when deciding whether a release looks normal or suspicious. (The GitHub Blog)

A practical Node.js dependency policy now looks less like “run audit and update monthly” and more like this:

{
  "scripts": {
    "deps:ci": "npm ci",
    "deps:review": "npm ci --ignore-scripts"
  },
  "overrides": {
    "axios": "1.13.5"
  }
}

And in CI, the policy is often just as important as the code:

name: ci
on:
  push:
  pull_request:

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22
      - run: npm ci
      - run: npm test

That is not a full supply chain program, but it captures the key idea: freeze what you can, review what you install, and make publishing and artifact lineage harder to subvert. The Axios incident turned that from a nice-to-have into a mainstream expectation. (npm Docs)

Axios npm CVE, the real risk is your outbound trust boundary

What teams should do now

If you need one operational decision tree, it should start with classification. If the issue is CVE-2024-39338 or CVE-2025-27152, you should patch and then review every place where attacker-controlled input can influence a request destination. If the issue is CVE-2023-45857, patch and then review where security-sensitive headers are derived and where they are allowed to travel. If the issue is CVE-2025-58754, patch and then reject non-HTTP schemes before the request layer. If the issue is CVE-2026-25639, patch and then stop accepting arbitrary config-shaped objects from outside your trust boundary. (GitHub)

If the issue is [email protected] ou 0.30.4, do not treat it as ordinary dependency maintenance. Treat any environment that installed those versions as potentially compromised, rotate secrets, inspect build and install evidence, and move to a known-safe version. That is the clear line in Microsoft’s guidance and in the broader incident reporting from the security community. (Microsoft)

If the alert is disputed or withdrawn, do not ignore it blindly and do not escalate it blindly. Read the state of the record. Determine whether the problem is direct, transitive, theoretical, disputed, or withdrawn. Good dependency response is not about always moving faster. It is about classifying correctly so you do not waste time fixing the wrong thing while missing the real boundary failure. (GitHub)

Further reading and reference links

For the official package-side view, the Axios GitHub security advisories page is the best starting point, especially for the currently published advisories and their affected and patched version ranges. (GitHub)

For the SSRF records, read the GitHub advisory and NVD entry for CVE-2024-39338, then the GitHub advisory and NVD entry for CVE-2025-27152. Together they show the evolution from protocol-relative confusion to absolute-URL override, which is the clearest way to understand the Axios destination-control problem. (GitHub)

For the browser-side token issue, the GitHub advisory and NVD entry for CVE-2023-45857 remain the authoritative references, and Axios’ current repository documentation on withXSRFToken is useful for understanding how the model changed after the fix. (GitHub)

For the Node-specific denial-of-service paths, read the advisory and NVD entry for CVE-2025-58754 and the advisory plus release information for CVE-2026-25639. Those two records are the strongest evidence that Axios security review should include non-network paths and config ingestion paths, not just SSRF sinks. (GitHub)

For defensive engineering, OWASP’s SSRF Prevention Cheat Sheet, the npm security cheat sheet, npm’s docs for package-lock.json, npm ci, overrides, and trusted publishing are more useful than most secondary blog posts because they translate dependency events into durable controls. (Série OWASP Cheat Sheet)

For the March 2026 malicious release incident, Microsoft’s mitigation write-up is the most useful operational reference, especially for the host-compromise mindset, safe downgrade guidance, and the note that the malicious publication differed from the project’s normal trusted-publisher pattern. Snyk’s incident analysis is also valuable for understanding the install-time dependency injection path. (Microsoft)

For related Penligent reading, the most directly relevant internal article is Axios Compromised on npm, What the Malicious Releases Actually Did, which complements this piece by focusing on the malicious release mechanics rather than the longer-term Axios boundary model. Penligent’s public product pages are also relevant if your next step is turning these review patterns into scoped, repeatable validation and evidence collection rather than leaving them as checklist items. (Penligente)

Compartilhe a postagem:
Publicações relacionadas
pt_BRPortuguese