Skip to content

fix(security): stop serving the aem.live site on workers.dev hostnames - #69

Open
trieloff wants to merge 2 commits into
mainfrom
fix/workers-dev-no-site-proxy
Open

trieloff wants to merge 2 commits into
mainfrom
fix/workers-dev-no-site-proxy

Conversation

@trieloff

@trieloff trieloff commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

Why

The Cloudflare account Helix-Dev (852dfa4ae1b0d579df29be65b986c101) has accepted phishing abuse reports (Netcraft and others) on:

Hostname Report date Notes
rum-proxy-ci.adobeaem.workers.dev/ 2026-10-02 / 2026-10-03 mitigation phishing_interstitial active since 2026-10-03 09:58Z
rum-proxy-prod.adobeaem.workers.dev/ 2026-05-28
rum-explorer-og.adobeaem.workers.dev/ NOT in this repo (dashboard-edited Worker)

The interstitial only covers the root URL. / returns 403 Suspected Phishing | Cloudflare, but /docs/ and /tools/rum/explorer.html still return 200 with full aem.live content.

Root cause

handleRequest handles /tools/rum/_ogimage* and /tools/rum/_cors* itself. It proxies every other path to main--helix-website--adobe.aem.live, and only adds the RUM Explorer og:* meta on /tools/rum/explorer.html. So https://rum-proxy-*.adobeaem.workers.dev/, /docs/, etc. serve a full Adobe-branded copy of www.aem.live on a workers.dev host. That is the pattern phishing scanners flag.

Change

  • fix(security): requests whose path does not start with /tools/rum/ now get 301 Location: https://www.aem.live<path><query> with an empty body. The aem.live origin is never contacted for those paths. Everything under /tools/rum/ behaves exactly as before: the explorer og:* rewrite, _ogimage, _cors, and the other /tools/rum/ assets are still proxied.

Routing finding (why a redirect is safe, not a loop)

A 301 to www.aem.live would loop if www.aem.live's CDN sent non-/tools/rum/ paths to this Worker. I checked read-only, on 2026-10-05, using response headers that only the Worker path produces on www.aem.live (Worker responses carry the Cloudflare nel/report-to headers and a single via: 1.1 varnish; origin responses carry via: 1.1 varnish, 1.1 varnish):

www.aem.live path Served by Evidence
/, /docs/, /developer/tutorial, /scripts/scripts.js, /favicon.ico, /robots.txt aem.live origin two varnish hops, no nel
/tools/, /tools/rum, /tools/rum-, /tools/rumx, /tools/rumexplorer.html, /tools/oversight/explorer.html aem.live origin two varnish hops, no nel
/TOOLS/rum/_cors aem.live origin prefix match is case-sensitive
/tools/rum/, /tools/rum/explorer.html, /tools/rum/elements/list-facet.js, /tools/rum/nonexistent Worker one varnish hop + nel
/tools/rum/_cors Worker 400, x-error: invalid url (origin direct: 404)
/tools/rum/_ogimage Worker 400, x-error: missing domain or view (origin direct: 404)

So the CDN in front of www.aem.live (Fastly/varnish) sends exactly the case-sensitive prefix /tools/rum/ to the Worker. That is the same prefix the new guard keeps. A redirected request therefore always lands on a path that www.aem.live serves from the origin, so it cannot come back to the Worker. Dot-segment paths such as /tools/rum/%2e%2e/docs/ are forwarded to the Worker but normalised by WHATWG URL parsing to /tools/docs/, and they redirect to that origin-served path. A code search for rum-proxy-prod across org:adobe finds only this repo, so the CDN config is not in a public adobe repo. The finding above rests on the response headers alone.

A plain 404 would also be safe. I chose the redirect so that any old links to the workers.dev hostnames still reach the real site.

Pre-existing CI failure (separate commit)

  • chore(deps): main has been red since chore(deps): update dependency @adobe/eslint-config-helix to v3 #55 (2026-01-20). That PR bumped @adobe/eslint-config-helix to 3.0.16 in package.json but not in package-lock.json, which still has 2.0.9. 3.x peer-depends on eslint ^9, while eslint is pinned to 8.57.1, so npm install fails with ERESOLVE and every run fails at Test. The main-run log has expired, but the identical failure is in current Renovate runs, e.g. job 111597208900. This PR pins the package back to 2.0.9, matching the lockfile. There is no lockfile change and no other dependency change. Moving to eslint 9 / flat config is left to Renovate.

Testing

  • test/index.test.js: replaced the placeholder with 19 unit tests that stub fetch:
    • non-/tools/rum/ paths (/, /docs/, /developer/tutorial, /tools/rum, /tools/rumx, /tools/, /TOOLS/rum/explorer.html) get a 301 to www.aem.live and make no origin fetch;
    • path and query are preserved;
    • /tools/rum/explorer.html still proxies to main--helix-website--adobe.aem.live and adds escaped og:* tags, and non-ok origin responses pass through;
    • other /tools/rum/ assets are proxied unchanged;
    • _cors returns 400 / 403 / 200 with CORS headers;
    • _ogimage returns 400, the stored image, or the pending 302.
  • Mutation check, run in a local stand-in harness:
    • guard changed to always proxy: 9 tests fail;
    • prefix widened to /tools/: 3 tests fail;
    • query dropped from Location: 1 test fails.
      The guard was restored after each.
  • test/post-deploy.test.js (ci host only, skipped for production):
    • /docs/?x=1 must return a 301 to https://www.aem.live/docs/?x=1 with no HTML body;
    • / must return 301 or 403 (Cloudflare's interstitial answers / before the Worker runs) and must not contain the aem.live page;
    • /tools/rum/_cors must still return the Worker's 400 invalid url.
  • CI: Test passes (19 passing).

CI blocker: Test Deploy (not caused by this PR)

Test Deploy fails at "Branch Deployment", before the post-deploy tests run. Wrangler gets Authentication error [code: 10000] from /accounts/852dfa4ae1b0d579df29be65b986c101/workers/services/rum-proxy-ci, so the CLOUDFLARE_API_TOKEN repo secret is invalid or lacks Workers deploy permission. A re-run failed identically. The last successful workflow run in this repo was on main on 2025-09-15, and the January 2026 branch Test Deploy runs also failed (their logs have expired). The release job deploys through the same token (.releaserc.cjs: deploy:ci, test-postdeploy, deploy:production), so after a merge, the release would also fail until the token is replaced. Someone with Helix-Dev Cloudflare and repo-admin rights needs to issue a new token and update the secret, then re-run this PR's workflow. The post-deploy tests have therefore not been run yet.

Follow-ups (not done here)

  • After this is deployed to ci and prod, request review and removal of the Cloudflare phishing mitigations / abuse reports for rum-proxy-ci and rum-proxy-prod.
  • rum-explorer-og.adobeaem.workers.dev is a dashboard-only Worker (deployed by maxed@adobe.com, 2024-06) and not part of this repo. It should be deleted; that is Max Edell's call.
  • Replace CLOUDFLARE_API_TOKEN (see above).

…ckfile

#55 bumped package.json to 3.0.16 without updating package-lock.json; 3.x
peer-depends on eslint ^9 while eslint is pinned to 8.57.1, so npm install
fails with ERESOLVE and every CI run is red at Test.
The worker proxied every path to main--helix-website--adobe.aem.live, so its
*.workers.dev hostnames served a full Adobe-branded copy of www.aem.live and
were reported as phishing. Requests outside /tools/rum/ now get a 301 to the
same path and query on https://www.aem.live; /tools/rum/* is unchanged.
Copilot AI balanced review requested due to automatic review settings October 5, 2026 07:59

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

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