| From: | PG Bug reporting form <noreply(at)postgresql(dot)org> |
|---|---|
| To: | pgsql-bugs(at)lists(dot)postgresql(dot)org |
| Cc: | zengman(at)halodbtech(dot)com |
| Subject: | BUG #19478: `dblink_close` can be used for injection. |
| Date: | 2026-05-15 01:29:54 |
| Message-ID: | 19478-37289e8b0d1a1299@postgresql.org |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-bugs |
The following bug has been logged on the website:
Bug reference: 19478
Logged by: Man Zeng
Email address: zengman(at)halodbtech(dot)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(at)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(at)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(at)lists(dot)postgresql(dot)org(dot)
```
Any thought?
--
regards,
Man Zeng
| From | Date | Subject | |
|---|---|---|---|
| Next Message | PG Bug reporting form | 2026-05-15 06:41:22 | BUG #19479: 04 is happening because your metadata is advertising a package version that is not actually present |
| Previous Message | Robert Haas | 2026-05-14 19:36:00 | Re: BUG #19354: JOHAB rejects valid byte sequences |