pg_createsubscriber: Obstruct SQL injection via subscription names.

drop_existing_subscription() neglected to escape the subscription
name when generating its query string.  To fix, use
PQescapeIdentifier() to construct a properly escaped name, and use
it in the ALTER SUBSCRIPTION and DROP SUBSCRIPTION commands.

Reported-by: Yu Kunpeng <yu443940816@live.com>
Author: Nathan Bossart <nathandbossart@gmail.com>
Reviewed-by: Amit Kapila <amit.kapila16@gmail.com>
Security: CVE-2026-6476
Backpatch-through: 17
This commit is contained in:
Nathan Bossart 2026-05-11 05:13:47 -07:00 committed by Noah Misch
parent 6d6348f032
commit d389415ffa

View file

@ -1257,18 +1257,23 @@ drop_existing_subscription(PGconn *conn, const char *subname, const char *dbname
{
PQExpBuffer query = createPQExpBuffer();
PGresult *res;
char *subname_esc;
Assert(conn != NULL);
subname_esc = PQescapeIdentifier(conn, subname, strlen(subname));
/*
* Construct a query string. These commands are allowed to be executed
* within a transaction.
*/
appendPQExpBuffer(query, "ALTER SUBSCRIPTION %s DISABLE;",
subname);
subname_esc);
appendPQExpBuffer(query, " ALTER SUBSCRIPTION %s SET (slot_name = NONE);",
subname);
appendPQExpBuffer(query, " DROP SUBSCRIPTION %s;", subname);
subname_esc);
appendPQExpBuffer(query, " DROP SUBSCRIPTION %s;", subname_esc);
PQfreemem(subname_esc);
if (dry_run)
pg_log_info("dry-run: would drop subscription \"%s\" in database \"%s\"",