Skip to content

Conversation

@ucswift
Copy link
Member

@ucswift ucswift commented Feb 11, 2026

Summary by CodeRabbit

  • Chores
    • Enhanced application loading mechanism with custom protocol handling, differentiating between development and production environments
    • Improved window initialization with proper title display and icon configuration
    • Optimized file serving and asset resolution for production builds through protocol-based routing

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 11, 2026

📝 Walkthrough

Walkthrough

The Electron main process is enhanced to implement custom protocol handling for production environments. Import signature expanded to include protocol and net from Electron. Development continues loading via HTTP localhost, while production now uses a custom app:// protocol with file serving from the dist directory.

Changes

Cohort / File(s) Summary
Electron Main Process Configuration
electron/main.js
Expanded imports to include protocol and net modules. Registered privileged app scheme. Enhanced window configuration with title and icon properties. Diverged loading paths: dev uses http://localhost:8081; production loads via app:// protocol. Added protocol handler to serve dist/ files in production.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • RD-T39 Working on electron build #90: Both PRs modify electron/main.js's app startup and resource-loading logic for dev vs production scenarios with custom protocol and file handling mechanisms.

Poem

🐰 A protocol, custom and bright,
Serves the dist files just right,
Dev hops on localhost's floor,
Prod through app:// opens the door,
Electron runs smoother tonight! 🚀

🚥 Pre-merge checks | ✅ 1 | ❌ 2
❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title is vague and uses uncertain language ('Trying to fix') that doesn't clearly convey the specific technical changes being made. Replace with a more descriptive title that clearly states the main change, such as 'Add custom app:// protocol support for production builds' or 'Set up protocol-based file serving for Electron production mode'.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch develop

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@electron/main.js`:
- Around line 61-75: The protocol handler for protocol.handle('app') currently
builds filePath from requestUrl.pathname and joins it with distPath allowing
path traversal; fix by resolving the candidate path using path.resolve(distPath,
filePath) (or similar) into a variable like fullPath and verify that fullPath
starts with the resolved distPath (e.g., path.resolve(distPath) as a prefix)
before calling net.fetch; if the check fails, return an error response (or a
404) instead of reading the file. Ensure you update the logic around filePath,
fullPath, distPath and protocol.handle to perform the resolve-and-validate step
to confine requests to dist/.
🧹 Nitpick comments (1)
electron/main.js (1)

34-36: Disabling contextIsolation and webSecurity in dev is risky.

While these settings are safe in production (nodeIntegration: false, contextIsolation: true, webSecurity: true), in dev mode the renderer gets full Node access with no context isolation and disabled web security. If the dev server ever loads untrusted content (e.g., a third-party script, an ad, or even a compromised localhost resource), it can access the full Node.js API.

Consider keeping contextIsolation: true in all modes and communicating with the main process via ipcRenderer through the preload script. This would also make dev behavior closer to prod, reducing surprises.

Comment on lines +61 to +75
if (!isDev) {
const distPath = path.join(__dirname, '../dist');
protocol.handle('app', (request) => {
const requestUrl = new URL(request.url);
let filePath = decodeURIComponent(requestUrl.pathname);

// Normalize the path: remove leading slashes/dots
filePath = filePath.replace(/^\/+/, '');
if (!filePath || filePath === '.' || filePath === './') {
filePath = 'index.html';
}

const fullPath = path.join(distPath, filePath);
return net.fetch(url.pathToFileURL(fullPath).toString());
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Path traversal vulnerability — the protocol handler does not confine requests to dist/.

filePath is derived from the request URL's pathname and only has leading slashes stripped. A request such as app://./../../etc/passwd will resolve to a path outside distPath because path.join happily resolves .. segments. Since the scheme has supportFetchAPI: true, any JS running in the renderer (including via an XSS vector) can fetch() arbitrary local files.

Add a check that the resolved path stays within the dist/ directory:

🔒 Proposed fix to prevent path traversal
         const distPath = path.join(__dirname, '../dist');
         protocol.handle('app', (request) => {
             const requestUrl = new URL(request.url);
             let filePath = decodeURIComponent(requestUrl.pathname);

             // Normalize the path: remove leading slashes/dots
             filePath = filePath.replace(/^\/+/, '');
             if (!filePath || filePath === '.' || filePath === './') {
                 filePath = 'index.html';
             }

-            const fullPath = path.join(distPath, filePath);
+            const fullPath = path.resolve(distPath, filePath);
+
+            // Prevent path traversal outside dist/
+            if (!fullPath.startsWith(distPath + path.sep) && fullPath !== distPath) {
+                return new Response('Forbidden', { status: 403 });
+            }
+
             return net.fetch(url.pathToFileURL(fullPath).toString());
         });
🤖 Prompt for AI Agents
In `@electron/main.js` around lines 61 - 75, The protocol handler for
protocol.handle('app') currently builds filePath from requestUrl.pathname and
joins it with distPath allowing path traversal; fix by resolving the candidate
path using path.resolve(distPath, filePath) (or similar) into a variable like
fullPath and verify that fullPath starts with the resolved distPath (e.g.,
path.resolve(distPath) as a prefix) before calling net.fetch; if the check
fails, return an error response (or a 404) instead of reading the file. Ensure
you update the logic around filePath, fullPath, distPath and protocol.handle to
perform the resolve-and-validate step to confine requests to dist/.

@ucswift
Copy link
Member Author

ucswift commented Feb 11, 2026

Approve

Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR is approved.

@ucswift ucswift merged commit 99a6443 into master Feb 11, 2026
11 of 12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant