From b49a970d615b0f0c7b554e9360655ee15d317e9a Mon Sep 17 00:00:00 2001 From: FunctionFreak Date: Sat, 24 Oct 2026 16:50:16 +0100 Subject: [PATCH] Take the page's scan result from frame 0 only A frame of another origin learns its path from the frame that read the document it sits in, over postMessage, and the page's own scripts can see and answer that message too. A page lying to one of its frames could hand it the path "0", and the worker took the page's result by that path alone, last writer winning, so that frame's records would have replaced the whole page in the scan. The page's result now comes only from frame 0, an id Chrome sets. Any other made-up path was never used: frames are taken from the kids list of the frame that read them. The fallback reader for pages the extension cannot script already returns the page as frame 0. --- AutoCua/web/browser/AutoCuaBridge/element.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/AutoCua/web/browser/AutoCuaBridge/element.js b/AutoCua/web/browser/AutoCuaBridge/element.js index 8b0f4e5..a54b11f 100644 --- a/AutoCua/web/browser/AutoCuaBridge/element.js +++ b/AutoCua/web/browser/AutoCuaBridge/element.js @@ -1320,11 +1320,15 @@ async function elementScan(tab, opts = {}) { if (failure) throw new Error(`scan failed: ${(failure && failure.message) || failure}`); // One result per frame Chrome could inject into; same-origin children answered - // {covered} and were read by their parent. + // {covered} and were read by their parent. The page's own result is the one from + // frame 0, an id Chrome sets: a frame handed the path "0" by a page lying to it + // (its hello is a message the page's own scripts can answer too) must not take + // the page's place. Any other made-up path is never used, since frames are only + // taken from the kids list of the frame that read them. const byPath = new Map(); for (const r of results) { const v = r && r.result; - if (v && v.path) byPath.set(v.path, v); + if (v && v.path && (v.path !== "0" || r.frameId === 0)) byPath.set(v.path, v); } const top = byPath.get("0"); if (!top || !top.recs) throw new Error(`scan failed: ${top && top.error ? top.error : "no result from the page"}`);