]> granicus.if.org Git - postgresql/commitdiff
Document security implications of qualified names.
authorNoah Misch <noah@leadboat.com>
Sun, 29 Jul 2018 03:08:01 +0000 (20:08 -0700)
committerNoah Misch <noah@leadboat.com>
Sun, 29 Jul 2018 03:08:40 +0000 (20:08 -0700)
Commit 5770172cb0c9df9e6ce27c507b449557e5b45124 documented secure schema
usage, and that advice suffices for using unqualified names securely.
Document, in typeconv-func primarily, the additional issues that arise
with qualified names.  Back-patch to 9.3 (all supported versions).

Reviewed by Jonathan S. Katz.

Discussion: https://postgr.es/m/20180721012446.GA1840594@rfd.leadboat.com

doc/src/sgml/ddl.sgml
doc/src/sgml/ref/create_function.sgml
doc/src/sgml/syntax.sgml
doc/src/sgml/typeconv.sgml
doc/src/sgml/xfunc.sgml

index 657bbc3c8721d818a76c9b620f8363e3a2d96043..158e5a7cfa62e545bb1d7e46a723afa7a2cb6c6e 100644 (file)
@@ -1937,9 +1937,12 @@ REVOKE CREATE ON SCHEMA public FROM PUBLIC;
        using <literal>ALTER ROLE <replaceable>user</replaceable> SET
        search_path = "$user"</literal>.  Everyone retains the ability to
        create objects in the public schema, but only qualified names will
-       choose those objects.  A user holding the <literal>CREATEROLE</literal>
-       privilege can undo this setting and issue arbitrary queries under the
-       identity of users relying on the setting.  If you
+       choose those objects.  While qualified table references are fine, calls
+       to functions in the public schema <link linkend="typeconv-func">will be
+       unsafe or unreliable</link>.  Also, a user holding
+       the <literal>CREATEROLE</literal> privilege can undo this setting and
+       issue arbitrary queries under the identity of users relying on the
+       setting.  If you create functions or extensions in the public schema or
        grant <literal>CREATEROLE</literal> to users not warranting this
        almost-superuser ability, use the first pattern instead.
       </para>
@@ -1950,8 +1953,10 @@ REVOKE CREATE ON SCHEMA public FROM PUBLIC;
        Remove the public schema from <varname>search_path</varname> in
        <link linkend="config-setting-configuration-file"><filename>postgresql.conf</filename></link>.
        The ensuing user experience matches the previous pattern.  In addition
-       to that pattern's implications for <literal>CREATEROLE</literal>, this
-       trusts database owners the same way.  If you assign
+       to that pattern's implications for functions
+       and <literal>CREATEROLE</literal>, this trusts database owners
+       like <literal>CREATEROLE</literal>.  If you create functions or
+       extensions in the public schema or assign
        the <literal>CREATEROLE</literal>
        privilege, <literal>CREATEDB</literal> privilege or individual database
        ownership to users not warranting almost-superuser access, use the
index ab0f29881ed454de5c21732a212af0ef949d853b..a4e18287fd57839dbdb616c237395a3d69583f5b 100644 (file)
@@ -480,8 +480,11 @@ CREATE [ OR REPLACE ] FUNCTION
        file containing the dynamically loadable object, and
        <replaceable class="parameter">link_symbol</replaceable> is the
        function's link symbol, that is, the name of the function in the C
-       language source code.  If the link symbol is omitted, it is assumed
-       to be the same as the name of the SQL function being defined.
+       language source code.  If the link symbol is omitted, it is assumed to
+       be the same as the name of the SQL function being defined.  The C names
+       of all functions must be different, so you must give overloaded C
+       functions different C names (for example, use the argument types as
+       part of the C names).
       </para>
 
       <para>
@@ -545,10 +548,9 @@ CREATE [ OR REPLACE ] FUNCTION
     <productname>PostgreSQL</productname> allows function
     <firstterm>overloading</firstterm>; that is, the same name can be
     used for several different functions so long as they have distinct
-    input argument types.  However, the C names of all functions must be
-    different, so you must give overloaded C functions different C
-    names (for example, use the argument types as part of the C
-    names).
+    input argument types.  Whether or not you use it, this capability entails
+    security precautions when calling functions in databases where some users
+    mistrust other users; see <xref linkend="typeconv-func">.
    </para>
 
    <para>
