Skip to content

Commit

Permalink
Merge pull request #192 from italomg/fix-privilege-escalation
Browse files Browse the repository at this point in the history
  • Loading branch information
marcocitus authored Jul 14, 2022
2 parents 59e2ff4 + 53a2e00 commit 7671aa0
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 10 deletions.
17 changes: 17 additions & 0 deletions expected/pg_cron-test.out
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,23 @@ SELECT username FROM cron.job where jobid=7;
pgcron_cront
(1 row)

-- Override function
DROP EXTENSION IF EXISTS pg_cron cascade;
CREATE TABLE test (data text);
DROP TYPE IF EXISTS current_setting cascade;
NOTICE: type "current_setting" does not exist, skipping
CREATE TYPE current_setting AS ENUM ('cron.database_name');
CREATE OR REPLACE FUNCTION public.func1(text, current_setting) RETURNS text
LANGUAGE sql volatile AS 'INSERT INTO test(data) VALUES (current_user); SELECT current_database();';
CREATE OR REPLACE FUNCTION public.func1(current_setting) RETURNS text
LANGUAGE sql volatile AS 'INSERT INTO test(data) VALUES (current_user); SELECT current_database();';
CREATE CAST (current_setting AS text) WITH FUNCTION public.func1(current_setting) AS IMPLICIT;
CREATE EXTENSION pg_cron VERSION '1.4';
select * from public.test;
data
------
(0 rows)

-- cleaning
DROP EXTENSION pg_cron;
drop user pgcron_cront;
Expand Down
20 changes: 10 additions & 10 deletions pg_cron.sql
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
DO $$
BEGIN
IF current_database() <> current_setting('cron.database_name') AND current_database() <> 'contrib_regression' THEN
IF pg_catalog.current_database() OPERATOR(pg_catalog.<>) pg_catalog.current_setting('cron.database_name') AND pg_catalog.current_database() OPERATOR(pg_catalog.<>) 'contrib_regression' THEN
RAISE EXCEPTION 'can only create extension in database %',
current_setting('cron.database_name')
USING DETAIL = 'Jobs must be scheduled from the database configured in '||
'cron.database_name, since the pg_cron background worker '||
pg_catalog.current_setting('cron.database_name')
USING DETAIL = 'Jobs must be scheduled from the database configured in 'OPERATOR(pg_catalog.||)
'cron.database_name, since the pg_cron background worker 'OPERATOR(pg_catalog.||)
'reads job descriptions from this database.',
HINT = format('Add cron.database_name = ''%s'' in postgresql.conf '||
'to use the current database.', current_database());
HINT = pg_catalog.format('Add cron.database_name = ''%s'' in postgresql.conf 'OPERATOR(pg_catalog.||)
'to use the current database.', pg_catalog.current_database());
END IF;
END;
$$;
Expand All @@ -16,17 +16,17 @@ CREATE SCHEMA cron;
CREATE SEQUENCE cron.jobid_seq;

CREATE TABLE cron.job (
jobid bigint primary key default nextval('cron.jobid_seq'),
jobid bigint primary key default pg_catalog.nextval('cron.jobid_seq'),
schedule text not null,
command text not null,
nodename text not null default 'localhost',
nodeport int not null default inet_server_port(),
database text not null default current_database(),
nodeport int not null default pg_catalog.inet_server_port(),
database text not null default pg_catalog.current_database(),
username text not null default current_user
);
GRANT SELECT ON cron.job TO public;
ALTER TABLE cron.job ENABLE ROW LEVEL SECURITY;
CREATE POLICY cron_job_policy ON cron.job USING (username = current_user);
CREATE POLICY cron_job_policy ON cron.job USING (username OPERATOR(pg_catalog.=) current_user);

CREATE FUNCTION cron.schedule(schedule text, command text)
RETURNS bigint
Expand Down
17 changes: 17 additions & 0 deletions sql/pg_cron-test.sql
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,23 @@ SELECT username FROM cron.job where jobid=2;
SELECT cron.schedule_in_database(job_name:='his vacuum', schedule:='0 11 * * *', command:='VACUUM',database:=current_database(), username:='pgcron_cront');
SELECT username FROM cron.job where jobid=7;

-- Override function
DROP EXTENSION IF EXISTS pg_cron cascade;
CREATE TABLE test (data text);
DROP TYPE IF EXISTS current_setting cascade;
CREATE TYPE current_setting AS ENUM ('cron.database_name');

CREATE OR REPLACE FUNCTION public.func1(text, current_setting) RETURNS text
LANGUAGE sql volatile AS 'INSERT INTO test(data) VALUES (current_user); SELECT current_database();';

CREATE OR REPLACE FUNCTION public.func1(current_setting) RETURNS text
LANGUAGE sql volatile AS 'INSERT INTO test(data) VALUES (current_user); SELECT current_database();';

CREATE CAST (current_setting AS text) WITH FUNCTION public.func1(current_setting) AS IMPLICIT;

CREATE EXTENSION pg_cron VERSION '1.4';
select * from public.test;

-- cleaning
DROP EXTENSION pg_cron;
drop user pgcron_cront;
Expand Down

0 comments on commit 7671aa0

Please sign in to comment.