Is Web Maker safe?
Web Maker syncs user code to Firebase and a multiplayer backend, and sends behavioral telemetry to a Google Cloud Run endpoint.
When a user is logged in, Web Maker automatically saves their HTML, CSS, and JavaScript workspace to Google Firestore under the project 'web-maker-app'. During multiplayer collaboration sessions, the full editor content is streamed keystroke-by-keystroke over a WebSocket to a Railway-hosted backend. Separately, the extension tracks approximately 80 categories of user interactions—including settings changes, keyboard shortcuts, and login events—and forwards them as JSON to a Google Cloud Run endpoint.
Who publishes itKushagra Gour - no other listings under this identity, 6 shared hostnames
Kushagra Gour - no other listings under this identity, 6 shared hostnames
What this publisher told the store about itself, and the other listings that told it the same thing.
Shared hosts - 6 hostnames
Hostnames hardcoded in this extension that few other listings call. That can mean one operator behind both, and it can equally mean a small shared vendor, so it is context rather than a conclusion. Hosts that many listings call are left out: they are services, not connections.
AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.
Publishers can request a review.
Findings
Code syncs to WebSocket during collaboration
Starting or joining a Web Maker multiplayer session places the editor's HTML, CSS, and JS into a Yjs doc connected to web-maker-backend-production.up.railway.app over WebSocket.
Edits are sent as binary Yjs update frames for that room.
- Severity
- Medium unwanted
- Type
- Unexpected
- CWE
- CWE-319
- Source
- Dynamic sandbox
You start a multiplayer collaboration session or open a shared collaboration link.
The extension connects your editor document to a remote WebSocket room and syncs the project code for that session.
- Editor HTML<main class="demo"><button id="save">Save</button></main>
Your page structure is included in the collaboration room when the session starts.
- Editor CSS.demo { display: grid; gap: 12px; color: #243b53; }
Your styling rules are included alongside the HTML so collaborators can see and edit them.
- Editor JavaScriptdocument.querySelector('#save').addEventListener('click', saveDraft);
Your script content is part of the shared room and can include logic you are actively developing.
- Room identifierA7kP2zQ9
The room value separates one collaboration session from another and is included in the WebSocket path.
- Collaboration display identitySwift Panda / #1E88E5
The session broadcasts a generated display name and color for cursor presence.
WebSocket upgrade; subsequent messages are binary Yjs sync, awareness, and update frames.
The shipped bundle creates a WebSocket-backed Yjs room from the current project code
Readable production endpoint constant
constants.js// Multiplayer collaboration server URL// For development: npm run start:collab (runs on ws://localhost:4444)// For production: Deploy collab-server/ to Railway and update the URL belowexport const COLLAB_SERVER_URL = window.location.hostname === 'localhost' ? 'ws://localhost:4444' : 'wss://web-maker-backend-production.up.railway.app';Readable createSession function from the source map
multiplayerService.jsexport function createSession(initialContent = { html: '', css: '', js: '' }) { const roomId = generateRoomId(); const ydoc = new Y.Doc(); // Initialize Y.Text instances with current content const yHtml = ydoc.getText('html'); const yCss = ydoc.getText('css'); const yJs = ydoc.getText('js'); // Insert initial content into Y.Text if (initialContent.html) { yHtml.insert(0, initialContent.html); } if (initialContent.css) { yCss.insert(0, initialContent.css); } if (initialContent.js) { yJs.insert(0, initialContent.js); } // Connect to WebSocket server const provider = new WebsocketProvider(COLLAB_SERVER_URL, roomId, ydoc); // Set up local user awareness const userIdentity = generateUserIdentity(); provider.awareness.setLocalStateField('user', userIdentity); // Update URL with room ID addRoomIdToUrl(roomId); return { ydoc, provider, awareness: provider.awareness, roomId, url: generateSessionUrl(roomId), userIdentity, isHost: true };}The editors are bound to Yjs text objects, so edits become sync updates
Readable ContentWrap editor bindings
components/ContentWrap.jsxyText={ this.props.multiplayerSession?.ydoc?.getText('html') || null}awareness={this.props.multiplayerSession?.awareness || null}yText={ this.props.multiplayerSession?.ydoc?.getText('css') || null}awareness={this.props.multiplayerSession?.awareness || null}yText={ this.props.multiplayerSession?.ydoc?.getText('js') || null}awareness={this.props.multiplayerSession?.awareness || null}Readable CodeEditor Yjs binding setup
components/CodeEditor.jsxasync setupYjsBinding(yText, awareness) { // Destroy existing binding first this.destroyYjsBinding(); if (!yText || !awareness) { return; } await this.editorReadyDeferred.promise; if (this.props.type === 'monaco') { // Dynamically load y-monaco if not loaded if (!MonacoBinding) { const yMonacoModule = await import('y-monaco'); MonacoBinding = yMonacoModule.MonacoBinding; } this.yjsBinding = new MonacoBinding( yText, this.instance.getModel(), new Set([this.instance]), awareness ); } else { // CodeMirror 5 binding this.yjsBinding = new CodemirrorBinding(yText, this.instance, awareness); }}Readable y-websocket update handler
node_modules/y-websocket/src/y-websocket.jsthis._updateHandler = (update, origin) => { if (origin !== this) { const encoder = encoding.createEncoder() encoding.writeVarUint(encoder, messageSync) syncProtocol.writeUpdate(encoder, update) broadcastMessage(this, encoding.toUint8Array(encoder)) }}this.doc.on('update', this._updateHandler)At session start
You didYou start a new collaboration room.
The extension didThe extension creates an 8-character room ID and inserts the current HTML, CSS, and JavaScript into the shared document.
During editing
You didYou type in the HTML, CSS, or JavaScript editor while the session is active.
The extension didThe Yjs binding updates the shared document, and the WebSocket provider sends a binary update for the room.
On share
You didYou copy or share the collaboration link.
The extension didThe link includes the room parameter so another browser can join the same shared document.
- web-maker-backend-production.up.railway.app
Railway-hosted WebSocket endpoint that receives the room connection and binary Yjs collaboration updates.
What it can do
Permissions this extension asks for, as declared in version 6.9.0. Asking for a permission is not a finding on its own - it is what the extension can do if it chooses to.
Read and change your data on every site you visit
<all_urls>
Store data in your browser
storage
See the address and title of every tab you have open
tabs
Run hidden pages in the background
offscreen
Where it sends data
Destinations our analysis observed Web Maker contacting. Sending data somewhere is not a finding on its own - an extension that syncs your settings has to talk to its own server - but it is where your data can go, and who else it goes to.
- firestore.googleapis.com
Web Maker sends data to firestore.googleapis.com. 16 other extensions we have analysed send data here.
- event-ajhkrtmkaq-uc.a.run.app
Web Maker sends data to event-ajhkrtmkaq-uc.a.run.app. No other extension we have analysed sends data here.
- web-maker-backend-production.up.railway.app
Web Maker sends data to web-maker-backend-production.up.railway.app. No other extension we have analysed sends data here.