---
name: azion-mitigate-cve-2025-29927-in-next-js
description: >-
  Strip the x-middleware-subrequest header with a Rules Engine rule on Azion Applications, so a crafted request cannot skip Next.js middleware.
---

# Mitigate CVE-2025-29927 in Next.js

You can block requests that exploit CVE-2025-29927 from Azion Console, with one rule on [Rules Engine for Applications](/en/documentation/platform/applications/rules-engine/) that removes the header the exploit depends on.

CVE-2025-29927 is a vulnerability in Next.js, scored CVSS 9.1, that lets a request skip middleware execution. Next.js middleware commonly carries authentication, authorization, and rate limiting, so a request that skips it reaches protected routes with no credentials. The advisory record is [GHSA-f82v-jwr5-mffw](https://github.com/advisories/GHSA-f82v-jwr5-mffw) and in the [Next.js security advisory](https://nextjs.org/blog/cve-2025-29927).

Next.js uses an internal header, `x-middleware-subrequest`, to count recursive middleware calls and stop an infinite loop. An external client was never meant to send it. When a request arrives carrying that header at a specific value, Next.js reads the request as an internal subrequest and runs no middleware at all.

Next.js 14.x and 15.x take this value:

```http
x-middleware-subrequest: middleware:middleware:middleware:middleware:middleware
```

Next.js 11.1.4 through 12.1.x take a middleware path instead:

```http
x-middleware-subrequest: pages/_middleware
x-middleware-subrequest: pages/dashboard/_middleware
```

The request needs no credentials and no special privileges, and it works from any network. A successful exploit can:

- Reach protected routes and admin panels
- Skip authentication and authorization checks
- Expose sensitive data and internal APIs
- Bypass rate limiting and other protective measures
- Poison the cache, which leads to denial of service

> **Caution**
>
> Upgrading Next.js is the definitive fix. Treat the rule below as a temporary measure while you plan and run the upgrade.

---

## Prerequisites

- An Azion account. Refer to [How to create an account on Azion](/en/documentation/fundamentals/creating-account/).
- An application on [Applications](/en/documentation/platform/applications/) whose origin is your Next.js deployment.
- Access to Azion Console. To sign in, refer to [How to access Azion Console](/en/documentation/guides/platform/account-and-billing/how-to-access-azion-console/).

---

## Detect a vulnerable application

A deployment is vulnerable when its Next.js version falls inside one of these ranges:

| Next.js version | Vulnerable range       | Patched version    |
| --------------- | ---------------------- | ------------------ |
| 15.x            | `>= 15.0.0, < 15.2.3`  | `15.2.3`           |
| 14.x            | `>= 14.0.0, < 14.2.25` | `14.2.25`          |
| 13.x            | `>= 13.0.0, < 13.5.9`  | `13.5.9`           |
| 12.x            | `>= 12.0.0, < 12.3.5`  | `12.3.5`           |
| 11.x            | All versions           | No patch available |

The version is not always readable from outside the deployment. Four signals in an HTTP response point at a Next.js application that runs middleware:

- The `x-powered-by: Next.js` response header, which a deployment can turn off, so its absence proves nothing
- An `x-middleware-rewrite` or `x-nextjs-cache` response header
- A reference to `/_next/static/` in a response body
- A response to the exploit header that differs from the response to a plain request

To probe one target, or a list of them, with the [Nuclei template for CVE-2025-29927](https://github.com/6mile/nextjs-CVE-2025-29927):

```bash
# Scan a single target
nuclei -u https://<your-domain>/ -t ./CVE-2025-29927-6mile.yaml -fr

# Scan a list of targets
nuclei -l websites.list -t ./CVE-2025-29927-6mile.yaml -fr -silent
```

A positive match means the application runs Next.js with middleware headers. It does not name the version, so read the Next.js version in your deployment environment before you decide.

---

## Create the mitigation rule

The Next.js advisory recommends blocking any external request that carries the `x-middleware-subrequest` header before it reaches the application. A rule with the **Filter Request Header** behavior removes that header from every incoming request, so Next.js never reads it and middleware runs as written. One rule covers every route of the application, needs no change to application code, and is created and removed independently of your release cycle.

To create the rule:

1. **Open the application**

   Access [Azion Console](https://console.azion.com/) > **Applications**, then select the application that serves your Next.js deployment.

2. **Select the Rules Engine tab**

3. **Select + Rule**

4. **Name the rule**

   Enter a name for the rule. For example: `Strip x-middleware-subrequest - CVE-2025-29927`.

5. **(Optional) Describe the rule**

   Enter a description. For example: `Strips the x-middleware-subrequest header from all incoming requests to mitigate CVE-2025-29927 in Next.js.`

6. **Confirm that Request Phase is selected**

7. **Set the criterion**

   In the **Criteria** section, select the `${uri}` variable, the *starts with* comparison operator, and `/` as the argument. This matches every request to the application.

8. **Add the Filter Request Header behavior**

   In the **Behaviors** section, select **Filter Request Header**.

9. **Enter the header name**

   In the header name field, enter `x-middleware-subrequest`.

10. **Save the rule**

The rule appears in the **Rules Engine** tab of the application. It takes a few minutes to reach Azion's distributed infrastructure, so a request sent right away can still carry the header through to the origin.

---

## Validate the mitigation

Send the same request twice, once with the exploit header and once without it:

```bash
# With the exploit header
curl -i -H 'x-middleware-subrequest: middleware:middleware:middleware:middleware:middleware' \
  https://<your-domain>/protected-route

# Without the exploit header
curl -i https://<your-domain>/protected-route
```

Both calls return the same response, because the header was removed before either request reached the origin. A protected route that the exploit header opened before the rule stays closed after it. To review the requests that reached the application, refer to [Real-Time Events](/en/documentation/platform/real-time-events/).

---

## Upgrade Next.js to a patched version

The rule strips the header, and the vulnerable code stays in the deployment until you replace it. Upgrade to the patched release for your major version:

| Current version | Upgrade target           |
| --------------- | ------------------------ |
| 15.x            | `>= 15.2.3`              |
| 14.x            | `>= 14.2.25`             |
| 13.x            | `>= 13.5.9`              |
| 12.x            | `>= 12.3.5`              |
| 11.x            | Upgrade to 12.x or later |

Once the patched release runs in production and the application behaves as expected, turn the rule off or delete it.

---

## Next steps

- [Rules Engine for Applications](/en/documentation/platform/applications/rules-engine.md): Every criterion and behavior you can set on an application rule.
- [Applications](/en/documentation/platform/applications.md): How an application routes a request to its origin.
- [Real-Time Events](/en/documentation/platform/real-time-events.md): Read what each request carried when it reached the application.
- [Firewall guides and tutorials](/en/documentation/platform/firewall/guides.md): The other application security tasks on this hub.
