Skip to content
Oday Bakkour
Back to Knowledge Hub

Daily SEO Note — September 24, 2026: Next.js Patches a Critical next/og RCE

Oday Bakkour profile photo
Oday Bakkour
12 min read
Share
Daily SEO Note — September 24, 2026: Next.js Patches a Critical next/og RCE

1. SEO for Content Writers

The most consequential editorial change in the last 24 hours came from a regulator, not from Google. On 23 September 2026 the UK Competition and Markets Authority published a strengthened proposal that would require any search service or AI assistant appearing on a Google choice screen to fairly attribute publisher content. Google's own systems were quiet over the same window: the Search Status Dashboard listed no active incidents or ranking updates as of 23 September 2026, 23:12 PDT, and the documentation changelog logged nothing after 18 September. No core or spam update is running, so ranking movement today is not algorithmic.

Publisher attribution becomes a regulatory condition, not a courtesy

What changed: the CMA's revised User Choice Conduct Requirement consultation, published 23 September 2026, would make Google show UK users a search choice screen when they first set up an Android phone or open Chrome, and re-prompt them once a year. The proposal opens those slots to AI assistants that meet technical and security criteria, and adds a condition that providers on the screen must "fairly attribute publisher content when used — meaning people can easily access source content and know where their search results have come from."

Who it affects: all content, with the sharpest effect on UK-facing publishers and anyone whose traffic already routes through an AI answer. Rollout status: consultation only. Responses close 9 October 2026 and a final decision is expected by the end of 2026. Nothing is in force today.

What to do differently in your next article: make every original claim land on a page that is worth attributing. That means a dated byline, a named author, a stated method for any figure you publish, and a stable URL for the claim rather than a paragraph buried in a listicle. Attribution requirements reward content that has an identifiable source of record; they do nothing for aggregated restatement.

Nothing is deprecated by this proposal yet. Primary source: CMA, 23 September 2026.

Unconfirmed: third-party data claims AI Overviews are linking out far more often

What changed, reportedly: on 23 September 2026 Malte Landwehr of Peec AI shared measurements suggesting the share of AI Overviews containing external links moved from close to zero to more than a quarter. The figure was picked up by Search Engine Roundtable, whose author noted the result did not match his own observation and disclosed a small investment in the company that produced the data.

Who it affects: any content type that competes for informational queries. Rollout status: unconfirmed. Google has made no announcement, and this is a single vendor's measurement rather than a documented product change. Treat it as a hypothesis to test against your own Search Console and referral data, not as a reason to rewrite a content plan.

What to do differently: nothing yet. If you want to prepare for a world where citation inside an AI answer is worth something, the preparation is the same work that already pays — a clean definitional paragraph near the top, a comparison table with real values, and at least one claim that only you can make. None of that is wasted if the measurement turns out to be noise.

Running in the opposite direction, Google was spotted on 21 September 2026 testing anchor links inside AI Overviews that open AI Mode rather than the cited publisher page. Rollout status: unconfirmed test, no Google statement, no documentation change. Google's AI features guidance has not been updated since 10 December 2025.

Who it affects: informational and explainer content most of all. The editorial consequence, if it ships, is that a citation stops implying a visit — your name appears, the click does not. That is not a reason to write worse summaries; it is a reason to make sure the article contains something a restatement cannot carry.

What to do differently: answer the query outright in the first hundred words, then earn the click with what the answer cannot compress — your own test results, a downloadable dataset, a decision table with your own thresholds, screenshots from a tool you actually ran. Stop writing openings that withhold the answer to manufacture scroll depth; that tactic loses twice now, once with readers and once with the extractor.

Google's hreflang examples went uppercase — audit your localization, not your markup

What changed: Google's Localized versions of your pages documentation, last updated 21 September 2026 UTC and surfaced by the community on 23 September, now shows region codes uppercase throughout its examples. The page states plainly that "the hreflang value is case-insensitive; Google accepts lowercase and uppercase codes, but formatting region codes in uppercase (for example, en-GB) follows ISO 3166-1 Alpha 2 convention."

Who it affects: multilingual and multi-regional sites only. Rollout status: documentation change, cosmetic. Nothing about ranking or eligibility changed, and no existing lowercase implementation is broken.

What to do differently: use the prompt, not the change. Pull your hreflang cluster and ask, per market, whether the localized URL holds a genuinely localized article or a near-duplicate with swapped spellings. Markets that get real transcreation — local examples, local pricing, local query phrasing including transliteration and dialect variants — should keep a distinct article. Markets that only justify a spelling pass should point at the source article instead of accumulating thin duplicates.

Stop doing: stop treating an hreflang entry as evidence that a market is served. The tag is a routing instruction, not editorial coverage.

Google Business Profile gives owners four days to reject user-suggested edits

What changed: Google's Business Profile help documentation gained a section on notifications about suggested edits, reported 23 September 2026. Owners get four days after notification to accept or reject a user-suggested edit that needs review. If nobody responds, Google may publish the edit anyway when other public information — the business website, for instance — supports it. Some edits may be applied with no prior review at all.

Who it affects: local and multi-location content, not editorial articles. Rollout status: documented and live. Severity: important for anyone running profiles at scale, because the failure mode is silent — an unattended inbox becomes an approved change.

What to do differently: name an owner for Business Profile notifications and put a four-day service level on them, the same way you would for a correction request. If your site is the public source Google checks against, your own hours, address and service pages need to be right first — they are now the tiebreaker when you do not reply.

Apply to your next brief

  • Give every original claim an attributable home: named author, visible date, stated method, stable URL.
  • Front-load the answer in the first hundred words, then add the part a summary cannot restate — your own data, tests or thresholds.
  • Before commissioning a localized article, decide translation versus transcreation per market; do not let an hreflang entry stand in for coverage.
  • Add a four-day response SLA for Google Business Profile suggested-edit notifications, with a named owner.
  • Keep your own AI-referral baseline in Search Console and analytics so vendor claims about AI Overview behaviour can be checked rather than believed.

2. SEO for Developers

One breaking item dominates the engineering track. Next.js shipped an out-of-band patch on 22 September 2026 for a critical remote code execution flaw in the Node.js implementation of next/og — the exact code path most sites use to generate dynamic Open Graph images from page titles. A day later, on 23 September, Vercel gave advance notice of nine more vulnerabilities landing on 30 September. If you run Next.js 16.2 or later with dynamic OG images, this is a same-day pull request.

Breaking: CVE-2026-94545, remote code execution in next/og ImageResponse

Version and date: Next.js 16.3.6 (Active LTS) and 15.5.26 (Maintenance LTS), released 22 September 2026. Advisory GHSA-vcvr-r3jv-pc5j, CVE-2026-94545, CVSS 9.5, critical. Affected range: next >= 16.2.0 and < 16.3.6. The upstream cause is improper escaping in Satori-generated SVG, tracked as GHSA-wx4j-mvgx-mqwp, affecting satori >= 0.0.27 and < 0.33.5.

Breaking, and exploitable in a very ordinary configuration. The symptom if ignored: where attacker-controlled values reach SVG content, attributes or styles inside the Node.js ImageResponse, crafted input is interpreted as SVG markup rather than text, and combined with other upstream dependencies that can lead to remote code execution. The canonical SEO pattern — an opengraph-image route that reads a title from a search parameter or an unvalidated slug and renders it — is precisely the shape at risk. Applications using the Edge ImageResponse implementation are not affected, and 15.x is not affected by the RCE; 15.5.26 carries related hardening only.

What to change: your package.json dependency on next, plus any direct satori dependency and transitive copies in the lockfile. While you are in the file, stop interpolating unvalidated request input into the JSX passed to ImageResponse — constrain the title to a known record or a length-capped, escaped string, and fall back to a static image when lookup fails.

scripts/patch-next-og.sh
#!/usr/bin/env bash
set -euo pipefail

# Next.js 16.3.x (Active LTS) - fixes CVE-2026-94545 / GHSA-vcvr-r3jv-pc5j
npm install [email protected]

