public inbox for pgsql-bugs@postgresql.org
help / color / mirror / Atom feedFrom: Japin Li <japinli@hotmail.com>
To: pgsql-bugs@lists.postgresql.org
Cc: zengman@halodbtech.com
Subject: Re: BUG #19478: `dblink_close` can be used for injection.
Date: Sat, 16 May 2026 09:24:15 +0800
Message-ID: <SY7PR01MB1092112D26F767633CF783E88B6052@SY7PR01MB10921.ausprd01.prod.outlook.com> (raw)
In-Reply-To: <19478-37289e8b0d1a1299@postgresql.org>
References: <19478-37289e8b0d1a1299@postgresql.org>
On Fri, 15 May 2026 at 01:29, PG Bug reporting form <noreply@postgresql.org> wrote:
> The following bug has been logged on the website:
>
> Bug reference: 19478
> Logged by: Man Zeng
> Email address: zengman@halodbtech.com
> PostgreSQL version: 18.4
> Operating system: 24.04.1-Ubuntu
> Description:
>
> Hi all,
>
> I think we can impose stricter restrictions on the parameters of
> `dblink_close`.
> For example, when calling `dblink_close`, certain operations can be achieved
> through SQL concatenation,
> which I believe is unexpected behavior.
>
> ```sql
> postgres@zxm-VMware-Virtual-Platform:~/Z-Xiao-M$ psql
> psql (19devel)
> Type "help" for help.
>
> postgres=# \c test
> You are now connected to database "test" as user "postgres".
> test=# CREATE EXTENSION IF NOT EXISTS dblink;
> CREATE EXTENSION
> test=# SELECT dblink_connect('c', 'dbname=' || current_database());
> dblink_connect
> ----------------
> OK
> (1 row)
>
> test=# SELECT dblink_open('c', 'cur', 'SELECT 1');
> dblink_open
> -------------
> OK
> (1 row)
>
> test=# -- CLOSE: CREATE TABLE
> test=# SELECT dblink_close('c', 'cur; CREATE TABLE hacked(id int); --');
> dblink_close
> --------------
> OK
> (1 row)
>
> test=# \d+ hacked
> Table "public.hacked"
> Column | Type | Collation | Nullable | Default | Storage | Compression |
> Stats target | Description
> --------+---------+-----------+----------+---------+---------+-------------+--------------+-------------
> id | integer | | | | plain | |
> |
> Access method: heap
>
> test=# SELECT dblink_disconnect('c');
> dblink_disconnect
> -------------------
> OK
> (1 row)
>
> test=# SELECT dblink_connect('c', 'dbname=' || current_database());
> dblink_connect
> ----------------
> OK
> (1 row)
>
> test=# SELECT dblink_open('c', 'cur', 'SELECT 1');
> dblink_open
> -------------
> OK
> (1 row)
>
> test=# -- CLOSE: DROP TABLE
> test=# SELECT dblink_close('c', 'cur; DROP TABLE hacked; --');
> dblink_close
> --------------
> OK
> (1 row)
>
> test=# \d+ hacked
> Did not find any relation named "hacked".
> test=#
> ```
>
> This is my SQL for reproducing the problem.
> ```sql
> CREATE EXTENSION IF NOT EXISTS dblink;
>
> SELECT dblink_connect('c', 'dbname=' || current_database());
> SELECT dblink_open('c', 'cur', 'SELECT 1');
>
> -- CLOSE: CREATE TABLE
> SELECT dblink_close('c', 'cur; CREATE TABLE hacked(id int); --');
>
> SELECT dblink_disconnect('c');
> \d+ hacked
>
> SELECT dblink_connect('c', 'dbname=' || current_database());
> SELECT dblink_open('c', 'cur', 'SELECT 1');
>
> -- CLOSE: DROP TABLE
> SELECT dblink_close('c', 'cur; DROP TABLE hacked; --');
>
> \d+ hacked
> SELECT dblink_disconnect('c');
> ```
>
> The solution to this problem is also very simple.
> ```
> postgres@zxm-VMware-Virtual-Platform:~/code/postgres/contrib$ git diff
> diff --git a/contrib/dblink/dblink.c b/contrib/dblink/dblink.c
> index 9798cb535bc..0a9334aa160 100644
> --- a/contrib/dblink/dblink.c
> +++ b/contrib/dblink/dblink.c
> @@ -543,7 +543,7 @@ dblink_close(PG_FUNCTION_ARGS)
>
> conn = rconn->conn;
>
> - appendStringInfo(&buf, "CLOSE %s", curname);
> + appendStringInfo(&buf, "CLOSE %s", quote_ident_cstr(curname));
>
> /* close the cursor */
> res = libpqsrv_exec(conn, buf.data, dblink_we_get_result);
> ```
>
> This is the feedback from the security team.
> ```
> Thanks for your report. We consider dblink_close() to be caller-trusted,
> and thus this is not considered a security vulnerability. Feel free to
> resubmit to pgsql-bugs@lists.postgresql.org.
> ```
>
> Any thought?
According to the documentation [1], it should be a cursor name. Wrapping it
in quotes can prevent attacks like SQL injection. I think your modification
is correct, and we should add test cases for it.
[1] https://www.postgresql.org/docs/current/contrib-dblink-close.html
> --
> regards,
> Man Zeng
--
Regards,
Japin Li
ChengDu WenWu Information Technology Co., Ltd.
reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: pgsql-bugs@postgresql.org
Cc: japinli@hotmail.com, pgsql-bugs@lists.postgresql.org, zengman@halodbtech.com
Subject: Re: BUG #19478: `dblink_close` can be used for injection.
In-Reply-To: <SY7PR01MB1092112D26F767633CF783E88B6052@SY7PR01MB10921.ausprd01.prod.outlook.com>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox