Restrict permission handler to app origin

Address review feedback on PR #845: the previous permissive fallthrough
granted every permission request/check that hit the default session,
which the in-app OAuth flow uses too. That meant remote OAuth pages
(accounts.google.com, login.microsoftonline.com, ...) could be auto-
approved for camera, microphone, geolocation, notifications, etc.

Gate the handler on the requesting origin: only the app's own renderer
(app://netcatty plus the dev server in dev) gets the local-fonts grant
and the prior approve-by-default behavior. Anything loaded from a
third-party origin is denied outright.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
bincxz
2026-04-28 08:12:26 +08:00
parent 9863c86d53
commit 975ca7e8ef
+39 -6
View File
@@ -1079,21 +1079,54 @@ if (!gotLock) {
registerAppProtocol();
// Grant the Local Font Access API (queryLocalFonts) for the app's own
// session so the terminal font picker can enumerate user-installed
// monospace fonts (Nerd Font variants etc.). The fallback browser uses
// an isolated partition and is not affected.
// origin so the terminal font picker can enumerate user-installed
// monospace fonts (Nerd Font variants etc.). In-app OAuth pop-ups for
// third-party providers also share the default session, so non-app
// origins must NOT inherit this grant — deny everything else for them.
try {
const defaultSession = session?.defaultSession;
if (defaultSession) {
defaultSession.setPermissionRequestHandler((_wc, permission, callback) => {
const allowedOrigins = new Set(["app://netcatty"]);
if (effectiveDevServerUrl) {
try {
allowedOrigins.add(new URL(effectiveDevServerUrl).origin);
} catch {
// ignore malformed dev server URL
}
}
const isAppOrigin = (rawUrl) => {
if (!rawUrl) return false;
try {
return allowedOrigins.has(new URL(String(rawUrl)).origin);
} catch {
return false;
}
};
defaultSession.setPermissionRequestHandler((wc, permission, callback, details) => {
const requestingUrl =
details?.requestingUrl ||
(typeof wc?.getURL === "function" ? wc.getURL() : "");
if (!isAppOrigin(requestingUrl)) {
callback(false);
return;
}
if (permission === "local-fonts") {
callback(true);
return;
}
// Preserve Electron's prior (no-handler) permissive default for
// the app's own renderers — installing a handler replaces that
// default, and tightening it here is out of scope for this fix.
callback(true);
});
defaultSession.setPermissionCheckHandler((_wc, permission) => {
if (permission === "local-fonts") return true;
defaultSession.setPermissionCheckHandler((wc, permission, requestingOrigin, details) => {
const url =
requestingOrigin ||
details?.requestingUrl ||
(typeof wc?.getURL === "function" ? wc.getURL() : "");
if (!isAppOrigin(url)) return false;
return true;
});
}