haochengsama's picture
Add files using upload-large-folder tool
a2ec7b6 verified
Raw
History Blame Contribute Delete
22.4 kB
-- Ground Truth Solution: Complete Security Audit Implementation
-- This includes comprehensive PostgreSQL user, role, and permission discovery
/*
================================================================================
PERMISSION MODEL DOCUMENTATION
================================================================================
## Current Permission State
| Username | Table | Permission | Status | Reason |
|-------------------|------------------------|------------|---------|-------------------------------------------|
| analytics_user | user_stat_analysis | SELECT | EXISTS | Correctly granted |
| analytics_user | user_profiles | SELECT | MISSING | Permission was revoked |
| analytics_user | financial_transactions | SELECT | EXISTS | Should be revoked - no business need |
| marketing_user | user_profiles | SELECT | EXISTS | Correctly granted |
| marketing_user | user_stat_analysis | SELECT | EXISTS | Correctly granted |
| marketing_user | product_catalog | SELECT | MISSING | Permission was revoked |
| marketing_user | financial_transactions | SELECT | EXISTS | Should be revoked - security risk |
| customer_service | user_profiles | SELECT | EXISTS | Correctly granted |
| customer_service | user_profiles | UPDATE | EXISTS | Correctly granted |
| customer_service | order_management | SELECT | EXISTS | Correctly granted |
| customer_service | order_management | INSERT | EXISTS | Correctly granted |
| customer_service | order_management | UPDATE | EXISTS | Correctly granted |
| customer_service | product_catalog | SELECT | MISSING | Permission was revoked |
| customer_service | user_credentials | SELECT | EXISTS | Should be revoked - security risk |
| finance_user | financial_transactions | SELECT | EXISTS | Correctly granted |
| finance_user | order_management | SELECT | EXISTS | Correctly granted |
| finance_user | user_profiles | SELECT | MISSING | Permission was revoked |
| product_manager | product_catalog | SELECT | EXISTS | Correctly granted |
| product_manager | product_catalog | INSERT | EXISTS | Correctly granted |
| product_manager | product_catalog | UPDATE | EXISTS | Correctly granted |
| product_manager | product_catalog | DELETE | EXISTS | Correctly granted |
| product_manager | order_management | SELECT | EXISTS | Correctly granted |
| product_manager | financial_transactions | SELECT | EXISTS | Should be revoked - no business need |
| security_auditor | user_credentials | SELECT | EXISTS | Correctly granted |
| security_auditor | user_profiles | SELECT | EXISTS | Correctly granted |
| security_auditor | audit_logs | SELECT | MISSING | Permission was revoked |
| security_auditor | financial_transactions | UPDATE | EXISTS | Should be revoked - excessive privilege |
| developer_user | user_profiles | SELECT | EXISTS | Correctly granted |
| developer_user | product_catalog | SELECT | MISSING | Permission was revoked |
| developer_user | user_credentials | SELECT | EXISTS | Should be revoked - security risk |
| developer_user | order_management | UPDATE | EXISTS | Should be revoked - no business need |
| backup_user | user_profiles | SELECT | EXISTS | Correctly granted |
| backup_user | product_catalog | SELECT | EXISTS | Correctly granted |
| backup_user | audit_logs | SELECT | EXISTS | Correctly granted |
| backup_user | order_management | SELECT | MISSING | Permission was revoked |
| backup_user | product_catalog | DELETE | EXISTS | Should be revoked - backup should be read-only |
| temp_contractor | product_catalog | SELECT | EXISTS | Should be revoked - user is inactive |
| temp_contractor | user_profiles | SELECT | EXISTS | Should be revoked - user is inactive |
| old_employee | audit_logs | SELECT | EXISTS | Should be revoked - user is inactive |
| old_employee | user_stat_analysis | UPDATE | EXISTS | Should be revoked - user is inactive |
| test_account | user_profiles | SELECT | EXISTS | Should be revoked - test account |
## Expected Permission State
| Username | Table | Permission | Justification |
|-------------------|------------------------|------------|--------------------------------------------------------------|
| analytics_user | user_profiles | SELECT | Analytics team needs customer data for user behavior analysis|
| analytics_user | user_stat_analysis | SELECT | Core analytics data required for reporting |
| analytics_user | product_catalog | SELECT | Product performance analysis and customer preferences |
| analytics_user | order_management | SELECT | Sales trend analysis and customer purchasing patterns |
| marketing_user | user_profiles | SELECT | Customer segmentation and personalized marketing campaigns |
| marketing_user | user_stat_analysis | SELECT | Campaign effectiveness analysis and user behavior tracking |
| marketing_user | product_catalog | SELECT | Product promotion planning and marketing material creation |
| customer_service | user_profiles | SELECT | Customer identity verification and support |
| customer_service | user_profiles | UPDATE | Update customer information and resolve account issues |
| customer_service | order_management | SELECT | Order status inquiries and customer support |
| customer_service | order_management | INSERT | Create orders for customers over phone |
| customer_service | order_management | UPDATE | Update order status and resolve order issues |
| customer_service | product_catalog | SELECT | Product information for customer questions and support |
| finance_user | financial_transactions | SELECT | Financial reporting, auditing, and compliance |
| finance_user | order_management | SELECT | Revenue reconciliation and financial analysis |
| finance_user | user_profiles | SELECT | Customer financial analysis and credit assessment |
| product_manager | product_catalog | SELECT | Product information access and management |
| product_manager | product_catalog | INSERT | Add new products to catalog |
| product_manager | product_catalog | UPDATE | Update product details, pricing, and specifications |
| product_manager | product_catalog | DELETE | Remove discontinued or obsolete products |
| product_manager | order_management | SELECT | Product sales analysis and demand forecasting |
| product_manager | user_stat_analysis | SELECT | Product usage analytics and customer behavior insights |
| security_auditor | audit_logs | SELECT | Security monitoring and incident investigation |
| security_auditor | user_credentials | SELECT | Security auditing and compliance verification |
| security_auditor | user_profiles | SELECT | User account auditing and security incident investigation |
| developer_user | user_profiles | SELECT | Application development and testing with realistic data |
| developer_user | product_catalog | SELECT | Application development and testing with product data |
| backup_user | user_profiles | SELECT | Complete data backup coverage for business continuity |
| backup_user | product_catalog | SELECT | Complete data backup coverage for business continuity |
| backup_user | order_management | SELECT | Complete data backup coverage for business continuity |
| backup_user | financial_transactions | SELECT | Complete data backup coverage for business continuity |
| backup_user | user_stat_analysis | SELECT | Complete data backup coverage for business continuity |
| backup_user | audit_logs | SELECT | Complete data backup coverage for business continuity |
| backup_user | user_credentials | SELECT | Complete data backup coverage for business continuity |
Notes:
- temp_contractor, old_employee, test_account should have NO permissions (accounts should be removed)
- All excessive permissions should be revoked for security compliance
- Missing permissions should be granted based on business role requirements
================================================================================
*/
BEGIN;
-- ============================================================================
-- CREATE AUDIT RESULTS TABLES
-- ============================================================================
CREATE TABLE security_audit_results (
audit_id SERIAL PRIMARY KEY,
audit_type VARCHAR(50) NOT NULL, -- 'DANGLING_USERS', 'MISSING_PERMISSIONS', 'EXCESSIVE_PERMISSIONS'
total_issues INTEGER NOT NULL,
users_affected INTEGER NOT NULL,
tables_affected INTEGER NOT NULL
);
CREATE TABLE security_audit_details (
detail_id SERIAL PRIMARY KEY,
username VARCHAR(50) NOT NULL,
issue_type VARCHAR(50) NOT NULL, -- 'DANGLING_USER', 'MISSING_PERMISSION', 'EXCESSIVE_PERMISSION'
table_name VARCHAR(50), -- NULL for dangling users
permission_type VARCHAR(20), -- 'SELECT', 'INSERT', 'UPDATE', 'DELETE', NULL for dangling users
expected_access BOOLEAN NOT NULL -- TRUE if user should have access, FALSE if should not
);
-- ============================================================================
-- DISCOVER DATABASE USERS AND ROLES
-- ============================================================================
CREATE TEMP TABLE temp_user_discovery AS
SELECT DISTINCT
COALESCE(u.usename, r.rolname) as username,
COALESCE(u.usesuper, r.rolsuper) as is_superuser,
COALESCE(u.usecreatedb, r.rolcreatedb) as can_create_db,
r.rolname as role_name,
u.usename as user_name,
CASE
WHEN COALESCE(u.usename, r.rolname) LIKE '%analytics%' THEN 'Analytics Team'
WHEN COALESCE(u.usename, r.rolname) LIKE '%marketing%' THEN 'Marketing Department'
WHEN COALESCE(u.usename, r.rolname) LIKE '%customer%' OR COALESCE(u.usename, r.rolname) LIKE '%service%' THEN 'Customer Service'
WHEN COALESCE(u.usename, r.rolname) LIKE '%finance%' THEN 'Finance Team'
WHEN COALESCE(u.usename, r.rolname) LIKE '%product%' THEN 'Product Management'
WHEN COALESCE(u.usename, r.rolname) LIKE '%security%' OR COALESCE(u.usename, r.rolname) LIKE '%audit%' THEN 'Security Team'
WHEN COALESCE(u.usename, r.rolname) LIKE '%backup%' THEN 'Backup Service'
WHEN COALESCE(u.usename, r.rolname) LIKE '%developer%' OR COALESCE(u.usename, r.rolname) LIKE '%dev%' THEN 'Development Team'
WHEN COALESCE(u.usename, r.rolname) LIKE '%temp%' OR COALESCE(u.usename, r.rolname) LIKE '%old%' OR COALESCE(u.usename, r.rolname) LIKE '%test%' THEN 'Inactive/Temporary'
ELSE 'Unknown'
END as inferred_business_role
FROM pg_user u
FULL OUTER JOIN pg_roles r ON u.usename = r.rolname
WHERE COALESCE(u.usename, r.rolname) NOT IN ('postgres', 'test_user')
AND COALESCE(u.usename, r.rolname) IS NOT NULL;
-- ============================================================================
-- DISCOVER ROLE MEMBERSHIPS
-- ============================================================================
CREATE TEMP TABLE temp_role_memberships AS
SELECT
member_role.rolname as member_name,
granted_role.rolname as granted_role_name,
grantor_role.rolname as grantor_name,
am.admin_option
FROM pg_auth_members am
JOIN pg_roles member_role ON am.member = member_role.oid
JOIN pg_roles granted_role ON am.roleid = granted_role.oid
JOIN pg_roles grantor_role ON am.grantor = grantor_role.oid
WHERE member_role.rolname NOT IN ('postgres')
AND granted_role.rolname NOT IN ('postgres');
-- ============================================================================
-- ANALYZE CURRENT PERMISSIONS
-- ============================================================================
CREATE TEMP TABLE temp_current_permissions AS
SELECT DISTINCT
tp.grantee as username,
tp.table_name,
tp.privilege_type as permission_type,
tp.is_grantable,
tp.grantor,
ud.inferred_business_role,
ud.is_superuser
FROM information_schema.table_privileges tp
LEFT JOIN temp_user_discovery ud ON tp.grantee = ud.username
WHERE tp.table_schema = 'public'
AND tp.grantee NOT IN ('postgres', 'PUBLIC', 'test_user')
AND tp.table_name NOT LIKE 'security_audit_%'
ORDER BY tp.grantee, tp.table_name, tp.privilege_type;
-- ============================================================================
-- IDENTIFY DANGLING USERS
-- ============================================================================
INSERT INTO security_audit_details (username, issue_type, table_name, permission_type, expected_access)
SELECT DISTINCT
username,
'DANGLING_USER',
NULL,
NULL,
FALSE
FROM temp_user_discovery
WHERE inferred_business_role = 'Inactive/Temporary';
-- ============================================================================
-- IDENTIFY EXCESSIVE PERMISSIONS
-- ============================================================================
WITH excessive_permissions AS (
SELECT username, table_name, permission_type FROM (VALUES
('analytics_user', 'financial_transactions', 'SELECT'),
('marketing_user', 'financial_transactions', 'SELECT'),
('customer_service', 'user_credentials', 'SELECT'),
('product_manager', 'financial_transactions', 'SELECT'),
('security_auditor', 'financial_transactions', 'UPDATE'),
('developer_user', 'user_credentials', 'SELECT'),
('developer_user', 'order_management', 'UPDATE'),
('backup_user', 'product_catalog', 'DELETE'),
('temp_contractor', 'product_catalog', 'SELECT'),
('temp_contractor', 'user_profiles', 'SELECT'),
('old_employee', 'audit_logs', 'SELECT'),
('old_employee', 'user_stat_analysis', 'UPDATE'),
('test_account', 'user_profiles', 'SELECT')
) AS excessive(username, table_name, permission_type)
)
INSERT INTO security_audit_details (username, issue_type, table_name, permission_type, expected_access)
SELECT
ep.username,
'EXCESSIVE_PERMISSION',
ep.table_name,
ep.permission_type,
FALSE
FROM excessive_permissions ep
WHERE EXISTS (
SELECT 1 FROM temp_current_permissions cp
WHERE cp.username = ep.username
AND cp.table_name = ep.table_name
AND cp.permission_type = ep.permission_type
);
-- ============================================================================
-- IDENTIFY MISSING PERMISSIONS
-- ============================================================================
WITH expected_permissions AS (
SELECT role_name, table_name, permission_type FROM (VALUES
('Analytics Team', 'user_profiles', 'SELECT'),
('Analytics Team', 'user_stat_analysis', 'SELECT'),
('Analytics Team', 'product_catalog', 'SELECT'),
('Analytics Team', 'order_management', 'SELECT'),
('Marketing Department', 'user_profiles', 'SELECT'),
('Marketing Department', 'user_stat_analysis', 'SELECT'),
('Marketing Department', 'product_catalog', 'SELECT'),
('Customer Service', 'user_profiles', 'SELECT'),
('Customer Service', 'user_profiles', 'UPDATE'),
('Customer Service', 'order_management', 'SELECT'),
('Customer Service', 'order_management', 'INSERT'),
('Customer Service', 'order_management', 'UPDATE'),
('Customer Service', 'product_catalog', 'SELECT'),
('Finance Team', 'financial_transactions', 'SELECT'),
('Finance Team', 'order_management', 'SELECT'),
('Finance Team', 'user_profiles', 'SELECT'),
('Product Management', 'product_catalog', 'SELECT'),
('Product Management', 'product_catalog', 'INSERT'),
('Product Management', 'product_catalog', 'UPDATE'),
('Product Management', 'product_catalog', 'DELETE'),
('Product Management', 'order_management', 'SELECT'),
('Product Management', 'user_stat_analysis', 'SELECT'),
('Security Team', 'audit_logs', 'SELECT'),
('Security Team', 'user_credentials', 'SELECT'),
('Security Team', 'user_profiles', 'SELECT'),
('Development Team', 'user_profiles', 'SELECT'),
('Development Team', 'product_catalog', 'SELECT'),
('Backup Service', 'user_profiles', 'SELECT'),
('Backup Service', 'product_catalog', 'SELECT'),
('Backup Service', 'order_management', 'SELECT'),
('Backup Service', 'financial_transactions', 'SELECT'),
('Backup Service', 'user_stat_analysis', 'SELECT'),
('Backup Service', 'audit_logs', 'SELECT'),
('Backup Service', 'user_credentials', 'SELECT')
) AS expected(role_name, table_name, permission_type)
)
INSERT INTO security_audit_details (username, issue_type, table_name, permission_type, expected_access)
SELECT DISTINCT
ud.username,
'MISSING_PERMISSION',
ep.table_name,
ep.permission_type,
TRUE
FROM temp_user_discovery ud
JOIN expected_permissions ep ON ud.inferred_business_role = ep.role_name
LEFT JOIN temp_current_permissions cp ON (
cp.username = ud.username
AND cp.table_name = ep.table_name
AND cp.permission_type = ep.permission_type
)
WHERE cp.username IS NULL
AND ud.inferred_business_role != 'Inactive/Temporary'
AND ud.inferred_business_role != 'Unknown'
AND EXISTS (
SELECT 1 FROM information_schema.tables t
WHERE t.table_name = ep.table_name
AND t.table_schema = 'public'
AND t.table_type = 'BASE TABLE'
);
-- ============================================================================
-- POPULATE SUMMARY STATISTICS
-- ============================================================================
INSERT INTO security_audit_results (audit_type, total_issues, users_affected, tables_affected)
SELECT
'DANGLING_USERS',
COUNT(*),
COUNT(DISTINCT username),
0
FROM security_audit_details
WHERE issue_type = 'DANGLING_USER';
INSERT INTO security_audit_results (audit_type, total_issues, users_affected, tables_affected)
SELECT
'MISSING_PERMISSIONS',
COUNT(*),
COUNT(DISTINCT username),
COUNT(DISTINCT table_name)
FROM security_audit_details
WHERE issue_type = 'MISSING_PERMISSION';
INSERT INTO security_audit_results (audit_type, total_issues, users_affected, tables_affected)
SELECT
'EXCESSIVE_PERMISSIONS',
COUNT(*),
COUNT(DISTINCT username),
COUNT(DISTINCT table_name)
FROM security_audit_details
WHERE issue_type = 'EXCESSIVE_PERMISSION';
-- ============================================================================
-- CLEANUP TEMPORARY TABLES
-- ============================================================================
DROP TABLE temp_user_discovery;
DROP TABLE temp_role_memberships;
DROP TABLE temp_current_permissions;
COMMIT;
-- ============================================================================
-- DISCOVERY AND VERIFICATION QUERIES
-- ============================================================================
-- Show all users and their properties
SELECT
usename as username,
usesuper as is_superuser,
usecreatedb as can_create_db,
valuntil as password_expiry
FROM pg_user
WHERE usename NOT IN ('postgres', 'test_user')
ORDER BY usename;
-- Show all roles and their properties
SELECT
rolname as role_name,
rolsuper as is_superuser,
rolinherit as inherits_privileges,
rolcanlogin as can_login
FROM pg_roles
WHERE rolname NOT LIKE 'pg_%'
AND rolname NOT IN ('postgres', 'test_user')
ORDER BY rolname;
-- Show current table privileges
SELECT
grantee as username,
table_name,
privilege_type as permission,
is_grantable
FROM information_schema.table_privileges
WHERE table_schema = 'public'
AND grantee NOT IN ('postgres', 'PUBLIC', 'test_user')
AND table_name NOT LIKE 'security_audit_%'
ORDER BY grantee, table_name, privilege_type;
-- Show role memberships
SELECT
member.rolname as member,
granted.rolname as granted_role
FROM pg_auth_members am
JOIN pg_roles member ON am.member = member.oid
JOIN pg_roles granted ON am.roleid = granted.oid
WHERE member.rolname NOT IN ('postgres')
ORDER BY member.rolname, granted.rolname;
-- Display audit summary
SELECT
audit_type,
total_issues,
users_affected,
tables_affected
FROM security_audit_results
ORDER BY audit_type;
-- Display detailed findings
SELECT
username,
issue_type,
COALESCE(table_name, 'N/A') as table_name,
COALESCE(permission_type, 'N/A') as permission_type,
expected_access
FROM security_audit_details
ORDER BY issue_type, username, table_name;