aboutsummaryrefslogtreecommitdiffstats
path: root/packages
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2021-12-25 00:52:49 +0100
committerLibravatar Kristóf Marussy <kristof@marussy.com>2021-12-25 00:52:49 +0100
commit9f0cd0d2c312519b8741ad557cd514ab1921eeb0 (patch)
tree20b586a95576b74984e57901691e9dc481124658 /packages
parentrefactor: Simplify script injection (diff)
downloadsophie-9f0cd0d2c312519b8741ad557cd514ab1921eeb0.tar.gz
sophie-9f0cd0d2c312519b8741ad557cd514ab1921eeb0.tar.zst
sophie-9f0cd0d2c312519b8741ad557cd514ab1921eeb0.zip
feat: Harden window navigation and permissions
Diffstat (limited to 'packages')
-rw-r--r--packages/main/src/index.ts60
1 files changed, 55 insertions, 5 deletions
diff --git a/packages/main/src/index.ts b/packages/main/src/index.ts
index 0c0a585..09441ef 100644
--- a/packages/main/src/index.ts
+++ b/packages/main/src/index.ts
@@ -84,8 +84,9 @@ function getResourcePath(relativePath: string): string {
84 return join(__dirname, relativePath); 84 return join(__dirname, relativePath);
85} 85}
86 86
87const baseUrl = `file://${__dirname}`;
87function getResourceUrl(relativePath: string): string { 88function getResourceUrl(relativePath: string): string {
88 return new URL(relativePath, `file://${__dirname}`).toString(); 89 return new URL(relativePath, baseUrl).toString();
89} 90}
90 91
91let serviceInjectRelativePath = '../../service-inject/dist/index.cjs'; 92let serviceInjectRelativePath = '../../service-inject/dist/index.cjs';
@@ -103,6 +104,33 @@ let mainWindow: BrowserWindow | null = null;
103 104
104const store = createRootStore(); 105const store = createRootStore();
105 106
107const rendererBaseUrl = getResourceUrl('../renderer/');
108function shouldCancelMainWindowRequest(url: string, method: string): boolean {
109 if (method !== 'GET') {
110 return true;
111 }
112 let normalizedUrl: string;
113 try {
114 normalizedUrl = new URL(url).toString();
115 } catch (_err) {
116 return true;
117 }
118 if (normalizedUrl.startsWith('devtools:')) {
119 return false;
120 }
121 if (isDevelopment) {
122 if (normalizedUrl.startsWith('chrome-extension:')) {
123 return false;
124 }
125 if (import.meta.env.VITE_DEV_SERVER_URL !== undefined) {
126 const isHttp = normalizedUrl.startsWith(import.meta.env.VITE_DEV_SERVER_URL);
127 const isWs = normalizedUrl.startsWith(import.meta.env.VITE_DEV_SERVER_URL.replace(/^http:/, 'ws:'));
128 return !isHttp && !isWs;
129 }
130 }
131 return !normalizedUrl.startsWith(getResourceUrl(rendererBaseUrl));
132}
133
106function createWindow(): Promise<unknown> { 134function createWindow(): Promise<unknown> {
107 mainWindow = new BrowserWindow({ 135 mainWindow = new BrowserWindow({
108 show: false, 136 show: false,
@@ -112,6 +140,26 @@ function createWindow(): Promise<unknown> {
112 }, 140 },
113 }); 141 });
114 142
143 const { webContents } = mainWindow;
144
145 webContents.userAgent = originalUserAgent;
146
147 webContents.session.setPermissionRequestHandler((_webContents, _permission, callback) => {
148 callback(false);
149 });
150
151 webContents.session.webRequest.onBeforeRequest(({ url, method }, callback) => {
152 callback({
153 cancel: shouldCancelMainWindowRequest(url, method),
154 })
155 });
156
157 webContents.on('will-navigate', (event) => {
158 event.preventDefault();
159 });
160
161 webContents.setWindowOpenHandler(() => ({ action: 'deny' }));
162
115 if (isDevelopment) { 163 if (isDevelopment) {
116 openDevToolsWhenReady(mainWindow); 164 openDevToolsWhenReady(mainWindow);
117 } 165 }
@@ -120,10 +168,6 @@ function createWindow(): Promise<unknown> {
120 mainWindow?.show(); 168 mainWindow?.show();
121 }); 169 });
122 170
123 const { webContents } = mainWindow;
124
125 webContents.userAgent = originalUserAgent;
126
127 const browserView = new BrowserView({ 171 const browserView = new BrowserView({
128 webPreferences: { 172 webPreferences: {
129 sandbox: true, 173 sandbox: true,
@@ -198,6 +242,12 @@ function createWindow(): Promise<unknown> {
198 } 242 }
199 }); 243 });
200 244
245 browserView.webContents.session.setPermissionRequestHandler(
246 (_webContents, _permission, callback) => {
247 callback(false);
248 }
249 );
250
201 browserView.webContents.session.webRequest.onBeforeSendHeaders(({ url, requestHeaders }, callback) => { 251 browserView.webContents.session.webRequest.onBeforeSendHeaders(({ url, requestHeaders }, callback) => {
202 if (url.match(/^[^:]+:\/\/accounts\.google\.[^.\/]+\//)) { 252 if (url.match(/^[^:]+:\/\/accounts\.google\.[^.\/]+\//)) {
203 requestHeaders['User-Agent'] = chromelessUserAgent; 253 requestHeaders['User-Agent'] = chromelessUserAgent;