fix(core): don't serve in-page POST/unsafe requests from the discovery cache#2325
Open
Sriram567 wants to merge 1 commit into
Open
fix(core): don't serve in-page POST/unsafe requests from the discovery cache#2325Sriram567 wants to merge 1 commit into
Sriram567 wants to merge 1 commit into
Conversation
…y cache Asset-discovery's request interception serves cached responses keyed on URL only, ignoring the HTTP method. An in-page POST to a URL that was already fetched via GET (e.g. a login form submitted from an `execute` script) was answered from the cached GET body and never reached the origin — so the request never authenticated, no session cookie was set, and the snapshot captured unauthenticated content. Only serve cached resources for safe, cacheable methods (GET/HEAD). POST/PUT/ PATCH/DELETE (or an absent method) now fall through to a real origin request. Fixes PER-9766. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes PER-9766 — PSE team can't snapshot pages behind form authentication.
Root cause
Asset-discovery's request interception serves cached responses keyed on URL only, ignoring the HTTP method:
packages/core/src/discovery.js:463—lookupCacheResourcekeys purely on URL (snapshotResources.get(url) || cache.get(url)).packages/core/src/network.js(sendResponseResource) — fulfils any cached resource viaFetch.fulfillRequestregardless ofrequest.method.A customer logging in from an
executescript did:The login POST went to the site root, which had already been captured (GET) and cached during navigation. Discovery answered the POST from that cached login-page body, so it never reached the origin — no session was established, and the follow-up
/my-accountfetch returned unauthenticated content thatdocument.writethen captured.Debug-log proof:
Evaluate JavaScript→Handling request: https://…/(the POST) →- Resource cache hit→/my-accountfetched unauthenticated →Snapshot taken.Fix
Only serve cached resources for safe, cacheable methods (GET/HEAD). POST/PUT/PATCH/DELETE (or an absent method) fall through to
Fetch.continueRequest→ origin. Answering a state-changing request with a cached GET body is incorrect in general; page navigation and asset fetches are GET, so normal snapshotting is unaffected.Testing
Added
discovery.test.js› resource caching › "serves cached resources only for cacheable methods (PER-9766)": caches an asset on the initial GET, then issues a POST to the same URL from anexecutescript and asserts the origin sees the POST (i.e. it is not served from cache). Verified the spec fails without the fix (Expected ['GET'] to contain 'POST') and passes with it.Review notes
This touches core discovery interception (100%-coverage gate). The new
cacheableMethodbranch is exercised by the GET+POST test. Worth a prod-replay sanity check, though the only behavior change is: an unsafe-method request whose URL happens to be cached now hits the origin instead of replaying a GET body.🤖 Generated with Claude Code