On Fri, May 24, 2024 at 12:52 PM Ashutosh Sharma <ashu.coe...@gmail.com> wrote:
> Hi All, > > We all know that installing an extension typically requires superuser > privileges, which means the database objects it creates are owned by the > superuser. > > If the extension creates any SECURITY DEFINER functions, it can introduce > security vulnerabilities. For example, consider an extension that creates > the following functions, outer_func and inner_func, in the schema s1 when > installed: > > CREATE OR REPLACE FUNCTION s1.inner_func(data text) > RETURNS void AS $$ > BEGIN > INSERT INTO tab1(data_column) VALUES (data); > END; > $$ LANGUAGE plpgsql; > > CREATE OR REPLACE FUNCTION s1.outer_func(data text) > RETURNS void AS $$ > BEGIN > PERFORM inner_func(data); > END; > $$ LANGUAGE plpgsql SECURITY DEFINER; > > If a regular user creates another function with name "inner_func" with the > same signature in the public schema and sets the search path to public, s1, > the function created by the regular user in the public schema takes > precedence when outer_func is called. Since outer_func is marked as > SECURITY DEFINER, the inner_func created by the user in the public schema > is executed with superuser privileges. This allows the execution of any > statements within the function block, leading to potential security issues. > > To address this problem, one potential solution is to adjust the function > resolution logic. For instance, if the caller function belongs to a > specific schema, functions in the same schema should be given preference. > Although I haven’t reviewed the feasibility in the code, this is one > possible approach. > > Another solution could be to categorize extension-created functions to > avoid duplication. This might not be an ideal solution, but it's another > consideration worth sharing. > > Function call should schema qualify it. That's painful, but it can be avoided by setting a search path from inside the function. There was some discussion about setting a search path for a function at [1]. But the last message there is non-conclusive. We may want to extend it to extensions such that all the object references in a given extension are resolved using extension specific search_path. [1] https://www.postgresql.org/message-id/2710f56add351a1ed553efb677408e51b060e67c.camel%40j-davis.com -- Best Wishes, Ashutosh Bapat