registry  /  @bobfrankston/rmfmail  /  1.2.130

@bobfrankston/rmfmail@1.2.130

Local-first email client with IMAP sync and standalone native app

AI Security Review

scanned 2h ago · by lpm-firewall-ai

The Android/web mail runtime silently exports verbose diagnostic data to a third-party host. Startup serializes each account's IMAP object, which may include password credentials, and ongoing sync logging exports account identifiers and errors.

Static reason
One or more suspicious static signals were detected.; source matched previously finalized malicious package; routed for review
Trigger
Launching the Android/web runtime; initial and periodic mail synchronization.
Impact
Disclosure of email addresses, server configuration, account identifiers, error contents, and potentially IMAP passwords to the remote logging host.
Mechanism
Automatic remote verbose logging of account configuration and sync metadata.
Attack narrative
On Android/web startup, the package initializes synchronization and invokes `vlog` with `JSON.stringify(account.imap)`. The built-in logger silently sends up to 800 characters to `rmf39.aaz.lt`. The same remote logger receives account email/host/auth metadata and sync error messages during automatic synchronization. This is unconsented telemetry from a mail client and can expose credentials if the IMAP object contains a password.
Rationale
Source inspection confirms automatic remote logging of sensitive mail-account configuration, including a full serialized IMAP object, to an unrelated logging endpoint. The benign workspace-only postinstall hook does not mitigate this concrete exfiltration path.
Evidence
package.jsonbin/postinstall.jsbin/mailx.jsbin/mcp-server.jspackages/mailx-store-web/android-bootstrap.tspackages/mailx-store-web/worker-entry.tspackages/mailx-store-web/sync-manager.ts
Network endpoints1
rmf39.aaz.lt/logit/

Decision evidence

public snapshot
AI called this Malicious at 96.0% confidence as Malware with low false-positive risk.
Evidence for block
  • `packages/mailx-store-web/android-bootstrap.ts` sends silent remote `vlog` requests to `https://rmf39.aaz.lt/logit/...`.
  • Android startup logs `JSON.stringify(account.imap)` before account registration; IMAP configuration can contain credentials.
  • `packages/mailx-store-web/sync-manager.ts` logs account email, IMAP host/auth, IDs, and raw error messages through injected `vlog`.
  • `packages/mailx-store-web/worker-entry.ts` wires remote `vlog` into automatic worker startup and periodic mail sync.
Evidence against
  • `bin/postinstall.js` only checks Node version and symlinks bundled workspace packages; it performs no network access.
  • `bin/mcp-server.js` reads package-local `~/.rmfmail/agent.json` and calls a token-gated localhost RPC endpoint.
  • No foreign AI-agent configuration files are written by the inspected lifecycle code.
Behavioral surface
Source
ChildProcessCryptoDynamicRequireEnvironmentVarsEvalFilesystemNetworkShellWebSocket
Supply chain
HighEntropyStringsMinifiedObfuscatedProtestwareTelemetryUrlStrings
ManifestNo manifest risk signals triggered.
scanned 417 file(s), 16.2 MB of source, external domains: 127.0.0.1, accounts.google.com, api.anthropic.com, api.openai.com, autoconfig.thunderbird.net, bugs.webkit.org, bugzilla.mozilla.org, calendar.google.com, cdn.jsdelivr.net, cdnjs.cloudflare.com, contacts.google.com, cure53.de, developer.mozilla.org, developers.google.com, docs.microsoft.com, drafts.csswg.org, en.cppreference.com, feross.org, github.com, gmail.googleapis.com, graph.microsoft.com, html.spec.whatwg.org, lea.verou.me, mail.google.com, oauth2.googleapis.com, openjdk.java.net, opensource.org, people.googleapis.com, quilljs.com, rmf39.aaz.lt, tasks.google.com, tasks.googleapis.com, tiptap.dev, translate.google.com, websemantics.uk, www.cse.yorku.ca, www.googleapis.com, www.tiny.cloud, www.w3.org

Source & flagged code

17 flagged · loading source
package.jsonView file
scripts.postinstall = node bin/postinstall.js
High
Install Time Lifecycle Scripts

Package defines install-time lifecycle scripts.

package.jsonView on unpkg
scripts.postinstall = node bin/postinstall.js
Medium
Ambiguous Install Lifecycle Script

Install-time lifecycle script is not statically allowlisted and needs review.

package.jsonView on unpkg
bin/mailx.jsView file
54import net from "node:net"; L55: import { execSync } from "node:child_process"; L56: import { ports } from "@bobfrankston/miscinfo";
High
Child Process

