May 5, 2026·5 min read·107 visits
A flaw in the Axios configuration merging process allows a polluted Object prototype to overwrite the `validateStatus` function. This causes the client to treat 4xx and 5xx error responses as successful, potentially bypassing authentication and error-handling checks.
Axios versions prior to 1.15.1 and 0.31.1 contain a prototype pollution gadget in the configuration merging logic. This vulnerability allows an attacker to bypass authentication mechanisms by leveraging a separate prototype pollution flaw to manipulate the HTTP response validation process.
Axios is a widely adopted promise-based HTTP client for Node.js and the browser. The library employs a configuration merging system to combine global defaults with per-request configuration objects. This mechanism processes properties like headers, base URLs, and response validation functions.
The vulnerability exists within the lib/core/mergeConfig.js module, specifically affecting how certain direct configuration keys are merged. Axios assigned the validateStatus property to a merging strategy that utilized the JavaScript in operator. This operator inherently traverses the object prototype chain during property existence checks.
Because the in operator evaluates properties on the prototype, Axios acts as a prototype pollution gadget. If an attacker pollutes the global Object.prototype via an independent vulnerability, Axios will adopt the polluted properties during configuration merging. This transforms a generic prototype pollution flaw into a specific application logic bypass.
The root cause of CVE-2026-42041 is the insecure implementation of the mergeDirectKeys strategy within the Axios configuration merging engine. Axios utilizes distinct strategies to handle different types of configuration data. The validateStatus property dictates whether an HTTP response is treated as a success or failure, and it is processed using mergeDirectKeys.
The mergeDirectKeys function originally relied on the JavaScript in operator to determine if a property was supplied in the user's configuration object. The in operator returns true if a property exists directly on the object or anywhere within its prototype chain. This design choice introduced a severe side effect when the global prototype is modified.
When prop in config2 is evaluated, the JavaScript engine checks config2 for the validateStatus property. If the property is absent from config2, the engine inspects Object.prototype. If an attacker has polluted Object.prototype.validateStatus, the in operator returns true, and Axios assigns the malicious function as the active response validator.
The vulnerability manifests in the mergeDirectKeys function located in lib/core/mergeConfig.js. The original code evaluated property existence using the in operator, which exposed the logic to prototype chain pollution.
// Vulnerable Implementation (lib/core/mergeConfig.js)
function mergeDirectKeys(config1, config2) {
// ...
if (prop in config2) { // Traverses the prototype chain
return getMergedValue(config1[prop], config2[prop]);
}
// ...
}The patched implementation replaces the in operator with Object.prototype.hasOwnProperty.call(). This method strictly checks for properties defined directly on the object, ignoring properties inherited through the prototype chain.
// Patched Implementation (lib/core/mergeConfig.js)
function mergeDirectKeys(config1, config2) {
// ...
if (Object.prototype.hasOwnProperty.call(config2, prop)) { // Ignores prototype
return getMergedValue(config1[prop], config2[prop]);
}
// ...
}This fix is complete for the mergeDirectKeys strategy. It effectively neutralizes the specific gadget chain involving validateStatus. Security researchers should note that other JavaScript libraries employing the in operator for configuration merging remain susceptible to similar gadget behavior.
Exploitation requires a pre-existing prototype pollution vulnerability within the target application or its dependencies. The attacker first identifies an entry point, such as a vulnerable deep-merge function or JSON parser, to pollute the global prototype.
The attacker injects a payload that assigns a permissive function to the validateStatus property on Object.prototype. A standard payload sets this property to a function that always returns true, such as Object.prototype.validateStatus = () => true;. This function instructs Axios to accept any HTTP status code as a successful response.
Axios relies on lib/core/settle.js to process responses. The settle module executes the validateStatus function to determine if the Promise should be resolved or rejected. With the polluted function active, settle.js resolves the Promise regardless of the actual server response code.
// lib/core/settle.js execution flow
if (!validateStatus || validateStatus(response.status)) {
resolve(response); // Attacker payload forces this branch to execute
} else {
reject(new AxiosError(...));
}The CVSS v3.1 base score for this vulnerability is 4.8 (Medium), reflecting the high attack complexity. The vulnerability cannot be exploited in isolation; it functions purely as an amplifier for an existing prototype pollution flaw. Despite the medium score, the practical impact on application security can be critical.
Applications frequently use Axios interceptors to enforce authentication and authorization controls. A common pattern involves catching 401 Unauthorized or 403 Forbidden responses to trigger a logout process or token refresh. The prototype pollution gadget bypasses this logic entirely by masking the error response.
When a 401 response is silently converted into a resolved Promise, the application processes the empty or error-formatted response body as legitimate data. This leads to undefined application states, logic errors, or unauthorized access to restricted client-side views. The vulnerability severely compromises the integrity of the client-side state machine.
The primary remediation strategy is upgrading Axios to a patched version. Developers must update their dependencies to Axios version 1.15.1 or 0.31.1. Upgrading removes the insecure in operator from the configuration merging logic.
If immediate patching is not feasible, developers can implement a functional workaround. By explicitly defining a validateStatus function at the global Axios instance level, the application shadows the prototype chain. This prevents the JavaScript engine from traversing up to the polluted Object.prototype.
A secondary defense-in-depth measure involves auditing the application and its dependency tree for primary prototype pollution vulnerabilities. Addressing the root cause of the prototype pollution eliminates the prerequisite for this gadget. Development teams should employ dependency scanning tools and enforce strict input validation on all functions that recursively process object properties.
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
Axios Axios | < 0.31.1 | 0.31.1 |
Axios Axios | >= 1.0.0, < 1.15.1 | 1.15.1 |
| Attribute | Detail |
|---|---|
| Vulnerability Class | Prototype Pollution Gadget (CWE-1321) |
| Attack Vector | Network-based (Requires prior pollution) |
| CVSS v3.1 Score | 4.8 (Medium) |
| EPSS Score | 0.00088 (24.91%) |
| Primary Impact | Authentication Bypass / Logic Flaw |
| Exploit Status | Proof of Concept available |
Improperly Controlled Modification of Object Prototype Attributes ('Prototype Pollution')
CVE-2026-118777 is a prototype pollution vulnerability (CWE-1321) in the Forge JavaScript cryptography and networking library (distributed on npm as node-forge) prior to version 1.4.1. The flaw resides in the forge.http client subsystem, where incoming HTTP cookie names and paths parsed from Set-Cookie response headers are stored directly into standard JavaScript objects without key validation or property isolation. By returning crafted Set-Cookie headers containing keys such as __proto__ or constructor, a malicious HTTP server can inject arbitrary properties into Object.prototype, attach attributes to the global Object constructor, or delete built-in prototype methods to cause an application-wide denial of service.
CVE-2026-118775 (GHSA-4642-5mcj-2rqw) is an integer overflow and validation flaw in the ASN.1 serialization module of Forge (node-forge) prior to version 1.4.1. The asn1.oidToDer() function fails to validate the range of the first two arcs of an Object Identifier (OID) and truncates the packed initial subidentifier to a single 8-bit integer. Applications that perform policy checks on untrusted OID strings before encoding them into Distinguished Encoding Rules (DER) format can be tricked into emitting DER bytes that correspond to a completely different, restricted OID.
CVE-2026-119194 is an algorithmic complexity vulnerability (CWE-407) in the pyasn1 library for Python, affecting versions 0.3.3 through 0.6.4. The flaw resides in the schemaless decoding routine ConstructedPayloadDecoderBase._decodeComponentsSchemaless used across BER, CER, and DER codecs. By sending an ASN.1 container populated with child components whose tag identifiers are separated by multiples of CPython's integer hash modulus (sys.hash_info.modulus), an unauthenticated attacker can force worst-case hash collisions in an unbounded Python set, degrading decoding performance from O(N) to O(N^2) and causing a Denial of Service (DoS).
CVE-2026-119195 is an algorithmic complexity vulnerability (CWE-407) in the pyasn1 library for Python, affecting all versions prior to 0.6.5. When decoding constructed strings or indefinite-length ANY types across BER, CER, and certain DER code paths, the payload decoders repeatedly concatenate incoming fragments onto an immutable bytes object using the += operator. Because Python bytes objects cannot be resized in-place, each fragment iteration allocates a new buffer and copies all previously accumulated bytes, resulting in quadratic O(N^2) time and memory copy complexity. An unauthenticated remote attacker can supply a highly fragmented ASN.1 stream to exhaust CPU cycles and stall application worker threads.
An algorithmic complexity vulnerability (CWE-407) in pyasn1 versions prior to 0.6.5 allows unauthenticated attackers to cause a Denial of Service (DoS) via crafted ASN.1 payloads. The flaw resides in the binary-encoded ASN.1 REAL mantissa deserialization routine within RealPayloadDecoder.valueDecoder. By performing iterative byte-string slicing and repeated bitwise shifts on a growing arbitrary-precision integer, the decoder exhibits quadratic time and memory allocation complexity relative to the mantissa length. Supplying a BER-, CER-, or DER-encoded payload with a large REAL mantissa causes excessive CPU consumption and blocks application worker processes.
A vulnerability classified under CWE-407 (Inefficient Algorithmic Complexity) exists in the pyasn1 library prior to version 0.6.5. When parsing constructed ASN.1 BIT STRING payloads under BER, CER, or schema-driven DER encoding rules, the BitStringPayloadDecoder repeatedly shifts and copies the entire accumulated bit value for each incoming fragment. Processing inputs with a large number of small constructed fragments induces quadratic CPU consumption, allowing unauthenticated remote attackers to cause a denial of service via resource exhaustion during the initial decoding phase.