index 7f70d5056d22907b4f3c79777786935a65b0db91..b2b82dc9928d1b0d3edb17e05e8f5c1577daae8a 100644 (file)
@@ -1528,6 +1528,12 @@ sqrt(2)
     Other functions can be added by the user.
    </para>
 
+   <para>
+    When issuing queries in a database where some users mistrust other users,
+    observe security precautions from <xref linkend="typeconv-func"> when
+    writing function calls.
+   </para>
+
    <para>
     The arguments can optionally have names attached.
     See <xref linkend="sql-syntax-calling-funcs"> for details.
@@ -2409,6 +2415,8 @@ SELECT CASE WHEN min(employees) > 0
     its argument values in the same order as they are defined in the function
     declaration.  In named notation, the arguments are matched to the
     function parameters by name and can be written in any order.
+    For each notation, also consider the effect of function argument types,
+    documented in <xref linkend="typeconv-func">.
    </para>
 
    <para>
index 02959d0c9b7d01648f49093fcc1e6ca4e3d14188..58c211c440253b3f38db453b5851cc6de68294cc 100644 (file)
@@ -246,7 +246,19 @@ search path position.
 <para>
 Check for an operator accepting exactly the input argument types.
 If one exists (there can be only one exact match in the set of
-operators considered), use it.
+operators considered), use it.  Lack of an exact match creates a security
+hazard when calling, via qualified name
+  <footnote id="op-qualified-security">
+   <!-- If you edit this, consider editing func-qualified-security. -->
+   <para>
+    The hazard does not arise with a non-schema-qualified name, because a
+    search path containing schemas that permit untrusted users to create
+    objects is not a <link linkend="ddl-schemas-patterns">secure schema usage
+    pattern</link>.
+   </para>
+  </footnote>
+(not typical), any operator found in a schema that permits untrusted users to
+create objects.  In such situations, cast arguments to force an exact match.
 </para>
 
 <substeps>
@@ -589,6 +601,26 @@ function.  In that case the function appearing earlier in the search path is
 used, or if the two functions are in the same schema, the non-variadic one is
 preferred.
 </para>
+<para>
+This creates a security hazard when calling, via qualified name
+  <footnote id="func-qualified-security">
+   <!-- If you edit this, consider editing op-qualified-security. -->
+   <para>
+    The hazard does not arise with a non-schema-qualified name, because a
+    search path containing schemas that permit untrusted users to create
+    objects is not a <link linkend="ddl-schemas-patterns">secure schema usage
+    pattern</link>.
+   </para>
+  </footnote>,
+a variadic function found in a schema that permits untrusted users to create
+objects.  A malicious user can take control and execute arbitrary SQL
+functions as though you executed them.  Substitute a call bearing
+the <literal>VARIADIC</literal> keyword, which bypasses this hazard.  Calls
+populating <literal>VARIADIC "any"</literal> parameters often have no
+equivalent formulation containing the <literal>VARIADIC</literal> keyword.  To
+issue those calls safely, the function's schema must permit only trusted users
+to create objects.
+</para>
 </step>
 <step performance="optional">
 <para>
@@ -602,6 +634,15 @@ will not be able to determine which to prefer, and so an <quote>ambiguous
 function call</> error will result if no better match to the call can be
 found.
 </para>
+<para>
+This creates an availability hazard when calling, via qualified
+name<footnoteref linkend="func-qualified-security">, any function found in a
+schema that permits untrusted users to create objects.  A malicious user can
+create a function with the name of an existing function, replicating that
+function's parameters and appending novel parameters having default values.
+This precludes new calls to the original function.  To forestall this hazard,
+place functions in schemas that permit only trusted users to create objects.
+</para>
 </step>
 </substeps>
 </step>
@@ -610,9 +651,12 @@ found.
 <para>
 Check for a function accepting exactly the input argument types.
 If one exists (there can be only one exact match in the set of
-functions considered), use it.
-(Cases involving <type>unknown</type> will never find a match at
-this step.)
+functions considered), use it.  Lack of an exact match creates a security
+hazard when calling, via qualified
+name<footnoteref linkend="func-qualified-security">, a function found in a
+schema that permits untrusted users to create objects.  In such situations,
+cast arguments to force an exact match.  (Cases involving <type>unknown</type>
+will never find a match at this step.)
 </para>
 </step>
 