Package source references child process execution.

bin/mailx.jsView on unpkg · L54
268// reg.exe value for `\"path\" \"%1\"` — double-backslash escapes for L269: // cmd.exe's shell layer, which strips one level before the value reaches L270: // reg.exe. Quoting %1 keeps `?` and `&` from being eaten by cmd before
High
Shell

Package source references shell execution.

bin/mailx.jsView on unpkg · L268
53Cross-file remote execution chain: bin/mailx.js spawns bin/popout-server.js; helper contains network access plus dynamic code execution. L53: import os from "node:os"; L54: import net from "node:net"; L55: import { execSync } from "node:child_process"; L56: import { ports } from "@bobfrankston/miscinfo"; ... L185: // Linux pickers read Name= from the .desktop file directly. L186: if (process.platform === "linux") { L187: const appsDir = path.join(os.homedir(), ".local", "share", "applications"); L188: const desktopPath = path.join(appsDir, "rmfmail.desktop"); ... L246: // (shipped in the npm package) to the per-app location below. L247: const __perAppBin = path.join(process.env.LOCALAPPDATA || "", "rmfmail", "bin"); L248: const __rmfmailtoExe = path.join(__perAppBin, "rmfmailto.exe"); ... L268: // reg.exe value for `\"path\" \"%1\"` — double-backslash escapes for
High
Cross File Remote Execution Context

Source spawns a local helper that also contains network and dynamic execution context; review data flow before blocking.

bin/mailx.jsView on unpkg · L53
2417clearInstanceFile(); L2418: const { spawn: spawnChild } = await import("child_process"); L2419: const child = spawnChild("rmfmail", [], { detached: true, stdio: "ignore", shell: true, windowsHide: true }); ... L2432: } L2433: // Auto-update action: run npm install then restart L2434: if (req._action === "performUpdate") {
High
Runtime Package Install

Package source invokes a package manager install command at runtime.

bin/mailx.jsView on unpkg · L2417
matchType = normalized_sha256 matchedPackage = @bobfrankston/rmfmail@1.2.117 matchedPath = bin/mailx.js matchedIdentity = npm:QGJvYmZyYW5rc3Rvbi9ybWZtYWls:1.2.117 similarity = 1.000 summary = normalized source hash matched finalized malicious source
High
Known Malware Source Similarity

Source file is highly similar to a previously finalized malicious package; route for source-aware review.

bin/mailx.jsView on unpkg
53import os from "node:os"; L54: import net from "node:net"; L55: import { execSync } from "node:child_process"; L56: import { ports } from "@bobfrankston/miscinfo"; ... L185: // Linux pickers read Name= from the .desktop file directly. L186: if (process.platform === "linux") { L187: const appsDir = path.join(os.homedir(), ".local", "share", "applications"); L188: const desktopPath = path.join(appsDir, "rmfmail.desktop"); ... L246: // (shipped in the npm package) to the per-app location below. L247: const __perAppBin = path.join(process.env.LOCALAPPDATA || "", "rmfmail", "bin"); L248: const __rmfmailtoExe = path.join(__perAppBin, "rmfmailto.exe"); ... L268: // reg.exe value for `\"path\" \"%1\"` — double-backslash escapes for
Medium
Install Persistence

Source writes installer persistence such as shell profile or service configuration.

bin/mailx.jsView on unpkg · L53
client/lib/quill/quill.jsView file
1/*! For license information please see quill.js.LICENSE.txt */ L2: !function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.Quill=e():t.... L3: //# sourceMappingURL=quill.js.map
Low
Eval

Package source references a known benign dynamic code generation pattern.

client/lib/quill/quill.jsView on unpkg · L1
bin/lean-accounts.jsView file
137package = @bobfrankston/rmfmail; repositoryIdentity = mailx; dependency = jsonc-parser L137: const mod = await import(pathToFileURL(path.join(dir, "lib", "esm", "main.js")).href).catch(() => null) || L138: await import("jsonc-parser").catch(() => null); L139: if (mod) { parseJsonc = mod.parse; break; }
High
Copied Package Dependency Bridge

Package metadata claims a different repository identity while copied source loads a runtime dependency bridge.

