CVE-2026-47670 - DbGate loadReader dynamic import RCE
DbGate dbgate-api versions through 7.1.8 exposed a server-side code
generation flaw in the POST /runners/load-reader route. The route accepted a
request-controlled functionName, interpolated it into generated JavaScript,
and executed that script in a Node.js child process. The advisory describes a
variant where an authenticated user can break out of the intended function call
and use dynamic import() to bypass the older require = null mitigation.
This is a critical sibling to the earlier loadReader recipe for
CVE-2026-48017. Treat either finding as evidence that the loadReader
generated-code boundary must be removed or constrained with a finite,
server-side operation registry. A reviewer-ready fix upgrades DbGate, proves
raw request names cannot become JavaScript source, and reviews credentials
reachable by the DbGate process.
When to use it
Use this recipe when a repository deploys, embeds, forks, wraps, or configures
DbGate and may expose /runners/load-reader or equivalent reader execution.
It is most useful when authenticated users, support users, automation, demos,
or agents can influence functionName, plugin names, loader names, or
server-side reader execution.
Use it to remove raw request-controlled JavaScript generation and gate loadReader execution with explicit permissions. Do not use it to run dynamic import probes or command payloads.
Inputs
package.json, lockfiles, workspaces, Dockerfiles, Compose/Helm/Kubernetes manifests, Terraform/Ansible/PaaS config, reverse-proxy routes, CI images, SBOMs, generated dependency reports, forks, plugins, wrappers, and runbooks that reference DbGate.- Resolved
dbgate-api,dbgate,dbgate-serve, anddbgate-webversions across all deployable targets. - loadReader and shell API handling:
POST /runners/load-reader,loadReader,loaderScriptTemplate,functionName,compileShellApiFunctionName,extractShellApiPlugins, and generated runner scripts. - Role and reachability evidence for administrators, developers, support, tenants, contractors, automation accounts, demo users, and internet users.
- Runtime authority and cleanup ownership for sessions, saved database credentials, SQL history, query results, host files, cloud credentials, mounted secrets, and internal service endpoints.
Affected versions
- Vulnerable package:
dbgate-api <=7.1.8 - Fixed package:
dbgate-api 7.1.9+ - Affected route:
POST /runners/load-reader - Affected parameter:
functionName - Affected code shape: generated JavaScript that calls a reader function chosen directly from request input
- Related recipe:
CVE-2026-48017covers the same loadReader boundary with a different documented bypass path
Indicator-of-exposure
- The repository depends on, vendors, forks, builds, or deploys DbGate or
server-side
dbgate-api <=7.1.8. - A deployable DbGate server is reachable by users who are not fully trusted administrators.
- The repository exposes DbGate through Docker, Compose, Helm, Kubernetes, systemd, PaaS config, reverse-proxy routes, internal admin tooling, support environments, demo stacks, or customer-managed installs.
- Product code, forks, plugins, or wrappers accept reader function names, package-qualified loader names, shell API names, plugin names, or route bodies from users.
- The DbGate runtime can read saved database connection profiles, database passwords, SQL history, host files, cloud credentials, source checkout material, mounted secrets, or internal network services.
Quick checks:
rg -n "dbgate|dbgate-api|load-reader|loadReader|loaderScriptTemplate|functionName|compileShellApiFunctionName|extractShellApiPlugins|require\\s*=\\s*null|dynamic import|import\\(" .
npm ls dbgate-api dbgate dbgate-serve dbgate-web
pnpm why dbgate-api dbgate dbgate-serve dbgate-web
yarn why dbgate-api dbgate dbgate-serve dbgate-web
rg -n "dbgate|dbgate-api|DBGATE|runners/load-reader|LOGINS|LOGIN_PASSWORD|authProvider|none" Dockerfile* docker-compose*.yml compose*.yml charts k8s deploy .github . 2>/dev/null
Windows:
rg -n "dbgate|dbgate-api|load-reader|loadReader|loaderScriptTemplate|functionName|compileShellApiFunctionName|extractShellApiPlugins|require\\s*=\\s*null|dynamic import|import\\(" .
npm ls dbgate-api dbgate dbgate-serve dbgate-web
pnpm why dbgate-api dbgate dbgate-serve dbgate-web
yarn why dbgate-api dbgate dbgate-serve dbgate-web
rg -n "dbgate|dbgate-api|DBGATE|runners/load-reader|LOGINS|LOGIN_PASSWORD|authProvider|none" Dockerfile* docker-compose*.yml compose*.yml charts k8s deploy .github .
Do not send crafted functionName values, run dynamic-import probes, execute
commands through DbGate, or inspect live tokens during triage.
Remediation strategy
- Upgrade every controlled
dbgate-api, DbGate runtime, lockfile, image, deployment manifest, generated dependency report, and SBOM to7.1.9+. - If this repository owns a DbGate fork, wrapper, plugin boundary, or similar reader execution path, remove request-controlled code generation. Replace it with a finite server-side registry that maps approved reader identifiers to implementation functions.
- Reject unknown reader identifiers before script generation. Validation should reject newlines, comments, whitespace, punctuation, quotes, brackets, operators, template markers, package-name confusion, control characters, and any identifier not present in the approved registry.
- Apply explicit authorization to loadReader execution. Basic authenticated users should not be able to select arbitrary server-side reader functions.
- Do not rely on
require = null, deny-lists, or UI-only checks as the primary security boundary. Dynamicimport()and other Node.js surfaces make that style of sandbox fragile. - Reduce DbGate runtime authority: least-privilege OS user, no writable source checkout, no deploy/cloud credentials, narrow mounts, restricted egress, and secret-manager-backed database credentials where practical.
- Rotate DbGate tokens, saved database credentials, and other reachable runtime secrets if untrusted authenticated users had access to a vulnerable service.
The prompt
You are remediating CVE-2026-47670 / GHSA-wm5r-5qp3-5vxf, a critical DbGate
`/runners/load-reader` code-injection issue where request-controlled
`functionName` input reaches generated JavaScript and can bypass `require =
null` via dynamic import. Produce exactly one output:
- A reviewer-ready PR/change request that upgrades DbGate, removes unsafe
request-controlled JavaScript generation, gates loadReader execution,
refreshes generated artifacts, and documents operator cleanup, or
- TRIAGE.md if this repository does not control an affected DbGate runtime,
package, fork, plugin, image, wrapper, or deployment.
## Rules
- Scope only CVE-2026-47670 / GHSA-wm5r-5qp3-5vxf and directly related DbGate
loadReader, generated-code, authorization, and runtime-hardening work.
- Also close `CVE-2026-48017` if the same loadReader boundary is present, but
do not broaden into unrelated DbGate features unless they share the same
generated-code pattern.
- Treat DbGate sessions, bearer tokens, saved database credentials, SQL
history, query results, source checkout material, environment variables,
cloud credentials, mounted files, and internal service endpoints as
sensitive.
- Do not send exploit payloads, dynamic-import probes, newline-injection
strings, process-spawn checks, or shell commands through `/runners/load-reader`
or any DbGate runner endpoint.
- Do not print tokens, passwords, database rows, query history, decoded JWTs,
connection profiles, environment variables, generated runner scripts, or
command output into logs, reports, snapshots, or commits.
- Do not rely on `require = null`, deny-lists, or UI-only validation as the sole
security control.
- Do not auto-merge.
## Steps
1. Inventory every DbGate reference controlled by this repository:
`package.json`, lockfiles, workspaces, Dockerfiles, Compose files, Helm
charts, Kubernetes manifests, Terraform, Ansible, reverse-proxy routes,
PaaS config, CI images, SBOMs, generated dependency reports, runbooks,
forks, plugins, and local wrappers.
2. Determine every resolved `dbgate-api`, `dbgate`, `dbgate-serve`, and
`dbgate-web` version. A target is vulnerable if the server-side runtime
resolves to `7.1.8` or earlier.
3. Search for loadReader and shell API function-name handling:
`POST /runners/load-reader`, `loadReader`, `loaderScriptTemplate`,
`functionName`, `compileShellApiFunctionName`, `extractShellApiPlugins`,
generated runner scripts, plugin loader aliases, and custom route wrappers.
4. Classify who can authenticate to or reach the affected DbGate runtime:
trusted administrators, internal developers, tenant users, contractors,
support users, automation accounts, demo users, or internet users.
5. If this repository only contains unrelated documentation or an external
deployment pointer, stop with `TRIAGE.md` listing checked files, runtime
owner if known, and required fixed version `dbgate-api 7.1.9+`.
6. Upgrade all controlled DbGate runtime packages and images to `7.1.9+`.
Regenerate lockfiles, package-manager metadata, image digests, SBOMs,
deployment render output, dependency reports, and docs that pin versions.
7. Where this repository owns product code, forks, wrappers, or plugins,
replace raw `functionName` handling with fail-closed controls:
- accept only known reader identifiers from an approved registry;
- parse package-qualified names into structured fields before use;
- reject empty names, newlines, comments, whitespace, separators,
punctuation, operators, parentheses, quotes, brackets, template markers,
and control characters;
- map approved names to functions without concatenating request input into
generated JavaScript;
- return non-secret validation errors.
8. Add server-side permission and platform checks before loadReader execution:
- require explicit reader/script execution permission;
- reject the route when generated runner execution is disabled by platform
policy;
- ensure non-admin/basic users cannot select arbitrary readers;
- fail closed when role, package identity, or reader identity is unknown.
9. Add regression tests that do not execute attacker code:
- vulnerable package versions are absent from manifests and images;
- malformed `functionName` values are rejected before script generation;
- dynamic-import-like strings, newline-containing strings, and package-name
confusion cases are rejected as invalid data, not executed;
- non-admin users cannot call or configure loadReader execution;
- logs omit tokens, connection profiles, query text, environment variables,
generated scripts, and database results.
10. Harden deployment where this repository controls runtime:
- run DbGate as non-root or least privilege when supported;
- mount only required paths and make them read-only where possible;
- deny cloud metadata and unnecessary internal egress;
- keep database credentials in a secret manager or deployment secret;
- isolate DbGate from source checkout and deployment credentials.
11. Add a PR body section named `CVE-2026-47670 operator actions` that states:
- DbGate and `dbgate-api` versions before and after;
- whether `/runners/load-reader` was reachable and by which roles;
- whether custom forks, plugins, or wrappers handled `functionName`;
- whether the same work also closes `CVE-2026-48017`;
- which database credentials, DbGate sessions, host files, and integration
secrets may have been reachable before the patch;
- whether credential rotation, session invalidation, log review, image
rebuilds, or runtime hardening are required;
- which validation commands passed and which unrelated failures remain.
12. Run available validation: package install, lockfile integrity, unit/API
tests, authz tests, route tests, lint/typecheck, container build,
deployment rendering, SBOM refresh, and dependency/security scans.
13. Use PR title:
`fix(sec): remediate CVE-2026-47670 in DbGate loadReader`.
## Stop conditions
- No affected DbGate runtime, package, image, fork, plugin, wrapper, or
deployment is controlled by this repository.
- The DbGate runtime is supplied by another team, managed service, or external
image; name the owner and required fixed version in `TRIAGE.md`.
- A fixed DbGate version cannot be consumed without a broader migration.
- Product requirements intentionally allow non-admin users to trigger arbitrary
DbGate reader execution; document the required product/security decision.
- Verification would require exploit payloads, process-spawn probes, live
dynamic-import execution, live database queries, or secret-bearing runtime
inspection.
- Validation fails for unrelated pre-existing reasons; document those failures
instead of broadening scope.
Verification - what the reviewer looks for
- No controlled lockfile, image, SBOM, package manifest, or deployment target
resolves server-side
dbgate-apito7.1.8or earlier. loadReaderand/runners/load-readercannot build generated JavaScript from raw request-controlledfunctionNamevalues.- Any remaining reader selection path uses a finite approved registry and server-side permission checks.
- Tests reject dynamic-import-like and newline-containing identifiers without executing them.
- Non-admin/basic users cannot reach arbitrary reader execution.
- Operator notes cover database credential rotation, DbGate session
invalidation, log review, runtime hardening, and whether
CVE-2026-48017is closed by the same patch.
Watch for
- Updating one npm manifest while Docker images, global installs, Helm charts, or SBOMs still resolve an old DbGate runtime.
- Treating “authenticated” as trusted in shared admin portals, demos, support tools, internal services, or customer-managed installs.
- Blocking the UI while API, proxy, import, or plugin routes still pass
functionNamethrough. - Allow-listing only one reader-name format while package-qualified names, plugin aliases, or extension points take a different path.
- Logs that capture bearer tokens, database credentials, SQL text, query results, environment variables, or generated runner scripts.
Output contract
Return one of:
- A reviewer-ready PR/change request that upgrades DbGate runtime packages to
7.1.9+, replaces rawfunctionNamehandling with a finite server-side registry, adds permission checks for loadReader execution, refreshes generated artifacts, reduces runtime authority, and documents whether the same work closes CVE-2026-48017. TRIAGE.mdwhen no controlled affected DbGate runtime, package, image, fork, plugin, wrapper, or deployment exists.
The output must list versions before/after, loadReader reachability by role, custom forks/plugins/wrappers in scope, validation commands, generated artifacts refreshed, and operator actions for session invalidation, credential rotation, log review, image rebuilds, and runtime hardening. It must not include exploit strings, generated runner scripts, tokens, database rows, query history, decoded credentials, or environment values.
Related recipes
- CVE-2026-47668 - DbGate JSON script runner unauthenticated RCE
- CVE-2026-48017 - DbGate loadReader functionName RCE
- Agent session kill rules
References
- GitHub Advisory Database: https://github.com/advisories/GHSA-wm5r-5qp3-5vxf
- DbGate 7.1.9 release: https://github.com/dbgate/dbgate/releases/tag/v7.1.9
- Related GitHub Advisory Database entry: https://github.com/advisories/GHSA-hv83-ggc4-v385
- NVD: https://nvd.nist.gov/vuln/detail/CVE-2026-47670