Next.js dev MCP endpoint leak: keep your Sume API key out of source

CVE-2026-94486 let a malicious page read source snippets from next dev. Keep the Sume API key in an env var, server-side, and log request ids not headers.

4 min readSume
All posts

A Low-severity advisory is still a reason to check where your Sume key lives. Next.js CVE-2026-94486 says a malicious website could read parts of a project through the next dev MCP endpoint, and a key written into source can travel with those parts.

Next.js facts are from its September 30 security release; Sume facts from Authentication and the SDK overview, read 2026-10-01.

What does the advisory say?

The post says next dev exposes an MCP endpoint that does not verify request origin. A malicious website could read the project location on disk, source snippets from error reports, the route inventory and dev logs. It says production deployments do not serve it. The fix is in v16.3.8 and v15.5.27.

What the dev endpoint exposed, from the Next.js post read 2026-10-01
DataExposed by the dev MCP endpoint
Project location on diskYes
Source snippets from error reportsYes
Route inventoryYes
Dev logsYes
Production deploymentsNot served

Where should the Sume key live?

A Sume API key spends your credits and there is no browser-safe variant. The docs say never to ship one to client JavaScript or a NEXT_PUBLIC_* variable, and to put your own endpoint in front and build the Sume request there. Read it from process.env so no literal sits in a line that an error report could quote.

I am inferring the link between source snippets and keys: the advisory lists snippets, not secrets, so it does not say env values were exposed.

What does a safe route look like?

The handler builds the client from the env var and returns only the job id. On failure it logs the status, not headers or the body. The request_id inside Sume's error envelope is what support needs.

import { createSumeClient, generateVideoV1 } from "@sume-com/sdk";

export async function POST(req: Request) {
  const apiKey = process.env.SUME_API_KEY;
  if (!apiKey) return Response.json({ error: "server misconfigured" }, { status: 500 });

  const { prompt } = await req.json();
  const client = createSumeClient({ apiKey });
  const { data, error, response } = await generateVideoV1({
    client,
    headers: { "idempotency-key": crypto.randomUUID() },
    body: { prompt, mode: "async" },
  });
  if (error) {
    console.error("sume submit failed", response.status);
    return Response.json({ error: "upstream" }, { status: 502 });
  }
  return Response.json({ job_id: data!.data.request_id });
}

What should you do if a key was exposed?

Rotate it from the dashboard; the docs say to rotate a key that may have been exposed. Also keep keys out of support tickets and screenshots.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume