Home Explore Blog CI



postgresql

21th chunk of `doc/src/sgml/extend.sgml`
cd3d335654f2cca1e63be4d9d8fdfd2f28212e2b53979ca30000000100000fbc
 <literal>OPERATOR(<replaceable>schema</replaceable>.=) ANY</literal>
      and <literal>CASE WHEN <replaceable>expression</replaceable></literal>.
     </para>

     <para>
      A general-purpose extension usually should not assume that it's been
      installed into a secure schema, which means that even schema-qualified
      references to its own objects are not entirely risk-free.  For
      example, if the extension has defined a
      function <literal>myschema.myfunc(bigint)</literal> then a call such
      as <literal>myschema.myfunc(42)</literal> could be captured by a
      hostile function <literal>myschema.myfunc(integer)</literal>.  Be
      careful that the data types of function and operator parameters exactly
      match the declared argument types, using explicit casts where necessary.
     </para>
    </sect3>

    <sect3 id="extend-extensions-security-scripts">
     <title>Security Considerations for Extension Scripts</title>

     <para>
      An extension installation or update script should be written to guard
      against search-path-based attacks occurring when the script executes.
      If an object reference in the script can be made to resolve to some
      other object than the script author intended, then a compromise might
      occur immediately, or later when the mis-defined extension object is
      used.
     </para>

     <para>
      DDL commands such as <command>CREATE FUNCTION</command>
      and <command>CREATE OPERATOR CLASS</command> are generally secure,
      but beware of any command having a general-purpose expression as a
      component.  For example, <command>CREATE VIEW</command> needs to be
      vetted, as does a <literal>DEFAULT</literal> expression
      in <command>CREATE FUNCTION</command>.
     </para>

     <para>
      Sometimes an extension script might need to execute general-purpose
      SQL, for example to make catalog adjustments that aren't possible via
      DDL.  Be careful to execute such commands with a
      secure <varname>search_path</varname>; do <emphasis>not</emphasis>
      trust the path provided by <command>CREATE/ALTER EXTENSION</command>
      to be secure.  Best practice is to temporarily
      set <varname>search_path</varname> to <literal>pg_catalog,
      pg_temp</literal> and insert references to the extension's
      installation schema explicitly where needed.  (This practice might
      also be helpful for creating views.)  Examples can be found in
      the <filename>contrib</filename> modules in
      the <productname>PostgreSQL</productname> source code distribution.
     </para>

     <para>
      Secure cross-extension references typically require schema-qualification
      of the names of the other extension's objects, using the
      <literal>@extschema:<replaceable>name</replaceable>@</literal>
      syntax, in addition to careful matching of argument types for functions
      and operators.
     </para>
    </sect3>
   </sect2>

   <sect2 id="extend-extensions-example">
    <title>Extension Example</title>

    <para>
     Here is a complete example of an <acronym>SQL</acronym>-only
     extension, a two-element composite type that can store any type of value
     in its slots, which are named <quote>k</quote> and <quote>v</quote>.  Non-text
     values are automatically coerced to text for storage.
    </para>

    <para>
     The script file <filename>pair--1.0.sql</filename> looks like this:

<programlisting><![CDATA[
-- complain if script is sourced in psql, rather than via CREATE EXTENSION
\echo Use "CREATE EXTENSION pair" to load this file. \quit

CREATE TYPE pair AS ( k text, v text );

CREATE FUNCTION pair(text, text)
RETURNS pair LANGUAGE SQL AS 'SELECT ROW($1, $2)::@extschema@.pair;';

CREATE OPERATOR ~> (LEFTARG = text, RIGHTARG = text, FUNCTION = pair);

-- "SET search_path" is easy to get right, but qualified names perform better.
CREATE FUNCTION lower(pair)
RETURNS pair LANGUAGE SQL
AS 'SELECT ROW(lower($1.k), lower($1.v))::@extschema@.pair;'

Title: Security Best Practices for PostgreSQL Extension Development
Summary
This section provides detailed security guidelines for developing PostgreSQL extensions, particularly focusing on extension scripts. It emphasizes the importance of guarding against search-path-based attacks during script execution. The text advises caution when using commands with general-purpose expressions, such as CREATE VIEW or DEFAULT expressions in CREATE FUNCTION. For executing general-purpose SQL, it recommends setting a secure search_path (pg_catalog, pg_temp) and explicitly referencing the extension's installation schema. The passage also discusses secure cross-extension references, suggesting the use of schema-qualified names with the @extschema:name@ syntax. The section concludes with an example of a simple SQL-only extension, demonstrating the creation of a composite type, functions, and an operator, while adhering to the security practices discussed.