bin/lean-accounts.jsView on unpkg · L137
136if (fs.existsSync(path.join(dir, "package.json"))) { L137: const mod = await import(pathToFileURL(path.join(dir, "lib", "esm", "main.js")).href).catch(() => null) || L138: await import("jsonc-parser").catch(() => null);
Medium
Dynamic Require

Package source references dynamic require/import behavior.

bin/lean-accounts.jsView on unpkg · L136
bin/build-bundles.mjsView file
5* mailx's msger custom protocol routes every fetch through one IPC channel L6: * (Rust → daemon stdin → response → stdout), so an ES module import cascade L7: * pays a multi-second roundtrip per file. With ~17 client-side modules each ... L148: logLevel: "info", L149: // .wasm files are inlined as base64 data URLs so the runtime can L150: // decode → Uint8Array → pass as initSqlJs({ wasmBinary }), bypassing L151: // sql.js's fetch(...) of the .wasm. Android WebView refuses to L152: // compile WASM fetched from file:// (even with AllowFileAccess /
Low
Weak Crypto

Package source references weak cryptographic algorithms.

bin/build-bundles.mjsView on unpkg · L5
bin/rmfmailto.exeView file
path = bin/rmfmailto.exe kind = native_binary sizeBytes = 310272 magicHex = [redacted]
Medium
Ships Native Binary

Package ships native binary artifacts.

bin/rmfmailto.exeView on unpkg
bin/mailx.tsView file
matchType = normalized_sha256 matchedPackage = @bobfrankston/rmfmail@1.2.117 matchedPath = bin/mailx.ts matchedIdentity = npm:QGJvYmZyYW5rc3Rvbi9ybWZtYWls:1.2.117 similarity = 1.000 summary = normalized source hash matched finalized malicious source
High
Known Malware Source Similarity

Source file is highly similar to a previously finalized malicious package; route for source-aware review.

bin/mailx.tsView on unpkg
bin/build-rmfmailto-exe.jsView file
matchType = normalized_sha256 matchedPackage = @bobfrankston/rmfmail@1.2.117 matchedPath = bin/build-rmfmailto-exe.js matchedIdentity = npm:QGJvYmZyYW5rc3Rvbi9ybWZtYWls:1.2.117 similarity = 1.000 summary = normalized source hash matched finalized malicious source
High
Known Malware Source Similarity

Source file is highly similar to a previously finalized malicious package; route for source-aware review.

bin/build-rmfmailto-exe.jsView on unpkg
packages/mailx-store-web/worker-bundle.jsView file
matchType = normalized_sha256 matchedPackage = @bobfrankston/rmfmail@1.2.117 matchedPath = packages/mailx-store-web/worker-bundle.js matchedIdentity = npm:QGJvYmZyYW5rc3Rvbi9ybWZtYWls:1.2.117 similarity = 1.000 summary = normalized source hash matched finalized malicious source
High
Known Malware Source Similarity

Source file is highly similar to a previously finalized malicious package; route for source-aware review.

packages/mailx-store-web/worker-bundle.jsView on unpkg
client/compose/spellcheck-core.jsView file
matchType = normalized_sha256 matchedPackage = @bobfrankston/rmfmail@1.2.117 matchedPath = client/compose/spellcheck-core.js matchedIdentity = npm:QGJvYmZyYW5rc3Rvbi9ybWZtYWls:1.2.117 similarity = 1.000 summary = normalized source hash matched finalized malicious source
High
Known Malware Source Similarity

Source file is highly similar to a previously finalized malicious package; route for source-aware review.

client/compose/spellcheck-core.jsView on unpkg

Findings

11 High8 Medium8 Low
HighInstall Time Lifecycle Scriptspackage.json
HighChild Processbin/mailx.js
HighShellbin/mailx.js
HighCopied Package Dependency Bridgebin/lean-accounts.js
HighCross File Remote Execution Contextbin/mailx.js
HighRuntime Package Installbin/mailx.js
HighKnown Malware Source Similaritybin/mailx.js
HighKnown Malware Source Similaritybin/mailx.ts
HighKnown Malware Source Similaritybin/build-rmfmailto-exe.js
HighKnown Malware Source Similaritypackages/mailx-store-web/worker-bundle.js
HighKnown Malware Source Similarityclient/compose/spellcheck-core.js
MediumAmbiguous Install Lifecycle Scriptpackage.json
MediumDynamic Requirebin/lean-accounts.js
MediumNetwork
MediumEnvironment Vars
MediumInstall Persistencebin/mailx.js
MediumProtestware
MediumShips Native Binarybin/rmfmailto.exe
MediumStructural Risk Force Deep Review
LowScripts Present
LowEvalclient/lib/quill/quill.js
LowWeak Cryptobin/build-bundles.mjs
LowFilesystem
LowObfuscated
LowHigh Entropy Strings
LowTelemetry
LowUrl Strings