@@ -750,6 +794,57 @@ SELECT round(4.0, 4);
 </para>
 </example>
 
+<example>
+<title>Variadic Function Resolution</title>
+
+<para>
+<screen>
+CREATE FUNCTION public.variadic_example(VARIADIC numeric[]) RETURNS int
+  LANGUAGE sql AS 'SELECT 1';
+CREATE FUNCTION
+</screen>
+
+This function accepts, but does not require, the VARIADIC keyword.  It
+tolerates both integer and numeric arguments:
+
+<screen>
+SELECT public.variadic_example(0),
+       public.variadic_example(0.0),
+       public.variadic_example(VARIADIC array[0.0]);
+ variadic_example | variadic_example | variadic_example
+------------------+------------------+------------------
+                1 |                1 |                1
+(1 row)
+</screen>
+
+However, the first and second calls will prefer more-specific functions, if
+available:
+
+<screen>
+CREATE FUNCTION public.variadic_example(numeric) RETURNS int
+  LANGUAGE sql AS 'SELECT 2';
+CREATE FUNCTION
+
+CREATE FUNCTION public.variadic_example(int) RETURNS int
+  LANGUAGE sql AS 'SELECT 3';
+CREATE FUNCTION
+
+SELECT public.variadic_example(0),
+       public.variadic_example(0.0),
+       public.variadic_example(VARIADIC array[0.0]);
+ variadic_example | variadic_example | variadic_example
+------------------+------------------+------------------
+                3 |                2 |                1
+(1 row)
+</screen>
+
+Given the default configuration and only the first function existing, the
+first and second calls are insecure.  Any user could intercept them by
+creating the second or third function.  By matching the argument type exactly
+and using the <literal>VARIADIC</literal> keyword, the third call is secure.
+</para>
+</example>
+
 <example>
 <title>Substring Function Type Resolution</title>
 
index c41c3501a1b1f17079fb4b86d3aea6accbf5239b..c8b6ecbfad5c5784a72f4afcc4db4028e6799ffd 100644 (file)
@@ -683,8 +683,11 @@ SELECT mleast(ARRAY[10, -1, 5, 4.4]);    -- doesn't work
     <para>
      Sometimes it is useful to be able to pass an already-constructed array
      to a variadic function; this is particularly handy when one variadic
-     function wants to pass on its array parameter to another one.  You can
-     do that by specifying <literal>VARIADIC</> in the call:
+     function wants to pass on its array parameter to another one.  Also,
+     this is the only secure way to call a variadic function found in a schema
+     that permits untrusted users to create objects; see
+     <xref linkend="typeconv-func">.  You can do this by
+     specifying <literal>VARIADIC</literal> in the call:
 
 <screen>
 SELECT mleast(VARIADIC ARRAY[10, -1, 5, 4.4]);
@@ -746,7 +749,10 @@ SELECT mleast(arr := ARRAY[10, -1, 5, 4.4]);
      parameters after a parameter with a default value have to have
      default values as well.  (Although the use of named argument notation
      could allow this restriction to be relaxed, it's still enforced so that
-     positional argument notation works sensibly.)
+     positional argument notation works sensibly.)  Whether or not you use it,
+     this capability creates a need for precautions when calling functions in
+     databases where some users mistrust other users; see
+     <xref linkend="typeconv-func">.
     </para>
 
     <para>
@@ -1222,11 +1228,14 @@ $$ LANGUAGE SQL;
    <para>
     More than one function can be defined with the same SQL name, so long
     as the arguments they take are different.  In other words,
-    function names can be <firstterm>overloaded</firstterm>.  When a
-    query is executed, the server will determine which function to
-    call from the data types and the number of the provided arguments.
-    Overloading can also be used to simulate functions with a variable
-    number of arguments, up to a finite maximum number.
+    function names can be <firstterm>overloaded</firstterm>.  Whether or not
+    you use it, this capability entails security precautions when calling
+    functions in databases where some users mistrust other users; see
+    <xref linkend="typeconv-func">.  When a query is executed, the server
+    will determine which function to call from the data types and the number
+    of the provided arguments.  Overloading can also be used to simulate
+    functions with a variable number of arguments, up to a finite maximum
+    number.
    </para>
 
    <para>