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 1wRv1l-002o3p-0V for pgsql-hackers@arkaria.postgresql.org; Tue, 26 May 2026 16:53:13 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1wRv1i-005GcF-1u for pgsql-hackers@arkaria.postgresql.org; Tue, 26 May 2026 16:53:11 +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 1wRv1i-005Gc6-0r for pgsql-hackers@lists.postgresql.org; Tue, 26 May 2026 16:53:11 +0000 Received: from mail-oi1-x236.google.com ([2607:f8b0:4864:20::236]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1wRv1h-00000001YDF-0ySO for pgsql-hackers@postgresql.org; Tue, 26 May 2026 16:53:10 +0000 Received: by mail-oi1-x236.google.com with SMTP id 5614622812f47-4859b1fc7a8so1278119b6e.0 for ; Tue, 26 May 2026 09:53:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1779814387; x=1780419187; darn=postgresql.org; h=content-disposition:mime-version:message-id:subject:to:from:date :from:to:cc:subject:date:message-id:reply-to; bh=gKzMm87QueOcgkOeRI6xgS+wDFFH3sWzYB4fQwpW2oc=; b=KUR3QNx4rfG6X1/jtSqRtin6WdtU7EVYdPlPonxizXddWhq+RhCNRHRVswo3XloAtv oupRx/jZ2SIgeRooFvssNMX3dXfOq5SIRCLEU7BUWPK09fx1jERpBshDG7tX1IDrbmJg kIKeHENXh4UOeAMOkTA8ClZInl6J2L9l/y5bOBp42z98ndmdn7MpvRsYFEdKrA6+zMlh CRUT2cvWcYBFbkCa6dbfSgOyrmoQdSh+Tu1oSy1VHDYbsmw3ze6+NH7o2v7JwXb88aNj ATrxzmej6A6X0AAD1/0AHHa6lnTh+9TYqRyPh/uNdb9KRfvqSF1Y9OoWhYQ50ZmPauFZ 13Xw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779814387; x=1780419187; h=content-disposition:mime-version:message-id:subject:to:from:date :x-gm-gg:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=gKzMm87QueOcgkOeRI6xgS+wDFFH3sWzYB4fQwpW2oc=; b=kItvbHMNFzPf3t/tRkz9U8Jq1wa8kNvCxZueyfJYwX6FzgONGC/pvxAxefeq2zhd7z 7bPWCx09sAeV5H4xGrLGDouw7vkUaNH9rs0C8TZ5q2itBn+FlO7+uzCmWzzESHsy8hAo mp41lfk8P2N7exSPYaE0RVglLmx5QxarBms+gtErAcsDn9Y7Fp3nRKf+r/qtiU7wSwsc visSOUXYZrVT6GVakf2UxbSa5yjudyVxfZIBhT6wqjAgpwbNrqbPFhakXxuIRsM/ImG6 5porwEEP194pjM9kedoVpVL+bKQoehWQ6x1D7WVKqE7rfxhIYvfeKc+hjJGlhg8jeL7U c62Q== X-Gm-Message-State: AOJu0Yw2u1FPeltiyYd2qTCxQfpdKwn53Sd81KXadx+XXpGULnKzq82b 5ygb+gjedNows9h59DlWjNBYxI/CRYMl4uk31tiXUTok+GhCvtVC4mGSaQEkbQ== X-Gm-Gg: Acq92OGhiuZ92iwg/THbkIv8pC6JWzn/1tQUykNlHGcEkhO79QyjOfhkFAnrDdDZi/H FPHvcET1nqLYpUhijCn45Tyq+PLUfgeMFHi3fVNfWYLKUUZkdwc7YdYZAWrlEvieeqTMw+LsoZc M2wQxgo920xygUo3cfWflzEGAhAyQSpblKiXeXOSy2PN/l/3A6iZaUAfImNPfoAIYD3QyENO9Aa 6lQOzJNSNxwGb5X/3FMMdidrL8OEKp0u3CTw1nRckb9HBTdXoGe/cf7moPd/xuKIv4+C3+xBdj4 VT0Awt1KEfWlu/vptK4g4YfbNf8hv9EfRHIqM2KAYMaE3hFCaW2KlcpSgwa6IZ/Sa5Y+VxF6SzG FFDQuZHQBIt6MATY6Pl1axA8EbnXiYM397scHS5ERLW4aukCK9k1GoGCBUAqiwhc89VuraKMs7a b+S2WqgahY4ruFvKsd+QLaJvr/lybHGsy3RjlfT7kDWGz8bUaACs8OB1Njt0iJ0AQnUD9Na+mBr ibmyD7DS5L8rWxIGUqkSw== X-Received: by 2002:a05:6820:6bee:b0:696:63dc:cac9 with SMTP id 006d021491bc7-69d7eb6c5a6mr7463576eaf.23.1779814386578; Tue, 26 May 2026 09:53:06 -0700 (PDT) Received: from nathan (162-195-168-172.lightspeed.stlsmo.sbcglobal.net. [162.195.168.172]) by smtp.gmail.com with ESMTPSA id 006d021491bc7-69d83a4db17sm6890016eaf.9.2026.05.26.09.53.05 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 26 May 2026 09:53:05 -0700 (PDT) Date: Tue, 26 May 2026 11:53:03 -0500 From: Nathan Bossart To: pgsql-hackers@postgresql.org Subject: expand refint docs with usage info Message-ID: MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="3pMPqxRi+4qCFlgd" Content-Disposition: inline List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --3pMPqxRi+4qCFlgd Content-Type: text/plain; charset=us-ascii Content-Disposition: inline The security team has received a couple of reports about potential SQL injection opportunities via refint's trigger arguments. We discussed this while preparing CVE-2026-6637 and concluded that forcibly quoting these arguments would be much more likely to break working code than to prevent any exploits. Unlike data values, the table/column names come from trigger arguments, and there is little reason for a trigger author to put hostile inputs into those arguments. The attached documentation patch was originally intended to go along with CVE-2026-6637, but we ultimately scoped it down to only the security-relevant parts. This should be back-patched to v14. Note that we are preparing to removing refint completely in v20, but IMHO this doc update is still worth doing. Thoughts? -- nathan --3pMPqxRi+4qCFlgd Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0001-expand-refint-docs-with-usage-info.patch From 45e236f4f66726146983c15c936997bb358162ba Mon Sep 17 00:00:00 2001 From: Nathan Bossart Date: Tue, 26 May 2026 11:46:45 -0500 Subject: [PATCH v1 1/1] expand refint docs with usage info --- doc/src/sgml/contrib-spi.sgml | 58 ++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/doc/src/sgml/contrib-spi.sgml b/doc/src/sgml/contrib-spi.sgml index 6fa9479d1b9..7e4e580bc74 100644 --- a/doc/src/sgml/contrib-spi.sgml +++ b/doc/src/sgml/contrib-spi.sgml @@ -34,6 +34,14 @@ key mechanism, of course, but the module is still useful as an example.) + + + refint requires a + secure schema usage pattern and + data types where the equality operator is named =. + + + check_primary_key() checks the referencing table. To use, create an AFTER INSERT OR UPDATE trigger using this @@ -44,6 +52,29 @@ keys, create a trigger for each reference. + + + The referenced table name and column name arguments to + check_primary_key() are copied as-is into internally + generated SQL statements and therefore must be double-quoted by the user as + necessary in the CREATE TRIGGER command. See + for more information about quoting + SQL identifiers. Conversely, the referencing table + column name arguments should not be double quoted. See the following mock + example of proper use of check_primary_key(): + +CREATE TRIGGER mytrigger +AFTER INSERT OR UPDATE ON referencing_table +FOR EACH ROW EXECUTE PROCEDURE +check_primary_key ( + 'column A', 'column B', -- referencing table columns + 'myschema."referenced table"', -- referenced table + '"column A"', '"column B"' -- referenced table columns +); + + + + check_foreign_key() checks the referenced table. To use, create an AFTER DELETE OR UPDATE trigger using this @@ -53,13 +84,38 @@ (cascade — to delete the referencing row, restrict — to abort transaction if referencing keys exist, setnull — to set referencing key fields to null), - the triggered table's column names which form the primary/unique key, then + the referenced table's column names which form the primary/unique key, then the referencing table name and column names (repeated for as many referencing tables as were specified by first argument). Note that the primary/unique key columns should be marked NOT NULL and should have a unique index. + + + The referencing table name and column name arguments + to check_foreign_key() are copied as-is into + internally generated SQL statements and therefore must be double-quoted by + the user as necessary in the CREATE TRIGGER command. + See for more information about + quoting SQL identifiers. Conversely, the referenced + table column name arguments should not be double quoted. See the following + mock example of proper use of check_foreign_key(): + +CREATE TRIGGER mytrigger +AFTER DELETE OR UPDATE ON referenced_table +FOR EACH ROW EXECUTE PROCEDURE +check_foreign_key ( + 1, -- number of referencing tables + 'cascade', -- action + 'column A', 'column B', -- referenced table columns + 'myschema."referencing table"', -- referencing table + '"column A"', '"column B"' -- referencing table columns +); + + + + Note that if these triggers are executed from another BEFORE trigger, they can fail unexpectedly. For -- 2.50.1 (Apple Git-155) --3pMPqxRi+4qCFlgd--