Security and quality

Restrict navigation and new windows

Prevent the notes window from navigating away or creating an unexpected BrowserWindow.

8 minute lesson

~~~

Desktop Notes loads one bundled interface. It does not need page navigation or renderer-created windows, so deny both:

win.webContents.on('will-navigate', event => {
  event.preventDefault()
})

win.webContents.setWindowOpenHandler(() => ({
  action: 'deny'
}))

If you later add an external documentation link, intercept it in the main process:

const { shell } = require('electron')

win.webContents.setWindowOpenHandler(({ url }) => {
  const target = new URL(url)

  if (
    target.protocol === 'https:' &&
    target.hostname === 'docs.desktop-notes.test'
  ) {
    void shell.openExternal(target.href)
  }

  return { action: 'deny' }
})

Parse the URL and compare exact protocol and hostname values. A startsWith() check can accept attacker-controlled hosts that merely begin with trusted text.

Never pass an unchecked string to shell.openExternal(). Protocol handlers can do more than open web pages.

Keep the restrictive content security policy in index.html. Avoid inline scripts because they require weakening script-src.

Test a normal click, window.open(), a link with target="_blank", and a form navigation. Include confusing URLs such as https://docs.desktop-notes.test.attacker.invalid and a non-HTTP protocol. Only the exact allowlisted link should leave the app.

Lesson completed

Take this course offline

Get every free book and course as PDF and EPUB files.

Get the download library →