フロントエンド

Next.js May 2026 security release対応入門——認可と依存更新を棚卸しする

Next.js May 2026 security releaseを題材に、App Router、middleware認可、Firestore、GitHub Actionsを安全に棚卸しする実践手順を解説します。

2026年6月21日
Next.jsReactセキュリティFirestoreGitHub Actions
Next.js May 2026 security release対応入門——認可と依存更新を棚卸しする

はじめに

Next.js App Routerで業務アプリを作っていて、こんな状態になっていませんか?

状況リスク
middleware.ts だけで管理画面を守っている迂回経路が出たときにページ側の認可が空になる
Server ActionsからFirestoreへ直接書き込む権限確認の場所が曖昧になる

2026年5月7日、Vercelは Next.js May 2026 security release を公開しました。公式発表では、DoS、middleware/proxy bypass、SSRF、cache poisoning、XSSを含む13件のアドバイザリが案内されています。React Server Components由来のCVE-2026-23870も含まれており、Next.js App Routerを使うプロジェクトは無視できません。

本記事では、架空の社内申請SaaS「SecureDesk」を題材に、Next.js + Firestore + GitHub Actions + TypeScriptの構成で、依存更新と認可設計を棚卸しします。

何が発表されたのか

Vercelの発表では、Next.jsの推奨アップグレード先として 15.5.18 または 16.2.6 が示されています。Next.js 13.x/14.xは、15系または16系の修正版へ上げる必要があります。Next.js 15.xは 15.5.18、Next.js 16.xは 16.2.6 が修正済みです。

領域SecureDeskで見る場所
Server Functions / RSCServer Actions、Route Handlers
middleware / proxy/admin/billing/approvals
WebSocket / Cache / Script独自Nodeサーバー、共有キャッシュ、CSP nonce

パッチ適用が最優先ですが、同時に「保護したい画面がmiddlewareだけに依存していないか」「Firestore書き込み前にサーバー側で権限を見ているか」を確認します。

ハンズオン1: 依存を更新する

まず現在のNext.jsバージョンを確認します。

node -p "require('./package.json').dependencies.next"
yarn why next

Next.js 16系なら修正版へ上げます。

yarn add next@16.2.6
yarn build

Next.js 15系なら next@15.5.18 です。react-server-dom-* を直接依存している場合は、その該当バージョンも確認します。

ハンズオン2: middlewareだけの認可をやめる

今回のアドバイザリには、App Routerでmiddlewareやproxyベースの認可に依存するアプリが、特定の経路で保護対象へ到達される可能性があるものが含まれています。すぐにアップグレードできない場合は、ページやルート側でも認可することが示されています。

SecureDeskでは、/approvals 配下を承認者だけが見られる想定にします。middlewareではログイン済みかどうかを早めに見ますが、最終判断はFirestore読み書き直前でも行います。

たとえば requireApprovalRole(userId) というサーバー専用関数を作り、userRoles/{userId} をFirestoreから読みます。roleapprover または admin で、かつ disabled でないことを確認してからデータ取得や更新へ進みます。Server Component、Route Handler、Server Actionからこの関数を呼べば、middleware以外にも防御線を置けます。

ハンズオン3: Server Actionの書き込みにも権限を置く

Firestoreへの書き込みも同じです。承認処理では、操作者の権限と対象ドキュメントの状態を確認してから更新します。

"use server";

import { getFirestore } from "firebase-admin/firestore";
import { requireApprovalRole } from "@/lib/auth/require-approval-role";
import { getCurrentUserId } from "@/lib/auth/session";

const db = getFirestore();
type Decision = "approved" | "rejected";

export async function decideApproval(requestId: string, decision: Decision) {
  const userId = await getCurrentUserId();
  await requireApprovalRole(userId);

  if (decision !== "approved" && decision !== "rejected") {
    throw new Error("Invalid decision");
  }

  const requestRef = db.collection("approvalRequests").doc(requestId);
  const auditRef = db.collection("auditLogs").doc();

  await db.runTransaction(async (tx) => {
    const snapshot = await tx.get(requestRef);
    if (!snapshot.exists || snapshot.get("status") !== "pending") {
      throw new Error("Request is not actionable");
    }

    tx.update(requestRef, { status: decision, decidedBy: userId });

    tx.create(auditRef, {
      action: `approval.${decision}`,
      requestId,
      actorId: userId,
    });
  });
}

これはNext.jsの脆弱性そのものを直すコードではなく、業務データへの到達点で認可を再確認する防御線です。

ハンズオン4: CIで更新漏れを減らす

依存更新は1回だけでは終わりません。GitHub ActionsでPRごとのbuildを固定します。

name: Next.js Security Check

on:
  pull_request:
    branches: [main]
  workflow_dispatch:

permissions:
  contents: read

jobs:
  nextjs:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: "22"
          cache: "yarn"

      - run: yarn install --frozen-lockfile
      - run: node -p "require('./package.json').dependencies.next"
      - run: yarn build

Dependabotなどで依存更新PRを作る場合も、セキュリティPRは小さく保ちます。

導入チェックリスト

  1. 公式発表とGitHub Security Advisoryで影響範囲を確認する
  2. next15.5.18 または 16.2.6 へ上げる
  3. yarn build と主要画面の動作確認を行う
  4. middleware.tsproxy.tsbeforeInteractive、WebSocket upgradeの利用を検索する
  5. Firestoreを読む・書くサーバー処理にも認可を置く
  6. GitHub Actionsで更新確認を継続する

参考リンク

まとめ

Next.js May 2026 security releaseは、依存更新だけでなく認可設計を見直すきっかけになります。まず修正版へ上げ、yarn build で確認します。そのうえで、Firestoreを読む・書く直前のサーバー処理にも権限確認を置き、GitHub Actionsで同じ棚卸しを継続できる形にしておきましょう。