BTC
ETH
SOL
BNB
GOLD
XRP
DOGE
ADA
Back to home
Tech

Total.js RCE gadgets all around

Total.js, a Node.js full-stack framework claiming zero external dependencies, ships with remote code execution flaws in versions 4 and 5.

Total.js, a Node.js full-stack framework claiming zero external dependencies, ships with remote code execution flaws in versions 4 and 5. Attackers feed user input into the TextDB/NoSQL query builder’s .rule() method, which evaluates arbitrary JavaScript via new Function(). This lands in production code paths without proper sanitization, chaining directly to server-side execution.

Why does this hit hard? Total.js targets developers building web apps, APIs, and CMS with its all-JS stack. Over 10,000 npm downloads in recent months show active use, despite a niche footprint. Past flaws like CVE-2020-28495 (prototype pollution to RCE), CVE-2021-23344 (sandbox escape), and CVE-2021-31760 (code injection) reveal a pattern: the framework’s self-contained design dodges supply chain risks but amplifies its own bugs. Fix one, another emerges. If your app processes untrusted queries—think user filters in dashboards or search—this turns a query into shell access.

Vulnerable Code Paths

The entry point sits in textdb-wrapper.js at line 785. Call db.find().rule(userInput), and it shoves raw strings into options.filter. Downstream, textdb-builder.js‘s QueryBuilder.filter() at line 274 compiles it: new Function('doc', 'return ' + code). Execute.

// Vulnerable API usage
db.find().rule(userInput);  // Pushes raw JS to filter

Wrappers hide some sinks, but .update() with {'=field': 'PAYLOAD'} concatenates values directly—another vector if devs pass tainted objects. Total.js tries a “protection” blacklist in textdb-builder.js lines 608-609:

function isdangerous(rule) {
  return (/require|global/).test(rule);
}

It flags literal “require” or “global.” Trivial to dodge. Use doc.constructor.constructor for the Function constructor instead of global. Split “require” as 'req'+'uire'. No sweat.

RCE Payloads and Bypasses

Non-blind RCE shines here. process exposes in the eval scope, so bypass require and pipe output to a doc property. Response JSON leaks command results.

curl -s -G \
  --data-urlencode "filter[0][rule]=process.mainModule.require('req'+'uire')('child_process').execSync('id').toString()" \
  http://target/api/endpoint

This spits user/group from id command straight back. Scale to reverse shells: spawn netcat listeners or wget payloads. Blind? Time-based delays via Date or resource hogs confirm execution.

Context: Total.js v4 hit in 2023-2024 scans, v5 ongoing. No patch noted as of early 2026 reporting. Framework maintainer Peter Širka patched prior CVEs reactively—expect similar. But with new Function() in query engines, it’s redesign territory. Compare to MongoDB’s aggregation pipelines: they sandbox JS tightly; Total.js doesn’t.

Implications for Users

Scan your deps: npm ls total.js or GitHub deps. Versions <5.1.x (assuming patch) expose if TextDB enables. Mitigate: Disable .rule(), sanitize inputs server-side, or swap to vetted DBs like SQLite with prepared queries. Run as non-root, containerize.

This matters because Total.js sells “secure by isolation.” Reality: unpatched flaws stack risk. Devs pick it for simplicity—lightweight, no bloat—but security demands vigilance. Audit query builders everywhere; new Function() is a red flag in 2026. If exploited, pivot to full compromise: data exfil, crypto miners, ransomware loaders. Check logs for odd filter[rule] params now.

Fair take: Zero-deps is smart against left-pad incidents. But Total.js’s history—six+ CVEs since 2020—flags sloppy input handling. Users, patch fast or migrate. Attackers, probe Total.js endpoints; low-hanging fruit in overlooked stacks.

April 10, 2026 · 3 min · 10 views · Source: Lobsters

Related