Restore explicit consent boundaries for embedded Browser2 capture permissions

Browser2 tabs should not inherit the app-wide media/display-capture auto-approval path. This change keeps the default session behavior intact while narrowing the embedded browser session to clipboard-only permissions and denying automatic display-source selection there.

Constraint: Browser2 work is currently flowing through the dev branch and needs a minimal, low-risk patch
Rejected: Remove session permission handling entirely | could break existing app-level capture flows outside Browser2
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: If Browser2 later needs media or display capture, add an explicit per-origin/user approval flow instead of widening the shared allowlist
Tested: pnpm install; pnpm run deps; apps/main npm run build; source-backed permission validation JSON
Not-tested: Manual interactive Electron permission prompt UX
This commit is contained in:
JunghwanNA 2026-04-18 00:44:34 +09:00
parent 50df9ed178
commit b979bddf48

View file

@ -116,21 +116,26 @@ protocol.registerSchemesAsPrivileged([
},
]);
const ALLOWED_SESSION_PERMISSIONS = new Set(["media", "display-capture", "clipboard-read", "clipboard-sanitized-write"]);
const APP_SESSION_PERMISSIONS = new Set(["media", "display-capture", "clipboard-read", "clipboard-sanitized-write"]);
const BROWSER_SESSION_PERMISSIONS = new Set(["clipboard-read", "clipboard-sanitized-write"]);
function configureSessionPermissions(targetSession: Session): void {
function configureSessionPermissions(targetSession: Session, allowedPermissions: Set<string>): void {
targetSession.setPermissionCheckHandler((_webContents, permission) => {
return ALLOWED_SESSION_PERMISSIONS.has(permission);
return allowedPermissions.has(permission);
});
targetSession.setPermissionRequestHandler((_webContents, permission, callback) => {
callback(ALLOWED_SESSION_PERMISSIONS.has(permission));
callback(allowedPermissions.has(permission));
});
// Auto-approve display media requests and route system audio as loopback.
// Electron requires a video source in the callback even if we only want audio.
// We pass the first available screen source; the renderer discards the video track.
// Only sessions that explicitly allow display-capture should receive an
// auto-approved source. Embedded browser tabs use a separate session with a
// narrower permission set.
targetSession.setDisplayMediaRequestHandler(async (_request, callback) => {
if (!allowedPermissions.has("display-capture")) {
callback({});
return;
}
const sources = await desktopCapturer.getSources({ types: ['screen'] });
if (sources.length === 0) {
callback({});
@ -159,8 +164,8 @@ function createWindow() {
},
});
configureSessionPermissions(session.defaultSession);
configureSessionPermissions(session.fromPartition(BROWSER_PARTITION));
configureSessionPermissions(session.defaultSession, APP_SESSION_PERMISSIONS);
configureSessionPermissions(session.fromPartition(BROWSER_PARTITION), BROWSER_SESSION_PERMISSIONS);
// Show window when content is ready to prevent blank screen
win.once("ready-to-show", () => {