# Next.js 15.5.x (Maintenance LTS) - related hardening only, not vulnerable to the RCE
# npm install [email protected]

# Satori is the upstream cause; make sure no transitive copy is left behind.
npm ls satori || true
npm audit --omit=dev

# Expect: [email protected] or later everywhere in the tree.

Nine more Next.js vulnerabilities land on 30 September — book the window now

Version and date: advance notice published 23 September 2026. Next.js 16.3.7 and 15.5.27 are planned for 30 September 2026 and will address nine vulnerabilities — one critical, two high, five medium, one low — with full advisories published alongside the release.

Non-breaking as of today, because there is nothing to install yet. The symptom if ignored is scheduling, not exploitation: a critical-severity patch published on a Wednesday with no prepared upgrade path becomes a rushed deploy on a Friday. Vercel publishes these notices specifically so teams can reserve the window.

What to change: your release calendar, and a CI guard that fails the build when the installed Next.js version drops below the patched floor. Pin the floor to 16.3.6 today and raise it to 16.3.7 on 30 September once the advisories are public.

scripts/check-next-version.sh
#!/usr/bin/env bash
# Fail CI when the installed Next.js version is below the current patched floor.
set -euo pipefail

FLOOR="16.3.6"   # raise to 16.3.7 on 2026-09-30, when the advisories publish
INSTALLED="$(node -p "require('next/package.json').version")"

if [ "$(printf '%s\n%s\n' "$FLOOR" "$INSTALLED" | sort -V | head -n1)" != "$FLOOR" ]; then
  echo "Next.js $INSTALLED is below the patched floor $FLOOR" >&2
  exit 1
fi

echo "Next.js $INSTALLED meets the $FLOOR floor."

Google's page experience docs now point at experimental CrUX ad metrics

Version and date: the resources section of Understanding page experience in Google Search results was updated on 22 September 2026 to link the CrUX ad metrics. The underlying CrUX metrics documentation was last updated 15 September 2026 and documents four: Ad Count, Ad Density, Ad Weight (CPU) and Ad Weight (Network).

Non-breaking and informational. These are labelled experimental, and Google's John Mueller has said they are included because they help evaluate the state of a site, not because they are ranking factors. The symptom if ignored is diagnostic blindness rather than a ranking loss: on an ad-supported template, ad weight is frequently the single largest contributor to a failing INP or LCP, and you cannot attribute it from the Core Web Vitals triad alone.

What to change: your monitoring job. Keep pulling the field metrics you already track from the CrUX API, and check the metrics documentation above for the current availability of the experimental ad fields before wiring them into a dashboard — experimental metrics move. The call below is the stable record query for an origin.

scripts/crux-query.sh
#!/usr/bin/env bash
# Pull field data for an origin from the Chrome UX Report API.
set -euo pipefail

curl -sS -X POST \
  "https://chromeuxreport.googleapis.com/v1/records:queryRecord?key=$CRUX_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{
    "origin": "https://example.com",
    "formFactor": "PHONE",
    "metrics": [
      "largest_contentful_paint",
      "interaction_to_next_paint",
      "cumulative_layout_shift"
    ]
  }' | jq '.record.metrics'

# Experimental ad metrics (Ad Count, Ad Density, Ad Weight CPU/Network) are
# documented at developer.chrome.com/docs/crux/methodology/metrics - confirm
# current availability there before adding them to this request.

hreflang region codes: uppercase is now the documented convention

Version and date: Localized versions of your pages updated 21 September 2026 UTC. Every example now uses uppercase region codes, and the page states the value is case-insensitive — Google accepts both — with uppercase chosen to follow ISO 3166-1 Alpha 2.

Non-breaking, and there is no symptom if ignored. Existing lowercase annotations keep working. The only reason to touch anything is consistency: if half your generator emits en-gb and half emits en-GB, a diff-based regression check on your sitemap or head tags will produce noise forever. Normalise once, in the generator, not by hand across templates.

What to change: wherever you build alternates. In the Next.js App Router that is the alternates.languages object returned from generateMetadata, and the matching entries in your sitemap generator. Keep x-default pointing at the market you actually want unmatched visitors to land on.

