Spaces:
Running
Running
| -- Task 5: Security Audit & Access Control | |
| -- | |
| -- Seeds realistic HR/project tables and three misconfigured roles plus an | |
| -- overly permissive public-schema grant. The agent must lock everything | |
| -- down via ALTER ROLE / GRANT / REVOKE. | |
| -- | |
| -- Roles are cluster-global and survive the task_schema DROP done by reset(), | |
| -- so the seed starts with an idempotent pre-clean that drops any stale roles | |
| -- from previous episodes. The task's ``teardown()`` also drops them on the | |
| -- next reset (belt and suspenders). | |
| SET search_path TO task_schema, public; | |
| -- --------------------------------------------------------------------------- | |
| -- Idempotent pre-clean: stale roles + stale public-schema grant | |
| -- --------------------------------------------------------------------------- | |
| DO $$ | |
| BEGIN | |
| IF EXISTS (SELECT FROM pg_roles WHERE rolname = 'analytics_user') THEN | |
| EXECUTE 'REASSIGN OWNED BY analytics_user TO dba'; | |
| EXECUTE 'DROP OWNED BY analytics_user'; | |
| DROP ROLE analytics_user; | |
| END IF; | |
| IF EXISTS (SELECT FROM pg_roles WHERE rolname = 'readonly_user') THEN | |
| EXECUTE 'REASSIGN OWNED BY readonly_user TO dba'; | |
| EXECUTE 'DROP OWNED BY readonly_user'; | |
| DROP ROLE readonly_user; | |
| END IF; | |
| IF EXISTS (SELECT FROM pg_roles WHERE rolname = 'intern_user') THEN | |
| EXECUTE 'REASSIGN OWNED BY intern_user TO dba'; | |
| EXECUTE 'DROP OWNED BY intern_user'; | |
| DROP ROLE intern_user; | |
| END IF; | |
| END $$; | |
| REVOKE CREATE ON SCHEMA public FROM PUBLIC; | |
| -- --------------------------------------------------------------------------- | |
| -- Tables | |
| -- --------------------------------------------------------------------------- | |
| CREATE TABLE IF NOT EXISTS employees ( | |
| id SERIAL PRIMARY KEY, | |
| name VARCHAR(100) NOT NULL, | |
| department VARCHAR(50) NOT NULL, | |
| hire_date DATE NOT NULL | |
| ); | |
| INSERT INTO employees (name, department, hire_date) | |
| SELECT | |
| 'Employee ' || i AS name, | |
| (ARRAY['Engineering','Sales','HR','Marketing','Finance'])[1 + (i % 5)] AS department, | |
| (DATE '2020-01-01') + ((i * 7) % 1500) AS hire_date | |
| FROM generate_series(1, 100) AS gs(i); | |
| CREATE TABLE IF NOT EXISTS salaries ( | |
| id SERIAL PRIMARY KEY, | |
| employee_id INT REFERENCES employees(id), | |
| amount DECIMAL(10,2) NOT NULL, | |
| effective_date DATE NOT NULL | |
| ); | |
| INSERT INTO salaries (employee_id, amount, effective_date) | |
| SELECT | |
| ((i - 1) % 100) + 1 AS employee_id, | |
| (50000 + ((i * 137) % 50000))::DECIMAL(10,2) AS amount, | |
| (DATE '2023-01-01') + ((i * 3) % 365) AS effective_date | |
| FROM generate_series(1, 100) AS gs(i); | |
| CREATE TABLE IF NOT EXISTS projects ( | |
| id SERIAL PRIMARY KEY, | |
| name VARCHAR(100) NOT NULL, | |
| budget DECIMAL(12,2) NOT NULL, | |
| status VARCHAR(20) NOT NULL | |
| ); | |
| INSERT INTO projects (name, budget, status) | |
| SELECT | |
| 'Project ' || i AS name, | |
| (100000 + (i * 13000))::DECIMAL(12,2) AS budget, | |
| (ARRAY['planning','active','completed','on_hold'])[1 + (i % 4)] AS status | |
| FROM generate_series(1, 20) AS gs(i); | |
| CREATE TABLE IF NOT EXISTS project_assignments ( | |
| employee_id INT, | |
| project_id INT, | |
| role VARCHAR(50) NOT NULL, | |
| PRIMARY KEY (employee_id, project_id) | |
| ); | |
| INSERT INTO project_assignments (employee_id, project_id, role) | |
| SELECT | |
| ((i * 7) % 100) + 1 AS employee_id, | |
| ((i * 3) % 20) + 1 AS project_id, | |
| (ARRAY['lead','engineer','reviewer','qa'])[1 + (i % 4)] AS role | |
| FROM generate_series(1, 50) AS gs(i) | |
| ON CONFLICT DO NOTHING; | |
| -- --------------------------------------------------------------------------- | |
| -- Seed the four security issues | |
| -- --------------------------------------------------------------------------- | |
| -- Issue 1: analytics_user has SUPERUSER (should be NOSUPERUSER). | |
| CREATE ROLE analytics_user WITH LOGIN PASSWORD 'analytics123' SUPERUSER; | |
| -- Issue 2: PUBLIC can CREATE objects in the public schema. | |
| GRANT CREATE ON SCHEMA public TO PUBLIC; | |
| -- Issue 3: readonly_user can SELECT task_schema.salaries (sensitive data leak). | |
| CREATE ROLE readonly_user WITH LOGIN PASSWORD 'readonly123'; | |
| GRANT USAGE ON SCHEMA task_schema TO readonly_user; | |
| GRANT SELECT ON ALL TABLES IN SCHEMA task_schema TO readonly_user; | |
| -- Issue 4: intern_user has no password (passwordless LOGIN role). | |
| CREATE ROLE intern_user WITH LOGIN; | |
| GRANT USAGE ON SCHEMA task_schema TO intern_user; | |
| GRANT SELECT ON employees, projects, project_assignments TO intern_user; | |
| ANALYZE employees; | |
| ANALYZE salaries; | |
| ANALYZE projects; | |
| ANALYZE project_assignments; | |