Theseus 0.3.123 (cont'd): Shield + Cookie Pop-ups now apply to sidebar AI panels

Shield (adblocker) already ran in the sidebar — it hooks the default
session's webRequest, so any WebContentsView on that session got the same
filter as a tab. Cookie Pop-ups (consent) didn't: the add-on-inject
preload asks main which scripts to run, and the gate required the sender
to be a web tab. Sidebar panels aren't in `tabs`, so sites loaded in the
sparkle-opened AI panel (and quick-link apps like WhatsApp, Telegram)
still showed every consent banner.

Fix is in injectionsForSender (and addon-page-msg for the inject's
round-trip back): also accept quickPanel.webContents and leftPanel's
sender as a "page" for the purpose of page-inject add-ons. The scripts
still see only the URL — nothing panel-specific — so no new attack
surface is opened; everything on the user's enabled page-inject list
runs on the same origins there as it does in a tab.
This commit is contained in:
Local Dev 2026-10-27 21:05:05 +02:00
parent fb3fa84d15
commit 1d4e85f1d2

21
main.js
View file

@ -7646,8 +7646,14 @@ ipcMain.on("wiz-link", (e, uri) => {
});
ipcMain.handle("addon-page-msg", async (e, addonId, msg, payload) => {
// Sidebar panels (quickPanel, leftPanel) count as pages for inject
// round-trips too — see injectionsForSender for the same gate.
const tab = tabForSender(e.sender);
if (!tab || !addonHost) throw new Error("not a page");
const isPanel = !tab && (
(quickPanel && e.sender === quickPanel.webContents) ||
(leftPanel && e.sender === leftPanel.webContents)
);
if ((!tab && !isPanel) || !addonHost) throw new Error("not a page");
// Only the tab's top-level document speaks for its origin. The inject
// preload runs in the main frame alone, so a message from any other frame
// did not come through it — and it would be credited with the top-level
@ -7672,14 +7678,23 @@ ipcMain.handle("addon-page-msg", async (e, addonId, msg, payload) => {
// Assigning event.returnValue sends the reply at once, so it is set exactly
// once at the end.
function injectionsForSender(e, href) {
// Normally the sender must be a web tab. Sidebar panels (the sparkle-opened
// AI chat, the quick-link apps like Telegram/WhatsApp) are not in `tabs`
// but DO load third-party origins, so cookie-consent rules, page-inject
// wallets and friends should run there too — otherwise the AI panel in
// the strip shows every consent banner the matching tab wouldn't.
const tab = tabForSender(e.sender);
if (!tab || !addonHost) return [];
const isPanel = !tab && (
(quickPanel && e.sender === quickPanel.webContents) ||
(leftPanel && e.sender === leftPanel.webContents)
);
if ((!tab && !isPanel) || !addonHost) return [];
const url = e.sender.getURL();
if (!url || url.startsWith("file:")) return [];
if (href && href !== url) console.log(`[addons] inject: preload href ${href} ≠ committed ${url}`);
const origin = pageOriginOf(url);
const list = addonHost.injectionsFor(url).map((x) => ({ ...x, origin }));
if (list.length) console.log(`[addons] inject ${list.map((x) => x.id).join(",")} into ${origin}`);
if (list.length) console.log(`[addons] inject ${list.map((x) => x.id).join(",")} into ${origin}${isPanel ? " (sidebar panel)" : ""}`);
return list;
}
ipcMain.on("addon-inject-scripts", (e, href) => { e.returnValue = injectionsForSender(e, href); });