app/[locale]/guide/page.tsx
import type { Metadata } from 'next'

const SITE = 'https://example.com'
const LOCALES = ['en-US', 'en-GB', 'ar-SY', 'fr-FR'] as const

export async function generateMetadata({
  params,
}: {
  params: Promise<{ locale: string }>
}): Promise<Metadata> {
  const { locale } = await params

  return {
    alternates: {
      canonical: `${SITE}/${locale}/guide`,
      languages: {
        // Uppercase region codes follow ISO 3166-1 Alpha 2.
        // Google treats hreflang values as case-insensitive either way.
        ...Object.fromEntries(
          LOCALES.map((l) => [l, `${SITE}/${l}/guide`]),
        ),
        'x-default': `${SITE}/en-US/guide`,
      },
    },
  }
}

Cloudflare shipped a WAF ruleset on 22 September, with another due 29 September

Version and date: the Cloudflare developer changelog records a WAF release dated 2026-09-22 adding detections for SSRF attempts using non-standard IP notations, jar loopback payloads and Jinja template injection, plus scheduled changes for 2026-09-29 covering broken access control, HTTP request smuggling and command injection.

Non-breaking by intent, and no SEO change is announced. It is on this list because managed-rule rollouts are the most common way a CDN quietly stops matching your robots.txt intent: a new detection fires on a crawler's request shape, the origin never sees it, and Search Console reports a crawl anomaly days later with no deploy to blame. The same applies to the AI crawler decisions you make per fetcher — allowing OAI-SearchBot while disallowing GPTBot in robots.txt means nothing if an edge rule answers first.

What to change: nothing in a config file. Add a post-WAF-release check to your monitoring — verify Googlebot by reverse DNS with forward confirmation, then fetch robots.txt and a representative content URL through the CDN with a crawler user agent and assert a 200. Run it after 29 September.

scripts/verify-googlebot.sh
#!/usr/bin/env bash
# Confirm the CDN is not overriding robots.txt intent after a WAF release.
set -euo pipefail

SITE="https://example.com"
GOOGLEBOT_UA="Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"

# 1. Verify a crawler IP from your logs: reverse DNS, then forward-confirm.
IP="66.249.66.1"
HOST="$(dig +short -x "$IP" | sed 's/\.$//')"
echo "reverse: $IP -> $HOST"
dig +short "$HOST"   # must resolve back to $IP

# 2. robots.txt must be reachable as Googlebot, and as an AI search fetcher.
for UA in "$GOOGLEBOT_UA" "OAI-SearchBot/1.0" "Claude-SearchBot/1.0"; do
  CODE="$(curl -s -o /dev/null -w '%{http_code}' -A "$UA" "$SITE/robots.txt")"
  echo "$CODE  robots.txt  as: $UA"
  [ "$CODE" = "200" ] || exit 1
done

# 3. A real content URL, not just robots.txt.
curl -s -o /dev/null -w '%{http_code}  content URL as Googlebot\n' \
  -A "$GOOGLEBOT_UA" "$SITE/"

Ship today

  1. Upgrade to Next.js 16.3.6 if you run 16.2.0 or later. This closes CVE-2026-94545, CVSS 9.5, in the Node.js next/og ImageResponse path.
  2. Confirm satori resolves to 0.33.5 or later everywhere in the lockfile, including transitive copies.
  3. Audit every opengraph-image route for unvalidated request input reaching the JSX passed to ImageResponse; constrain or escape it, with a static fallback.
  4. Add the patched-version floor check to CI, pinned at 16.3.6 today and raised to 16.3.7 on 30 September.
  5. Reserve a deploy window for 30 September for the nine-vulnerability Next.js release.
  6. Normalise hreflang region codes to uppercase in your metadata and sitemap generators — cosmetic, but it stops diff noise.
  7. Schedule a Googlebot and AI-fetcher reachability check for 29 September, after the next Cloudflare WAF release.
Add Oday Bakkour as a preferred source on Google

Comments

Share your thoughts and join the conversation

Leave a Comment

Loading comments...
RELATED