Summary
For MySQL, ssh_db_query builds the remote command by interpolating the raw SQL into a double-quoted shell string (mysql ... -e "${query}" ...). The remote shell therefore evaluates backticks `...` (command substitution) and $... before mysql ever sees the query. Any SQL that uses backtick-quoted identifiers — e.g. a hyphenated database name `my-db`.Table — is silently corrupted and returns empty/incorrect results with no error. The same construction also allows arbitrary shell command execution on the remote host.
Affected code
src/database-manager.js → buildMySQLQueryCommand() (v3.5.0):
// json branch
command += ` -e "${query}" --batch --skip-column-names | awk '...'`;
// non-json branch
command += ` -e "${query}"`;
buildPostgreSQLQueryCommand (-c "${query}") and the Mongo --eval "${query}" builder share the same double-quoting.
Reproduction
Two databases on one server, app and other-db:
SELECT a.id, o.note
FROM app_table a
LEFT JOIN `other-db`.notes o ON a.ext = o.ext
WHERE a.id = 1;
- Run via
ssh_db_query (database app): returns [], even though a matching row exists.
- Run the identical SQL via
mysql directly (e.g. a single-quoted heredoc): returns the row.
Cause: inside -e "... \other-db`.notes ...", the remote shell executes `` other-db`` as a command (command substitution) and substitutes its (empty) output, so MySQL actually receives... LEFT JOIN .notes ...` — an invalid/different reference — yielding empty/incorrect results. Queries without backticks are unaffected, which hides the bug.
Impact
- Correctness: any query needing backtick identifiers is silently wrong — hyphenated db/table names, cross-database joins, reserved-word columns. Empty/incorrect results with no error are dangerous for debugging and automation.
- Security: the same double-quoting executes
`...` / $(...) from the query string on the remote host. isSafeQuery() only filters SQL keywords, so a query such as SELECT `some command` or SELECT '$(id)' runs shell commands on the target server — i.e. the "SELECT-only" DB tool can execute arbitrary remote commands.
Suggested fix
Stop letting the shell parse the query:
- Feed the SQL to
mysql via stdin with a quoted heredoc delimiter (mysql ... <<'__SQL__' … __SQL__), so backticks/$ are never shell-evaluated; or
- single-quote the
-e argument and escape embedded single quotes ('\'').
- Apply the same to the PostgreSQL and MongoDB builders.
- Optionally harden
isSafeQuery() against shell metacharacters as defense-in-depth.
Version: mcp-ssh-manager 3.5.0.
Summary
For MySQL,
ssh_db_querybuilds the remote command by interpolating the raw SQL into a double-quoted shell string (mysql ... -e "${query}" ...). The remote shell therefore evaluates backticks`...`(command substitution) and$...beforemysqlever sees the query. Any SQL that uses backtick-quoted identifiers — e.g. a hyphenated database name`my-db`.Table— is silently corrupted and returns empty/incorrect results with no error. The same construction also allows arbitrary shell command execution on the remote host.Affected code
src/database-manager.js→buildMySQLQueryCommand()(v3.5.0):buildPostgreSQLQueryCommand(-c "${query}") and the Mongo--eval "${query}"builder share the same double-quoting.Reproduction
Two databases on one server,
appandother-db:ssh_db_query(databaseapp): returns[], even though a matching row exists.mysqldirectly (e.g. a single-quoted heredoc): returns the row.Cause: inside
-e "... \other-db`.notes ...", the remote shell executes ``other-db`` as a command (command substitution) and substitutes its (empty) output, so MySQL actually receives... LEFT JOIN .notes ...` — an invalid/different reference — yielding empty/incorrect results. Queries without backticks are unaffected, which hides the bug.Impact
`...`/$(...)from the query string on the remote host.isSafeQuery()only filters SQL keywords, so a query such asSELECT `some command`orSELECT '$(id)'runs shell commands on the target server — i.e. the "SELECT-only" DB tool can execute arbitrary remote commands.Suggested fix
Stop letting the shell parse the query:
mysqlvia stdin with a quoted heredoc delimiter (mysql ... <<'__SQL__'…__SQL__), so backticks/$are never shell-evaluated; or-eargument and escape embedded single quotes ('\'').isSafeQuery()against shell metacharacters as defense-in-depth.Version: mcp-ssh-manager 3.5.0.