diff --git a/HISTORY.asc b/HISTORY.asc index 23a761b..a32b581 100644 --- a/HISTORY.asc +++ b/HISTORY.asc @@ -2,6 +2,9 @@ STABLE ------ === Adopt the `stable` pseudo-version between releases +=== Add `pg_temp` to the `search_path` of the `SECURITY DEFINER` functions +They now use `SET search_path = pg_catalog, pg_temp`, so `pg_temp` is searched last rather than first. Updated installs get this from `0.3.3--stable`. + === Add `0.2.0--0.2.1` update script `ALTER EXTENSION trunklet UPDATE` now works from 0.2.0. Previously there was no update path from 0.2.0. Updated installs now also match a fresh install: the `language__get()` debug message that a fresh 0.3.3 install has is added by `0.3.3--stable` and was retroactively added to the already-released `0.3.2--0.3.3` update script. diff --git a/sql/trunklet--0.3.3--stable.sql b/sql/trunklet--0.3.3--stable.sql index 3d345ef..29ef06d 100644 --- a/sql/trunklet--0.3.3--stable.sql +++ b/sql/trunklet--0.3.3--stable.sql @@ -19,3 +19,12 @@ EXCEPTION ; END $body$; + +-- Match the SECURITY DEFINER search_path in a fresh install +ALTER FUNCTION trunklet.template__add(character varying, text, integer, text) SET search_path = pg_catalog, pg_temp; +ALTER FUNCTION trunklet.template__remove(integer) SET search_path = pg_catalog, pg_temp; +ALTER FUNCTION trunklet.template__remove(text, integer) SET search_path = pg_catalog, pg_temp; +ALTER FUNCTION trunklet.process_language(character varying, text, anyelement) SET search_path = pg_catalog, pg_temp; +ALTER FUNCTION trunklet.process(integer, anyelement) SET search_path = pg_catalog, pg_temp; +ALTER FUNCTION trunklet.process(text, integer, anyelement) SET search_path = pg_catalog, pg_temp; +ALTER FUNCTION trunklet.extract_parameters(character varying, anyelement, text[]) SET search_path = pg_catalog, pg_temp; diff --git a/sql/trunklet.sql b/sql/trunklet.sql index a56988a..c88b610 100644 --- a/sql/trunklet.sql +++ b/sql/trunklet.sql @@ -557,7 +557,7 @@ CREATE OR REPLACE FUNCTION trunklet.template__add( ) RETURNS _trunklet.template.template_id%TYPE -- !!!!!!! -SECURITY DEFINER SET search_path=pg_catalog +SECURITY DEFINER SET search_path = pg_catalog, pg_temp -- !!!!!! LANGUAGE sql AS $body$ @@ -588,7 +588,7 @@ CREATE OR REPLACE FUNCTION trunklet.template__remove( ) RETURNS void -- !!!!!!! -SECURITY DEFINER SET search_path=pg_catalog +SECURITY DEFINER SET search_path = pg_catalog, pg_temp -- !!!!!! LANGUAGE sql AS $body$ @@ -600,7 +600,7 @@ CREATE OR REPLACE FUNCTION trunklet.template__remove( ) RETURNS void -- !!!!!!! -SECURITY DEFINER SET search_path=pg_catalog +SECURITY DEFINER SET search_path = pg_catalog, pg_temp -- !!!!!! LANGUAGE sql AS $body$ @@ -679,7 +679,7 @@ CREATE OR REPLACE FUNCTION trunklet.process_language( ) RETURNS text LANGUAGE plpgsql -- !!!!!!! -SECURITY DEFINER SET search_path = pg_catalog +SECURITY DEFINER SET search_path = pg_catalog, pg_temp -- !!!!!!! AS $body$ @@ -720,7 +720,7 @@ CREATE OR REPLACE FUNCTION trunklet.process( , parameters anyelement ) RETURNS text LANGUAGE SQL -- !!! -SECURITY DEFINER SET search_path = pg_catalog +SECURITY DEFINER SET search_path = pg_catalog, pg_temp -- !!! AS $body$ SELECT trunklet.process_language( @@ -737,7 +737,7 @@ CREATE OR REPLACE FUNCTION trunklet.process( , parameters anyelement ) RETURNS text LANGUAGE SQL -- !!! -SECURITY DEFINER SET search_path = pg_catalog +SECURITY DEFINER SET search_path = pg_catalog, pg_temp -- !!! AS $body$ SELECT trunklet.process_language( @@ -902,7 +902,7 @@ CREATE OR REPLACE FUNCTION trunklet.extract_parameters( ) RETURNS anyelement LANGUAGE plpgsql -- !!!!!!! -SECURITY DEFINER SET search_path = pg_catalog +SECURITY DEFINER SET search_path = pg_catalog, pg_temp -- !!!!!!! AS $body$ diff --git a/test/core/functions.sql b/test/core/functions.sql index 76bb94f..927f97c 100644 --- a/test/core/functions.sql +++ b/test/core/functions.sql @@ -615,18 +615,23 @@ BEGIN ) a ; + -- Exact value: pg_temp must come after pg_catalog or it can shadow it RETURN QUERY SELECT is( proconfig - , '{search_path=pg_catalog}' + , ARRAY['search_path=pg_catalog, pg_temp'] , 'Verify search_path for ' || full_name ) -- This silliness is necessary to ensure stable ordering of the test FROM ( - SELECT *, p.oid::regprocedure AS full_name + SELECT p.proconfig, p.oid::regprocedure AS full_name FROM pg_proc p - JOIN pg_namespace n ON n.oid = p.pronamespace - WHERE nspname = 'trunklet' - AND prosecdef + JOIN pg_depend d + ON d.classid = 'pg_proc'::regclass + AND d.objid = p.oid + AND d.deptype = 'e' + AND d.refclassid = 'pg_extension'::regclass + AND d.refobjid = (SELECT oid FROM pg_extension WHERE extname = 'trunklet') + WHERE prosecdef -- Cast to text is necessary to avoid ordering by the actual OID in -- 9.5. COLLATE is necessary to ensure a consistent order. ORDER BY p.oid::regprocedure::text COLLATE "C"