Skip to content

fix(website-lambda): gate .plain.html and .md variants of private pages - #163

Merged
chrischrischris merged 2 commits into
mainfrom
cpeyer-adobe-gate-private-plain-html
Oct 1, 2026
Merged

chrischrischris merged 2 commits into
mainfrom
cpeyer-adobe-gate-private-plain-html

Conversation

@chrischrischris

Copy link
Copy Markdown
Collaborator

Description

Severity: SEV2. Private pages and audience-private blocks leaked to signed-out visitors through AEM's head-less page variants.

The website Lambda decided whether a page is private by scanning <head> for <meta name="audience" content="private">. AEM's .plain.html and .md variants have no <head>, so for a private page like /support/developer-overview:

  • /support/developer-overview correctly returned 404 to signed-out visitors.
  • /support/developer-overview.plain.html and /support/developer-overview.md returned 200 with the full page content.
  • Public pages served through these variants (for example /index.plain.html and /index.md) still included audience-private blocks.

This PR closes both leaks in workers/website-lambda/:

  • Privacy comes from the canonical page. For a signed-out request to a .plain.html or .md variant, the Lambda fetches the canonical page (/foo.plain.html → /foo, /index.plain.html → /) and runs the existing isPrivateHtml check on it. A private page returns 404. Any lookup failure (non-200, redirect or network error) also returns 404, so the check fails closed.
  • Audience blocks are filtered in both variants.
    • filterAudienceBlocks now matches the block markup that .plain.html uses.
    • The new filterAudienceMarkdown removes audience-private block tables from .md, including headers with inline formatting such as **Cards (audience private)** and the image reference definitions left behind by removed blocks.
  • Cache safety. GATE_ETAG_VERSION is bumped to 2, so copies filtered by the old gate are never confirmed with a 304.
  • Docs. The README's new "Page variants" section explains the behavior.

The Cloudflare worker (workers/website/) is unaffected because it denies signed-out visitors by default.

chrischrischris and others added 2 commits October 1, 2026 10:01
AEM serves every page as head-less variants (<page>.plain.html, <page>.md)
that carry no <head>, so the audience meta gate could not see that the page
was private and served it to anonymous visitors. The audience block filter
also missed both variants (no <main> in .plain.html; .md not filtered).

- gate.js: getCanonicalPagePath maps variants to their page; .md is now
  page-like (gate) instead of default-allow.
- index.js: for anonymous variant requests, fetch the canonical page and
  run isPrivateHtml on it before proxying; fail closed (404) on private,
  non-200/redirect, non-HTML, or fetch error.
- audience.js: strip audience blocks from .plain.html markup, and add
  filterAudienceMarkdown for .md block tables (plus orphaned image refs).
- Tests for gate, audience, and a new index.test.js with mocked fetch.
- README: document variant gating.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Resolve conflicts with the gated-ETag / sitemap work on main: export
isPageLike (now including .md variants), keep main's 206 fail-closed and
gated 304 handling alongside the canonical-page check, move the variant
routing tests to index.variants.test.js, and bump GATE_ETAG_VERSION to 2
since the audience filtering changed.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@aem-code-sync

aem-code-sync Bot commented Oct 1, 2026

Copy link
Copy Markdown

Hello, I'm the AEM Code Sync Bot and I will run some actions to deploy your branch and validate page speed.
In case there are problems, just click a checkbox below to rerun the respective action.

  • Re-run all PSI checks
  • Re-run failed PSI checks
  • Re-sync branch
Commits

@chrischrischris
chrischrischris merged commit cb9e06a into main Oct 1, 2026
7 of 9 checks passed
@chrischrischris
chrischrischris deleted the cpeyer-adobe-gate-private-plain-html branch October 1, 2026 16:53

This branch was successfully deployed

1 active deployment
cpeyer-adobe-gate-private-plain-html — ac103ed0 Deployed Oct 1, 2026 by aem-code-sync[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants