Skip to content

Commit 9f5dfb5

Browse files
committed
Validate protocol of opened external URLs
Not aware of any way that somebody could XSS a dangerous external URL into the app invisibly, but it's good to protect against that possibility I think.
1 parent 4de0ada commit 9f5dfb5

File tree

1 file changed

+27
-15
lines changed

1 file changed

+27
-15
lines changed

src/index.ts

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -202,24 +202,36 @@ if (!amMainInstance) {
202202
});
203203

204204
// Redirect all navigations & new windows to the system browser
205-
contents.on('will-navigate', (event, navigationUrl) => {
206-
const parsedUrl = new URL(navigationUrl);
205+
contents.on('will-navigate', handleNavigation);
206+
contents.on('new-window', handleNavigation);
207+
});
207208

208-
if (parsedUrl.origin !== APP_URL) {
209-
event.preventDefault();
210-
shell.openExternal(navigationUrl);
211-
}
212-
});
209+
function handleNavigation(event: Electron.Event, navigationUrl: string) {
210+
const parsedUrl = new URL(navigationUrl);
213211

214-
contents.on('new-window', (event, navigationUrl) => {
215-
const parsedUrl = new URL(navigationUrl);
212+
checkForUnsafeNavigation(parsedUrl);
216213

217-
if (parsedUrl.origin !== APP_URL) {
218-
event.preventDefault();
219-
shell.openExternal(navigationUrl);
220-
}
221-
});
222-
});
214+
if (!isLocalNavigation(parsedUrl)) {
215+
event.preventDefault();
216+
handleExternalNavigation(parsedUrl);
217+
}
218+
}
219+
220+
function checkForUnsafeNavigation(url: URL) {
221+
if (url.protocol !== 'http:' && url.protocol !== 'https:') {
222+
// This suggests an attempted XSS attack of some sort, report it:
223+
const error = new Error(`Attempt to open a dangerous non-HTTP url: ${url}`);
224+
throw error;
225+
}
226+
}
227+
228+
function isLocalNavigation(url: URL) {
229+
return url.origin === APP_URL;
230+
}
231+
232+
function handleExternalNavigation(url: URL) {
233+
shell.openExternal(url.toString());
234+
}
223235

224236
function showErrorAlert(title: string, body: string) {
225237
console.warn(`${title}: ${body}`);

0 commit comments

Comments
 (0)