fiddle

Activity, over time

Daily observations from the public event archive.

Attention

Daily stars & forks

Loading attention chart

Star accumulation

Cumulative stars

Loading star accumulation chart

Pull requests

Daily opens & merges

Loading pull requests chart

Conversations

Daily issues & comments

Loading conversations chart

Community

Daily accounts & reviews

Loading community chart

Releases

Daily releases

Loading releases chart

Mentions

3posts · 30d
Nov 30 posts
  1. @pranavgawai_ i also did the same for the organization "electron". Initially some good first issues: • fiddle#1687 • fiddle#1688 and then some meaningful contributions: • fiddle-core#138 • fiddle#1695 got good feedback from maintainers. t.co

    1 like · 28 views
  2. DEV · · @taventix

    Read an Electron app's fuses, runtime and ASAR integrity from the release ZIP, without running it Most Electron hardening lives outside your JavaScript. Which Electron, Chromium and Node a build ships, which fuses are flipped, and whether the app.asar is covered by an integrity hash are all decided at packaging time and baked into the binary. You won't see any of it in a code review of main.js. You can read all of it back from the shipped files. Here is what that looks like on two public releases of Electron Fiddle (MIT, the official Electron playground), straight from the macOS release ZIPs on GitHub. Nothing is unpacked by hand and nothing is executed. One command per build npx hexvero analyze Electron.Fiddle-darwin-arm64-0.39.0.zip The relevant part of the output: Runtime Electron 40.8.5 · Chromium 144.0.7559.236 · Node 24.14.0 read from Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework support: Electron 40.8.5 is past its end of support (2026-07-01, from the snapshot of 2026-10-18, as of 2026-10-24); 40.8.5 was released on 2026-03-26 fuses: runAsNode off, cookieEncryption off, nodeOptions off, nodeCliInspect off, embeddedAsarIntegrityValidation off, onlyLoadAppFromAsar on, loadBrowserProcessSpecificV8Snapshot off, grantFileProtocolExtraPrivileges on ASAR integrity: covers the loaded archive Where each line comes from: - Versions. The Electron Framework binary contains the user-agent fragment Chrome/<version> Electron/<version> and Node's release URL. A universal binary holds one copy per architecture, and the value only counts as known if all copies agree. - Fuses. Electron writes them as a small wire right after a fixed sentinel string in the binary: a schema byte, a count byte, then one byte per fuse (0 off, 1 on, r removed). That's the same wire @electron/fuses flips when you package. - ASAR integrity. On macOS this is ElectronAsarIntegrity in Contents/Info.plist: a hash of the archive's header. hexvero hashes the header of the app.asar actually in the bundle and says whether the record covers it. - Support. This compares the version against a dated snapshot of Electron's release data. It doesn't claim anything about vulnerabilities. The detail worth a second look Fiddle's bundle carries an integrity record that matches its app.asar, but the fuse embeddedAsarIntegrityValidation is off. Per Electron's docs, that fuse is what makes Electron check the record when it loads the archive. So the hash ships, but nothing verifies it at startup. Packagers write the record by default; the fuse is opt-in. That isn't a vulnerability claim about Fiddle, which is a developer tool. It's the kind of fact that's invisible unless you read the bundle, and it matters for anything that relies on the archive not being swapped on disk. Trail of Bits' CVE-2025-55305 write-up shows why this area deserves attention: they bypassed ASAR integrity through V8 heap snapshots in Signal, 1Password and Slack. What changed between 0.38.0 and 0.39.0 npx hexvero compare Electron.Fiddle-darwin-arm64-0.38.0.zip Electron.Fiddle-darwin-arm64-0.39.0.zip runtime runtime: 0 added, 0 removed, 3 changed, 12 unchanged · matched by item ~ electron value: "40.1.0" → "40.8.5" ~ chromium value: "144.0.7559.96" → "144.0.7559.236" ~ node value: "24.11.1" → "24.14.0" A patch-level Electron bump, and no fuse moved. The same comparison also covers the app's code, so other collections show what the release actually added: ipc ~ .webpack/renderer/main_window/preload.js::ipcRenderer.invoke::NPM_ADD_MODULES args: "({dir, packageManager}, ...)" → "({dir, packageManager, useSocketFirewall}, ...)" storage + .webpack/renderer/main_window/index.js::localStorage::isUsingSocketFirewall::write endpoints + .webpack/sfw/dist/sfw.mjs::http-client::https://api.github.com/repos/SocketDev/sfw-free/releases/latest That lines up with the release: 0.39.0 added an option to install packages through Socket's firewall. A new field travels over an existing IPC channel, there's a new persisted setting, and a bundled CLI calls GitHub's API. All three are visible from the ZIPs alone. Turn it into a release gate The question that matters at release time is "did this build get weaker than the last one?", not "is this build perfect?". hexvero check has a fuse-weakened rule for exactly that. It fails when a fuse moves to its less safe state (runAsNode, nodeOptions, nodeCliInspect or grantFileProtocolExtraPrivileges turned on; embeddedAsarIntegrityValidation, onlyLoadAppFromAsar or cookieEncryption turned off), when an integrity record stops covering the archive Electron loads, or when the Electron line goes past end of support: npx hexvero init previous/YourApp.app # writes .hexvero/policy.json npx hexvero check previous/YourApp.app dist/YourApp.app --policy .hexvero/policy.json # exit 0 pass, 3 violated, 4 not decidable It writes SARIF if you want the result in GitHub code scanning. The same policy also covers new IPC channels and preload members, more permissive webPreferences, and new external hosts. Limits - It reads bytes and never runs the app. A fuse that's on doesn't prove the behavior it guards is reachable, and a passing check isn't a security verdict. - Linux builds have no integrity record to read. Installers (.dmg, setup .exe, AppImage) need to be installed or unpacked first; .app bundles, install directories and release ZIPs are read as they are. - Anything it can't read is reported as unknown, never silently as "fine". hexvero is open source (MIT): maximilianfeix/hexvero. If it reads something wrong on your own builds, an issue with the output is the most useful feedback I can get. Written with AI assistance. Every command and output above is real, from hexvero 0.11.1 on the official Fiddle release ZIPs, run on 2026-10-24.

  3. DEV · · @ianwieds

    The analysis counted zero bridges. The app exposes 51 methods. --- title: The analysis counted zero bridges. The app exposes 51 methods. published: true published_at: 2026-10-12 11:00 -0700 tags: ai,javascript,opensource,discuss cover_image: beehiiv-images-production.s3.amazonaws.com --- I wanted to know how a desktop app's window talks to its main process. In Electron, that is the first question behind almost every "build me a feature like theirs" job: which calls cross the bridge, and what answers them on the other side. So I handed a shipped app to a reverse-engineering tool and read the summary. Three context bridges. None of them belonged to the app. The tool everyone starred this week REA, short for Reverse Engineer Anything, is an MCP server and CLI that lets a coding agent inspect apps it has no source for. Native binaries go through Hopper, Ghidra or IDA. JavaScript and Electron apps, .NET assemblies, Android packages and websites have their own paths. It was #1 on GitHub trending on Sunday with 25,599 new stars in a day (about 118,000 total, MIT licensed), and its Hacker News thread reached 774 points and 327 comments. The pitch is direct: see a feature you like in someone's app, and have your agent work out how it is built. The npm release, 6.4.0, ships 127 CLI commands (I counted them from --help). Most of those need a native disassembler. The static JavaScript path does not, so that is the one I ran. I skipped rea setup, which registers REA in your agents' MCP configs, and called the CLI through npx in a scratch folder. The run My target was Electron Fiddle 0.39.0, the Electron team's own MIT-licensed playground app. Open source on purpose: I could check every answer against the real code. I downloaded the macOS arm64 zip from its GitHub release, matched its SHA-256 to the digest GitHub publishes, and pulled out only app.asar (21.9 MB). Nothing was installed or launched. npx -y rea-agents@latest analyze-javascript-application /abs/path/app.asar --json > fiddle.json About three minutes later I had 43 MB of JSON. REA inventoried 89 files, parsed 71 JavaScript files and visited 2,386,900 syntax nodes without executing a line of the app. The Electron summary, trimmed: context_bridge_apis: 3 exposed_api_members: 5 ipc.operations: 26 ipc.literal_channels: 11 ipc.dynamic_channel_operations: 6 Every one of those findings is real, and none of them is Fiddle's. The 11 literal channels (clipboard:readText, open-github, get-displays and the rest) come from the example fiddles the app bundles as starter templates, under static/show-me/. The six dynamic channels and the __SENTRY_IPC__ bridge belong to the Sentry SDK. Fiddle's own bridge, window.ElectronFiddle, is not in the counts. Where the answer went It was not silently dropped, and that part deserves full credit. The preload that defines the bridge is a 9,768-byte file. REA parsed it completely, then attached two unknown nodes to it. One says semantic analysis of the file "was not started" because the parent had reserved its remaining result capacity. The other says its relationships exceeded the result budget. The main-process bundle got its own entry: the analyzer worker ran out of its default 1,024 MiB heap there. The graph carries 110 unknown nodes in total, and its coverage field reads partial. REA works through the files in path order, and the preload was number 23 of 89. Ahead of it sat the 2.9 MB main bundle, the 4.9 MB renderer bundle and Monaco's language workers. The small file holding the answer arrived after the budget was gone. Raising the analyzer heap to 4,096 MiB did not help: the run took about 20 minutes instead of 3, the main bundle ran out of heap again, and every count above came back the same. REA's docs describe the fix, a --source-path flag that analyzes only the files you name. It lives on the main branch. The npm release I ran answered Unknown flag: --source-path, and to be fair, the install docs warn that main runs ahead of npm. The one-line experiment So I made the selection by hand. I copied that one preload into its own folder and analyzed it alone. Ten seconds later: zero bridges, zero IPC operations, and this time the graph's coverage read complete. The reason sits in the minified file itself. Webpack does not leave require("electron") where the code uses it. It wraps the require in a numbered module and hands the result out through its own loader: 288(E){E.exports=require("electron")} // ...later in the same file const E=_(288) REA's semantic graph did see the reads of ipcRenderer.send and ipcRenderer.invoke. But it marked the binding E as an unknown value, and REA only treats something as Electron's API when it can prove the alias. So E.contextBridge.exposeInMainWorld(...) never counted as a bridge. The Sentry preload it did catch is a tiny separate file that calls require("electron") directly. I changed one expression in my copy, _(288) to require("electron"), and ran it again: context_bridge_apis: 1 (ElectronFiddle, 51 members, 0 unknown) ipc.operations: 48 ipc.dynamic_channel_operations: 48 Fifty-one members is exactly what Fiddle's src/preload/preload.ts defines; I counted them in the source. All 48 channels stay dynamic (e.IpcEvents.FIDDLE_RUN and so on) because the enum values live in another webpack module, and REA labels each one that way. For contrast, I pointed it at the unbundled source of Electron's archived API demos app. Seventeen seconds, 30 IPC operations over 18 literal channels, and all 12 renderer sends paired with their main-process handlers. On plain code, the static picture is very good. On a production bundle, the gaps open exactly where the bundler inserted its runtime. I could not find an open issue about following Electron through webpack's loader. I did not file one; this was a read-and-run session only. Evidence is a lower bound Here is the rule I would carry into any agent workflow built on a tool like this: a static count is a floor, never a census. "Found 3 bridges" means at least three, with the rest sitting in the unknowns. REA is designed around that idea. Its graph docs store unavailable values explicitly "so absence of evidence cannot silently become evidence of absence". Every dynamic channel and every inferred send-to-handler pairing in my runs carried its own limitation string, and the top-level result repeats that missing findings do not establish absence. The weak link is whoever reads the result. An agent that turns context_bridge_apis: 3 into "the app exposes three APIs" has thrown away the most useful part of the answer. If I put an agent on REA to study a feature, I would make it list every unknown that touches that feature before it writes one conclusion. In my run, that list pointed straight at a 9.8 KB file a person finds in seconds with grep exposeInMainWorld. That is the real shift here. Copying a feature used to start with a guess about how it works. Now it starts with evidence, and evidence comes with a list of what it could not see. Before you try it - It moves very fast. Versions 6.2.0, 6.3.0 and 6.4.0 shipped within about 36 hours, and 130 issues were opened on Oct 11 and 12 (UTC) alone. Issue #1387, still open, records 6.3.0 aborting on a large bundle that 6.2.0 finished; the reporter says 6.4.0 fixed it for them. Pin a version for anything you script. - Setup edits your agent config. It shows a plan, asks for approval and keeps backups. One HN commenter still called the paste-this-prompt install "the next evolution of installation by curl | bash". The CLI works without it. - The legal line is yours. REA's disclaimer rules out DRM bypass and copying proprietary code, and notes that licenses and local law may restrict reverse engineering. I picked an MIT app for that reason. Learning how a feature works and shipping someone else's code are different acts. When your agent reports that an app has none of something, do you make it show you the unknowns, or do you take the zero?

Latest stargazers

The last 10 distinct accounts we observed this year.

Most active participants

PR, issue, comment & review events in the past year.

Packages

Scan pending.

README badges

Embed a badge in your README or website.

  • electron/fiddle reached #3 in daily stars on gitwal · Aug 11, 2018
Live mentions · last 30 days
electron/fiddle mentions in the last 30 days