Updated Version of initial Release
This commit is contained in:
parent
bcf23f98ad
commit
ec1c0987ae
728
BEST_PRACTICES.md
Normal file
728
BEST_PRACTICES.md
Normal file
@ -0,0 +1,728 @@
|
|||||||
|
# c77_secure_db Best Practices Guide
|
||||||
|
|
||||||
|
This document provides comprehensive security best practices for implementing and maintaining c77_secure_db in production environments.
|
||||||
|
|
||||||
|
## 🛡️ **Core Security Principles**
|
||||||
|
|
||||||
|
### 1. **Never Bypass Security Controls**
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- ❌ NEVER DO THIS - Will be blocked but shows intent to bypass
|
||||||
|
INSERT INTO secure_table (name) VALUES ('data');
|
||||||
|
UPDATE secure_table SET value = 'changed' WHERE id = 1;
|
||||||
|
DELETE FROM secure_table WHERE id = 1;
|
||||||
|
|
||||||
|
-- ✅ ALWAYS DO THIS - Use secure operations
|
||||||
|
SELECT c77_secure_db_operation(jsonb_build_object(
|
||||||
|
'schema_name', 'myapp',
|
||||||
|
'table_name', 'secure_table',
|
||||||
|
'operation', 'insert',
|
||||||
|
'data', jsonb_build_object('name', 'data')
|
||||||
|
));
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. **Validate All Inputs**
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- ❌ BAD - No validation
|
||||||
|
SELECT c77_secure_db_operation(user_input::jsonb);
|
||||||
|
|
||||||
|
-- ✅ GOOD - Validate structure and content
|
||||||
|
DO $$
|
||||||
|
DECLARE
|
||||||
|
v_input jsonb := user_input::jsonb;
|
||||||
|
BEGIN
|
||||||
|
-- Validate required fields
|
||||||
|
IF NOT (v_input ? 'schema_name' AND v_input ? 'table_name' AND v_input ? 'operation') THEN
|
||||||
|
RAISE EXCEPTION 'Missing required fields in operation data';
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
-- Validate operation type
|
||||||
|
IF NOT (v_input->>'operation') IN ('insert', 'update', 'upsert', 'delete', 'soft_delete') THEN
|
||||||
|
RAISE EXCEPTION 'Invalid operation type';
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
-- Proceed with validated input
|
||||||
|
PERFORM c77_secure_db_operation(v_input);
|
||||||
|
END $$;
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. **Implement Proper Error Handling**
|
||||||
|
|
||||||
|
```php
|
||||||
|
// ✅ Laravel Example - Comprehensive error handling
|
||||||
|
public function secureOperation(array $data): array
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$result = DB::selectOne(
|
||||||
|
'SELECT c77_secure_db_operation(?) as result',
|
||||||
|
[json_encode($data)]
|
||||||
|
);
|
||||||
|
|
||||||
|
$response = json_decode($result->result, true);
|
||||||
|
|
||||||
|
if (!$response['success']) {
|
||||||
|
// Log security-relevant failures
|
||||||
|
Log::warning('Secure operation failed', [
|
||||||
|
'operation' => $data['operation'],
|
||||||
|
'table' => $data['table_name'],
|
||||||
|
'error' => $response['error'],
|
||||||
|
'operation_id' => $response['operation_id'] ?? null,
|
||||||
|
'user_id' => auth()->id()
|
||||||
|
]);
|
||||||
|
|
||||||
|
throw new SecureDbException($response['error']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $response;
|
||||||
|
|
||||||
|
} catch (Exception $e) {
|
||||||
|
// Never expose internal error details to users
|
||||||
|
Log::error('Secure DB exception', [
|
||||||
|
'error' => $e->getMessage(),
|
||||||
|
'data' => $data,
|
||||||
|
'user_id' => auth()->id()
|
||||||
|
]);
|
||||||
|
|
||||||
|
throw new SecureDbException('Operation failed due to security constraints');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔐 **Access Control Best Practices**
|
||||||
|
|
||||||
|
### 1. **Role-Based Permissions**
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- Create application-specific roles
|
||||||
|
CREATE ROLE myapp_read_only;
|
||||||
|
CREATE ROLE myapp_operator;
|
||||||
|
CREATE ROLE myapp_administrator;
|
||||||
|
|
||||||
|
-- Grant appropriate secure database roles
|
||||||
|
GRANT c77_secure_db_readonly TO myapp_read_only;
|
||||||
|
GRANT c77_secure_db_user TO myapp_operator;
|
||||||
|
GRANT c77_secure_db_admin TO myapp_administrator;
|
||||||
|
|
||||||
|
-- Assign users to roles (never grant c77_secure_db roles directly)
|
||||||
|
GRANT myapp_operator TO app_user;
|
||||||
|
GRANT myapp_read_only TO reporting_user;
|
||||||
|
GRANT myapp_administrator TO dba_user;
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. **RBAC Integration**
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- Define granular permissions
|
||||||
|
SELECT c77_rbac_grant_feature('data_entry_clerk', 'secure_db_insert');
|
||||||
|
SELECT c77_rbac_grant_feature('data_manager', 'secure_db_insert');
|
||||||
|
SELECT c77_rbac_grant_feature('data_manager', 'secure_db_update');
|
||||||
|
SELECT c77_rbac_grant_feature('supervisor', 'secure_db_delete');
|
||||||
|
SELECT c77_rbac_grant_feature('auditor', 'secure_db_admin');
|
||||||
|
|
||||||
|
-- Use scope-based access control
|
||||||
|
SELECT c77_rbac_assign_subject('emp_001', 'data_entry_clerk', 'department', 'sales');
|
||||||
|
SELECT c77_rbac_assign_subject('emp_002', 'data_manager', 'region', 'north_america');
|
||||||
|
SELECT c77_rbac_assign_subject('emp_003', 'supervisor', 'global', 'all');
|
||||||
|
|
||||||
|
-- Always set user context in applications
|
||||||
|
SET "c77_rbac.external_id" TO 'current_user_id';
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. **Principle of Least Privilege**
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- ❌ BAD - Overly broad permissions
|
||||||
|
GRANT c77_secure_db_admin TO app_user;
|
||||||
|
|
||||||
|
-- ✅ GOOD - Minimal necessary permissions
|
||||||
|
GRANT c77_secure_db_user TO app_user;
|
||||||
|
|
||||||
|
-- ❌ BAD - Global access for everyone
|
||||||
|
SELECT c77_rbac_assign_subject('user_123', 'admin', 'global', 'all');
|
||||||
|
|
||||||
|
-- ✅ GOOD - Scoped access
|
||||||
|
SELECT c77_rbac_assign_subject('user_123', 'operator', 'department', 'finance');
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔍 **Data Integrity Best Practices**
|
||||||
|
|
||||||
|
### 1. **Regular Integrity Verification**
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- Daily verification of critical tables
|
||||||
|
CREATE OR REPLACE FUNCTION daily_integrity_check()
|
||||||
|
RETURNS void LANGUAGE plpgsql AS $$
|
||||||
|
DECLARE
|
||||||
|
v_result jsonb;
|
||||||
|
v_critical_tables text[] := ARRAY['users', 'transactions', 'audit_logs'];
|
||||||
|
v_table text;
|
||||||
|
BEGIN
|
||||||
|
FOREACH v_table IN ARRAY v_critical_tables LOOP
|
||||||
|
SELECT c77_secure_db_verify_content_hashes('myapp', v_table) INTO v_result;
|
||||||
|
|
||||||
|
IF (v_result->>'mismatch_count')::integer > 0 THEN
|
||||||
|
RAISE EXCEPTION 'CRITICAL: Data integrity violation detected in table %', v_table
|
||||||
|
USING HINT = 'Immediate investigation required',
|
||||||
|
ERRCODE = 'data_corrupted';
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
RAISE NOTICE 'Integrity check passed for table %: % records verified',
|
||||||
|
v_table, v_result->>'total_records';
|
||||||
|
END LOOP;
|
||||||
|
END;
|
||||||
|
$$;
|
||||||
|
|
||||||
|
-- Schedule daily execution
|
||||||
|
SELECT cron.schedule('daily-integrity-check', '0 1 * * *', 'SELECT daily_integrity_check();');
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. **Hash Exclusion Strategy**
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- Exclude frequently changing metadata from hashes
|
||||||
|
COMMENT ON COLUMN myapp.users.content_hash IS
|
||||||
|
'{"exclude_hash_columns": ["last_login", "login_count", "last_activity", "session_data"]}';
|
||||||
|
|
||||||
|
-- Include business-critical data in hashes
|
||||||
|
COMMENT ON COLUMN myapp.transactions.content_hash IS
|
||||||
|
'{"exclude_hash_columns": ["created_at", "updated_at"]}'; -- Minimal exclusions
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. **Tamper Detection Response**
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- Automated response to tampering detection
|
||||||
|
CREATE OR REPLACE FUNCTION handle_tampering_detection(
|
||||||
|
p_table_name text,
|
||||||
|
p_record_id text,
|
||||||
|
p_expected_hash text,
|
||||||
|
p_actual_hash text
|
||||||
|
)
|
||||||
|
RETURNS void LANGUAGE plpgsql AS $$
|
||||||
|
BEGIN
|
||||||
|
-- Log the incident
|
||||||
|
INSERT INTO security_incidents (
|
||||||
|
incident_type,
|
||||||
|
table_name,
|
||||||
|
record_id,
|
||||||
|
expected_hash,
|
||||||
|
actual_hash,
|
||||||
|
detected_at,
|
||||||
|
severity
|
||||||
|
) VALUES (
|
||||||
|
'DATA_TAMPERING',
|
||||||
|
p_table_name,
|
||||||
|
p_record_id,
|
||||||
|
p_expected_hash,
|
||||||
|
p_actual_hash,
|
||||||
|
now(),
|
||||||
|
'CRITICAL'
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Notify security team
|
||||||
|
PERFORM pg_notify('security_alert', jsonb_build_object(
|
||||||
|
'type', 'DATA_TAMPERING',
|
||||||
|
'table', p_table_name,
|
||||||
|
'record_id', p_record_id,
|
||||||
|
'severity', 'CRITICAL'
|
||||||
|
)::text);
|
||||||
|
|
||||||
|
-- Optional: Quarantine the record
|
||||||
|
-- UPDATE myapp.table_name SET quarantined = true WHERE id = p_record_id;
|
||||||
|
END;
|
||||||
|
$$;
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📊 **Monitoring and Alerting Best Practices**
|
||||||
|
|
||||||
|
### 1. **Continuous Health Monitoring**
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- Comprehensive health monitoring
|
||||||
|
CREATE OR REPLACE FUNCTION security_health_monitor()
|
||||||
|
RETURNS jsonb LANGUAGE plpgsql AS $$
|
||||||
|
DECLARE
|
||||||
|
v_health jsonb;
|
||||||
|
v_alerts jsonb[] := '{}';
|
||||||
|
v_error_rate numeric;
|
||||||
|
v_token_count integer;
|
||||||
|
BEGIN
|
||||||
|
-- Get system health
|
||||||
|
SELECT c77_secure_db_health_check() INTO v_health;
|
||||||
|
|
||||||
|
-- Check error rate
|
||||||
|
v_error_rate := (v_health->>'error_rate_1h')::numeric;
|
||||||
|
IF v_error_rate > 5 THEN
|
||||||
|
v_alerts := v_alerts || jsonb_build_object(
|
||||||
|
'type', 'HIGH_ERROR_RATE',
|
||||||
|
'severity', 'WARNING',
|
||||||
|
'value', v_error_rate,
|
||||||
|
'threshold', 5,
|
||||||
|
'message', 'Error rate exceeds acceptable threshold'
|
||||||
|
);
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
-- Check token buildup
|
||||||
|
v_token_count := (v_health->>'active_tokens')::integer;
|
||||||
|
IF v_token_count > 100 THEN
|
||||||
|
v_alerts := v_alerts || jsonb_build_object(
|
||||||
|
'type', 'TOKEN_BUILDUP',
|
||||||
|
'severity', 'WARNING',
|
||||||
|
'value', v_token_count,
|
||||||
|
'threshold', 100,
|
||||||
|
'message', 'Excessive active tokens may indicate issues'
|
||||||
|
);
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
RETURN jsonb_build_object(
|
||||||
|
'health_status', v_health,
|
||||||
|
'alerts', v_alerts,
|
||||||
|
'alert_count', array_length(v_alerts, 1),
|
||||||
|
'timestamp', now()
|
||||||
|
);
|
||||||
|
END;
|
||||||
|
$$;
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. **Audit Log Analysis**
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- Suspicious activity detection
|
||||||
|
CREATE OR REPLACE VIEW security_anomalies AS
|
||||||
|
SELECT
|
||||||
|
'High Error Rate User' as anomaly_type,
|
||||||
|
user_name,
|
||||||
|
count(*) as error_count,
|
||||||
|
count(*) * 100.0 / SUM(count(*)) OVER() as error_percentage
|
||||||
|
FROM c77_secure_db_operation_audit
|
||||||
|
WHERE created_at > now() - interval '24 hours'
|
||||||
|
AND success = false
|
||||||
|
GROUP BY user_name
|
||||||
|
HAVING count(*) > 10
|
||||||
|
|
||||||
|
UNION ALL
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
'Unusual Activity Volume' as anomaly_type,
|
||||||
|
user_name,
|
||||||
|
count(*) as operation_count,
|
||||||
|
NULL as error_percentage
|
||||||
|
FROM c77_secure_db_operation_audit
|
||||||
|
WHERE created_at > now() - interval '1 hour'
|
||||||
|
GROUP BY user_name
|
||||||
|
HAVING count(*) > 100
|
||||||
|
|
||||||
|
UNION ALL
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
'Off-Hours Activity' as anomaly_type,
|
||||||
|
user_name,
|
||||||
|
count(*) as operation_count,
|
||||||
|
NULL as error_percentage
|
||||||
|
FROM c77_secure_db_operation_audit
|
||||||
|
WHERE created_at > now() - interval '24 hours'
|
||||||
|
AND EXTRACT(hour FROM created_at) NOT BETWEEN 8 AND 18
|
||||||
|
GROUP BY user_name
|
||||||
|
HAVING count(*) > 5;
|
||||||
|
|
||||||
|
-- Review anomalies regularly
|
||||||
|
SELECT * FROM security_anomalies ORDER BY anomaly_type, operation_count DESC;
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. **Performance Monitoring**
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- Performance baseline and alerting
|
||||||
|
CREATE OR REPLACE FUNCTION performance_monitor()
|
||||||
|
RETURNS jsonb LANGUAGE plpgsql AS $$
|
||||||
|
DECLARE
|
||||||
|
v_slow_operations jsonb;
|
||||||
|
v_avg_time numeric;
|
||||||
|
v_p95_time numeric;
|
||||||
|
BEGIN
|
||||||
|
-- Calculate performance metrics
|
||||||
|
SELECT
|
||||||
|
avg(execution_time_ms),
|
||||||
|
percentile_cont(0.95) WITHIN GROUP (ORDER BY execution_time_ms)
|
||||||
|
INTO v_avg_time, v_p95_time
|
||||||
|
FROM c77_secure_db_operation_audit
|
||||||
|
WHERE created_at > now() - interval '1 hour'
|
||||||
|
AND execution_time_ms IS NOT NULL;
|
||||||
|
|
||||||
|
-- Identify slow operations
|
||||||
|
SELECT jsonb_agg(
|
||||||
|
jsonb_build_object(
|
||||||
|
'operation_type', operation_type,
|
||||||
|
'schema_name', schema_name,
|
||||||
|
'table_name', table_name,
|
||||||
|
'avg_time_ms', avg(execution_time_ms),
|
||||||
|
'operation_count', count(*)
|
||||||
|
)
|
||||||
|
) INTO v_slow_operations
|
||||||
|
FROM c77_secure_db_operation_audit
|
||||||
|
WHERE created_at > now() - interval '1 hour'
|
||||||
|
AND execution_time_ms > 1000 -- Operations > 1 second
|
||||||
|
GROUP BY operation_type, schema_name, table_name;
|
||||||
|
|
||||||
|
RETURN jsonb_build_object(
|
||||||
|
'avg_execution_time_ms', v_avg_time,
|
||||||
|
'p95_execution_time_ms', v_p95_time,
|
||||||
|
'slow_operations', v_slow_operations,
|
||||||
|
'timestamp', now()
|
||||||
|
);
|
||||||
|
END;
|
||||||
|
$$;
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔧 **Maintenance Best Practices**
|
||||||
|
|
||||||
|
### 1. **Automated Maintenance Schedule**
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- Comprehensive maintenance routine
|
||||||
|
CREATE OR REPLACE FUNCTION automated_maintenance()
|
||||||
|
RETURNS jsonb LANGUAGE plpgsql AS $$
|
||||||
|
DECLARE
|
||||||
|
v_tokens_cleaned integer;
|
||||||
|
v_audit_archived integer;
|
||||||
|
v_health jsonb;
|
||||||
|
BEGIN
|
||||||
|
-- Clean expired tokens
|
||||||
|
SELECT c77_secure_db_cleanup_expired_tokens() INTO v_tokens_cleaned;
|
||||||
|
|
||||||
|
-- Archive old audit logs (keep 90 days)
|
||||||
|
WITH archived AS (
|
||||||
|
DELETE FROM c77_secure_db_operation_audit
|
||||||
|
WHERE created_at < (now() - interval '90 days')
|
||||||
|
RETURNING *
|
||||||
|
)
|
||||||
|
SELECT count(*) INTO v_audit_archived FROM archived;
|
||||||
|
|
||||||
|
-- Update statistics
|
||||||
|
ANALYZE c77_secure_db_auth_tokens;
|
||||||
|
ANALYZE c77_secure_db_operation_audit;
|
||||||
|
ANALYZE c77_secure_db_secure_schemas;
|
||||||
|
|
||||||
|
-- Health check
|
||||||
|
SELECT c77_secure_db_health_check() INTO v_health;
|
||||||
|
|
||||||
|
RETURN jsonb_build_object(
|
||||||
|
'tokens_cleaned', v_tokens_cleaned,
|
||||||
|
'audit_records_archived', v_audit_archived,
|
||||||
|
'health_status', v_health,
|
||||||
|
'maintenance_completed_at', now()
|
||||||
|
);
|
||||||
|
END;
|
||||||
|
$$;
|
||||||
|
|
||||||
|
-- Schedule maintenance
|
||||||
|
SELECT cron.schedule('secure-db-maintenance', '0 2 * * *', 'SELECT automated_maintenance();');
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. **Backup and Recovery**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
#!/bin/bash
|
||||||
|
# secure-db-backup.sh - Backup script for secure database
|
||||||
|
|
||||||
|
# Create timestamped backup
|
||||||
|
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
|
||||||
|
BACKUP_FILE="secure_db_backup_${TIMESTAMP}.sql"
|
||||||
|
|
||||||
|
# Full database backup
|
||||||
|
pg_dump -Fc -h localhost -U postgres myapp_database > "${BACKUP_FILE}"
|
||||||
|
|
||||||
|
# Backup extension-specific data
|
||||||
|
pg_dump -h localhost -U postgres \
|
||||||
|
--table=c77_secure_db_operation_audit \
|
||||||
|
--table=c77_secure_db_secure_schemas \
|
||||||
|
myapp_database > "secure_db_metadata_${TIMESTAMP}.sql"
|
||||||
|
|
||||||
|
# Verify backup integrity
|
||||||
|
if pg_restore --list "${BACKUP_FILE}" > /dev/null 2>&1; then
|
||||||
|
echo "Backup ${BACKUP_FILE} created successfully"
|
||||||
|
else
|
||||||
|
echo "ERROR: Backup verification failed"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Clean old backups (keep 30 days)
|
||||||
|
find /backup/path -name "secure_db_backup_*.sql" -mtime +30 -delete
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. **Security Updates**
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- Security update validation procedure
|
||||||
|
CREATE OR REPLACE FUNCTION validate_security_update()
|
||||||
|
RETURNS jsonb LANGUAGE plpgsql AS $$
|
||||||
|
DECLARE
|
||||||
|
v_test_results jsonb;
|
||||||
|
v_health_before jsonb;
|
||||||
|
v_health_after jsonb;
|
||||||
|
BEGIN
|
||||||
|
-- Pre-update health check
|
||||||
|
SELECT c77_secure_db_health_check() INTO v_health_before;
|
||||||
|
|
||||||
|
-- Run comprehensive tests
|
||||||
|
SELECT c77_secure_db_run_all_tests() INTO v_test_results;
|
||||||
|
|
||||||
|
-- Post-update health check
|
||||||
|
SELECT c77_secure_db_health_check() INTO v_health_after;
|
||||||
|
|
||||||
|
-- Validate update success
|
||||||
|
IF (v_test_results->>'overall_status') != 'ALL_TESTS_PASSED' THEN
|
||||||
|
RAISE EXCEPTION 'Security update validation failed: %', v_test_results->>'overall_status';
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
RETURN jsonb_build_object(
|
||||||
|
'update_validated', true,
|
||||||
|
'test_results', v_test_results,
|
||||||
|
'health_before', v_health_before,
|
||||||
|
'health_after', v_health_after,
|
||||||
|
'validation_timestamp', now()
|
||||||
|
);
|
||||||
|
END;
|
||||||
|
$$;
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🚨 **Incident Response Best Practices**
|
||||||
|
|
||||||
|
### 1. **Security Incident Classification**
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- Security incident severity levels
|
||||||
|
CREATE TYPE incident_severity AS ENUM ('LOW', 'MEDIUM', 'HIGH', 'CRITICAL');
|
||||||
|
|
||||||
|
-- Incident response procedures
|
||||||
|
CREATE OR REPLACE FUNCTION security_incident_response(
|
||||||
|
p_incident_type text,
|
||||||
|
p_severity incident_severity,
|
||||||
|
p_details jsonb
|
||||||
|
)
|
||||||
|
RETURNS void LANGUAGE plpgsql AS $$
|
||||||
|
BEGIN
|
||||||
|
-- Log incident
|
||||||
|
INSERT INTO security_incidents (
|
||||||
|
incident_type,
|
||||||
|
severity,
|
||||||
|
details,
|
||||||
|
reported_at,
|
||||||
|
status
|
||||||
|
) VALUES (
|
||||||
|
p_incident_type,
|
||||||
|
p_severity,
|
||||||
|
p_details,
|
||||||
|
now(),
|
||||||
|
'REPORTED'
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Automatic response based on severity
|
||||||
|
CASE p_severity
|
||||||
|
WHEN 'CRITICAL' THEN
|
||||||
|
-- Immediate notification
|
||||||
|
PERFORM pg_notify('critical_security_alert',
|
||||||
|
jsonb_build_object(
|
||||||
|
'type', p_incident_type,
|
||||||
|
'details', p_details,
|
||||||
|
'timestamp', now()
|
||||||
|
)::text
|
||||||
|
);
|
||||||
|
|
||||||
|
WHEN 'HIGH' THEN
|
||||||
|
-- Priority notification
|
||||||
|
PERFORM pg_notify('high_security_alert',
|
||||||
|
jsonb_build_object(
|
||||||
|
'type', p_incident_type,
|
||||||
|
'details', p_details,
|
||||||
|
'timestamp', now()
|
||||||
|
)::text
|
||||||
|
);
|
||||||
|
|
||||||
|
ELSE
|
||||||
|
-- Standard logging only
|
||||||
|
NULL;
|
||||||
|
END CASE;
|
||||||
|
END;
|
||||||
|
$$;
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. **Forensic Data Preservation**
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- Preserve forensic evidence
|
||||||
|
CREATE OR REPLACE FUNCTION preserve_forensic_evidence(
|
||||||
|
p_table_name text,
|
||||||
|
p_record_id text,
|
||||||
|
p_incident_id uuid
|
||||||
|
)
|
||||||
|
RETURNS void LANGUAGE plpgsql AS $$
|
||||||
|
DECLARE
|
||||||
|
v_record_data jsonb;
|
||||||
|
v_auth_token uuid;
|
||||||
|
BEGIN
|
||||||
|
-- Get authorization token for forensic access
|
||||||
|
v_auth_token := c77_secure_db_create_auth_token('forensic_preservation');
|
||||||
|
PERFORM set_config('c77_secure_db.auth_token', v_auth_token::text, true);
|
||||||
|
|
||||||
|
-- Capture complete record state
|
||||||
|
EXECUTE format('SELECT row_to_json(t) FROM %I.%I t WHERE id = $1', 'myapp', p_table_name)
|
||||||
|
INTO v_record_data
|
||||||
|
USING p_record_id;
|
||||||
|
|
||||||
|
-- Store forensic copy
|
||||||
|
INSERT INTO forensic_evidence (
|
||||||
|
incident_id,
|
||||||
|
table_name,
|
||||||
|
record_id,
|
||||||
|
record_data,
|
||||||
|
preserved_at
|
||||||
|
) VALUES (
|
||||||
|
p_incident_id,
|
||||||
|
p_table_name,
|
||||||
|
p_record_id,
|
||||||
|
v_record_data,
|
||||||
|
now()
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Clean up token
|
||||||
|
PERFORM set_config('c77_secure_db.auth_token', '', true);
|
||||||
|
END;
|
||||||
|
$$;
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📋 **Compliance Best Practices**
|
||||||
|
|
||||||
|
### 1. **Audit Trail Requirements**
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- Ensure comprehensive audit coverage
|
||||||
|
CREATE OR REPLACE FUNCTION audit_compliance_check()
|
||||||
|
RETURNS jsonb LANGUAGE plpgsql AS $$
|
||||||
|
DECLARE
|
||||||
|
v_coverage jsonb;
|
||||||
|
v_gaps text[];
|
||||||
|
BEGIN
|
||||||
|
-- Check audit coverage for critical tables
|
||||||
|
WITH critical_tables AS (
|
||||||
|
SELECT unnest(ARRAY['users', 'transactions', 'sensitive_data']) AS table_name
|
||||||
|
),
|
||||||
|
audit_coverage AS (
|
||||||
|
SELECT
|
||||||
|
ct.table_name,
|
||||||
|
COUNT(a.id) as audit_count,
|
||||||
|
MAX(a.created_at) as last_audit
|
||||||
|
FROM critical_tables ct
|
||||||
|
LEFT JOIN c77_secure_db_operation_audit a
|
||||||
|
ON ct.table_name = a.table_name
|
||||||
|
AND a.created_at > now() - interval '24 hours'
|
||||||
|
GROUP BY ct.table_name
|
||||||
|
)
|
||||||
|
SELECT jsonb_object_agg(table_name,
|
||||||
|
jsonb_build_object(
|
||||||
|
'audit_count', audit_count,
|
||||||
|
'last_audit', last_audit,
|
||||||
|
'compliant', (audit_count > 0)
|
||||||
|
)
|
||||||
|
) INTO v_coverage
|
||||||
|
FROM audit_coverage;
|
||||||
|
|
||||||
|
-- Identify gaps
|
||||||
|
SELECT array_agg(table_name)
|
||||||
|
INTO v_gaps
|
||||||
|
FROM jsonb_each(v_coverage)
|
||||||
|
WHERE NOT (value->>'compliant')::boolean;
|
||||||
|
|
||||||
|
RETURN jsonb_build_object(
|
||||||
|
'coverage_analysis', v_coverage,
|
||||||
|
'compliance_gaps', v_gaps,
|
||||||
|
'overall_compliant', (array_length(v_gaps, 1) IS NULL),
|
||||||
|
'check_timestamp', now()
|
||||||
|
);
|
||||||
|
END;
|
||||||
|
$$;
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. **Data Retention Policies**
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- Implement data retention policies
|
||||||
|
CREATE OR REPLACE FUNCTION apply_retention_policy()
|
||||||
|
RETURNS jsonb LANGUAGE plpgsql AS $$
|
||||||
|
DECLARE
|
||||||
|
v_audit_purged integer;
|
||||||
|
v_tokens_purged integer;
|
||||||
|
v_forensic_archived integer;
|
||||||
|
BEGIN
|
||||||
|
-- Purge old audit logs (beyond retention period)
|
||||||
|
WITH purged AS (
|
||||||
|
DELETE FROM c77_secure_db_operation_audit
|
||||||
|
WHERE created_at < (now() - interval '7 years') -- Adjust per compliance requirements
|
||||||
|
RETURNING *
|
||||||
|
)
|
||||||
|
SELECT count(*) INTO v_audit_purged FROM purged;
|
||||||
|
|
||||||
|
-- Clean very old auth tokens
|
||||||
|
WITH purged_tokens AS (
|
||||||
|
DELETE FROM c77_secure_db_auth_tokens
|
||||||
|
WHERE created_at < (now() - interval '7 days')
|
||||||
|
RETURNING *
|
||||||
|
)
|
||||||
|
SELECT count(*) INTO v_tokens_purged FROM purged_tokens;
|
||||||
|
|
||||||
|
-- Archive old forensic evidence
|
||||||
|
WITH archived AS (
|
||||||
|
UPDATE forensic_evidence
|
||||||
|
SET archived = true
|
||||||
|
WHERE preserved_at < (now() - interval '3 years')
|
||||||
|
AND archived = false
|
||||||
|
RETURNING *
|
||||||
|
)
|
||||||
|
SELECT count(*) INTO v_forensic_archived FROM archived;
|
||||||
|
|
||||||
|
RETURN jsonb_build_object(
|
||||||
|
'audit_records_purged', v_audit_purged,
|
||||||
|
'tokens_purged', v_tokens_purged,
|
||||||
|
'forensic_records_archived', v_forensic_archived,
|
||||||
|
'retention_policy_applied_at', now()
|
||||||
|
);
|
||||||
|
END;
|
||||||
|
$$;
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🎯 **Implementation Checklist**
|
||||||
|
|
||||||
|
### **Pre-Production Checklist**
|
||||||
|
- [ ] Security tests pass: `SELECT c77_secure_db_run_all_tests()`
|
||||||
|
- [ ] RBAC permissions properly configured
|
||||||
|
- [ ] Audit logging enabled and tested
|
||||||
|
- [ ] Monitoring and alerting configured
|
||||||
|
- [ ] Backup and recovery procedures tested
|
||||||
|
- [ ] Incident response plan documented
|
||||||
|
- [ ] Performance benchmarks established
|
||||||
|
- [ ] Security training completed for team
|
||||||
|
|
||||||
|
### **Production Checklist**
|
||||||
|
- [ ] Daily integrity checks scheduled
|
||||||
|
- [ ] Automated maintenance configured
|
||||||
|
- [ ] Security monitoring active
|
||||||
|
- [ ] Audit log retention policy implemented
|
||||||
|
- [ ] Performance monitoring baseline established
|
||||||
|
- [ ] Emergency procedures documented
|
||||||
|
- [ ] Security incident response team identified
|
||||||
|
- [ ] Compliance requirements validated
|
||||||
|
|
||||||
|
### **Ongoing Maintenance**
|
||||||
|
- [ ] Weekly hash verification
|
||||||
|
- [ ] Monthly security audits
|
||||||
|
- [ ] Quarterly security reviews
|
||||||
|
- [ ] Annual security assessment
|
||||||
|
- [ ] Regular staff security training
|
||||||
|
- [ ] Security policy updates
|
||||||
|
- [ ] Threat model reviews
|
||||||
|
- [ ] Disaster recovery testing
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Remember: Security is not a one-time implementation but an ongoing process requiring continuous attention, monitoring, and improvement.**
|
1357
EXAMPLES.md
Normal file
1357
EXAMPLES.md
Normal file
File diff suppressed because it is too large
Load Diff
513
INSTALLATION.md
513
INSTALLATION.md
@ -1,198 +1,447 @@
|
|||||||
# Installation Guide for c77_secure_db
|
# c77_secure_db v2.0 - Installation & Quick Start Guide
|
||||||
|
|
||||||
This guide provides detailed instructions for installing and configuring the `c77_secure_db` PostgreSQL extension.
|
## Overview
|
||||||
|
|
||||||
|
The c77_secure_db extension provides enterprise-grade database security with:
|
||||||
|
- **Token-based authorization** (no more session variable bypasses!)
|
||||||
|
- **Content hashing** for tamper detection
|
||||||
|
- **Optional c77_rbac integration** for advanced permissions
|
||||||
|
- **Comprehensive audit logging**
|
||||||
|
- **Automatic trigger management**
|
||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
- PostgreSQL 11 or higher
|
- PostgreSQL 14 or later
|
||||||
- Database superuser access (for installation)
|
|
||||||
- pgcrypto extension
|
- pgcrypto extension
|
||||||
|
- Superuser access for installation
|
||||||
|
- Optional: c77_rbac extension for advanced permissions
|
||||||
|
|
||||||
## Standard Installation (using PGXS)
|
## Installation
|
||||||
|
|
||||||
### Step 1: Obtain the Extension
|
### 1. Copy Extension Files
|
||||||
|
|
||||||
Either download the extension from the repository or create the files manually:
|
|
||||||
|
|
||||||
1. `c77_secure_db.control` - Extension control file
|
|
||||||
2. `c77_secure_db--1.0.0.sql` - SQL for extension version 1.0.0
|
|
||||||
3. `Makefile` - For installation with PGXS
|
|
||||||
|
|
||||||
### Step 2: Build and Install
|
|
||||||
|
|
||||||
Use the PostgreSQL build infrastructure (PGXS) to build and install the extension:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
make
|
# Copy control file
|
||||||
sudo make install
|
sudo cp c77_secure_db.control $(pg_config --sharedir)/extension/
|
||||||
|
|
||||||
|
# Copy SQL file
|
||||||
|
sudo cp c77_secure_db--1.0.sql $(pg_config --sharedir)/extension/
|
||||||
```
|
```
|
||||||
|
|
||||||
This will copy the files to the appropriate PostgreSQL extension directories.
|
### 2. Install Dependencies
|
||||||
|
|
||||||
### Step 3: Create the Extension in Your Database
|
|
||||||
|
|
||||||
Connect to your database and create the extension:
|
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
-- First, ensure pgcrypto is installed
|
-- Connect as superuser
|
||||||
CREATE EXTENSION IF NOT EXISTS pgcrypto;
|
CREATE EXTENSION IF NOT EXISTS pgcrypto;
|
||||||
|
|
||||||
-- Then create the c77_secure_db extension
|
-- Optional: Install c77_rbac for advanced permissions
|
||||||
|
-- CREATE EXTENSION IF NOT EXISTS c77_rbac;
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Install the Extension (Superuser Required)
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- Connect as PostgreSQL superuser
|
||||||
|
sudo -u postgres psql
|
||||||
|
|
||||||
|
-- Install the extension
|
||||||
CREATE EXTENSION c77_secure_db;
|
CREATE EXTENSION c77_secure_db;
|
||||||
|
|
||||||
|
-- Verify correct version
|
||||||
|
SELECT extname, extversion FROM pg_extension WHERE extname = 'c77_secure_db';
|
||||||
|
-- Should show: c77_secure_db | 1.0
|
||||||
|
|
||||||
|
-- Verify installation
|
||||||
|
SELECT c77_secure_db_health_check();
|
||||||
```
|
```
|
||||||
|
|
||||||
## Manual Installation
|
### 4. Run Security Tests (Superuser)
|
||||||
|
|
||||||
If you don't have development tools or prefer a manual installation:
|
|
||||||
|
|
||||||
### Step 1: Locate PostgreSQL Extension Directory
|
|
||||||
|
|
||||||
Find your PostgreSQL extension directory:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
pg_config --sharedir
|
|
||||||
```
|
|
||||||
|
|
||||||
The extension directory is usually `[pg_sharedir]/extension/`.
|
|
||||||
|
|
||||||
### Step 2: Copy Files
|
|
||||||
|
|
||||||
Copy the extension files:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Replace [pg_sharedir] with the output from pg_config --sharedir
|
|
||||||
cp c77_secure_db.control [pg_sharedir]/extension/
|
|
||||||
cp c77_secure_db--1.0.0.sql [pg_sharedir]/extension/
|
|
||||||
```
|
|
||||||
|
|
||||||
### Step 3: Create the Extension
|
|
||||||
|
|
||||||
Connect to your database and create the extension:
|
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
-- First, ensure pgcrypto is installed
|
-- CRITICAL: Run tests to verify security works
|
||||||
CREATE EXTENSION IF NOT EXISTS pgcrypto;
|
SELECT c77_secure_db_run_all_tests();
|
||||||
|
|
||||||
-- Then create the c77_secure_db extension
|
-- This should return: "overall_status": "ALL_TESTS_PASSED"
|
||||||
CREATE EXTENSION c77_secure_db;
|
-- If not, DO NOT use in production!
|
||||||
```
|
```
|
||||||
|
|
||||||
## Post-Installation Configuration
|
## Quick Start
|
||||||
|
|
||||||
### Step 1: Create a Secure Schema
|
### 1. Set Up Your Application User (Superuser)
|
||||||
|
|
||||||
Create a schema for your secure tables:
|
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
CREATE SCHEMA secure_data;
|
-- Create your application user and grant secure access
|
||||||
|
CREATE USER myapp_user WITH PASSWORD 'secure_password';
|
||||||
|
GRANT c77_secure_db_user TO myapp_user;
|
||||||
|
|
||||||
|
-- Now connect as your application user for regular operations
|
||||||
|
\c your_database myapp_user
|
||||||
```
|
```
|
||||||
|
|
||||||
### Step 2: Register the Schema
|
### 2. Create a Secure Schema
|
||||||
|
|
||||||
Register the schema with the secure database system:
|
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
SELECT c77_manage_secure_schemas('add', 'secure_data');
|
-- Create your application schema
|
||||||
|
CREATE SCHEMA myapp;
|
||||||
|
|
||||||
|
-- Register it as secure (this auto-applies triggers)
|
||||||
|
SELECT c77_secure_db_manage_secure_schemas('add', 'myapp');
|
||||||
```
|
```
|
||||||
|
|
||||||
### Step 3: Verify the Installation
|
### 3. Create Secure Tables
|
||||||
|
|
||||||
Verify that the functions are installed correctly:
|
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
SELECT pg_proc.proname
|
-- Create tables with required security columns
|
||||||
FROM pg_proc
|
CREATE TABLE myapp.users (
|
||||||
JOIN pg_namespace ON pg_proc.pronamespace = pg_namespace.oid
|
id BIGSERIAL PRIMARY KEY,
|
||||||
WHERE pg_namespace.nspname = 'public'
|
|
||||||
AND pg_proc.proname LIKE 'c77_%';
|
|
||||||
```
|
|
||||||
|
|
||||||
This should return a list of all the `c77_` functions.
|
|
||||||
|
|
||||||
## Testing
|
|
||||||
|
|
||||||
Create a test table and verify that direct modifications are blocked:
|
|
||||||
|
|
||||||
```sql
|
|
||||||
-- Create a test table
|
|
||||||
CREATE TABLE secure_data.test_table (
|
|
||||||
id SERIAL PRIMARY KEY,
|
|
||||||
name TEXT NOT NULL,
|
name TEXT NOT NULL,
|
||||||
|
email TEXT UNIQUE NOT NULL,
|
||||||
|
-- Security columns (required for tamper detection)
|
||||||
content_hash TEXT,
|
content_hash TEXT,
|
||||||
|
hash_version INTEGER DEFAULT 1,
|
||||||
created_at TIMESTAMPTZ DEFAULT NOW(),
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
updated_at TIMESTAMPTZ DEFAULT NOW(),
|
updated_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
deleted_at TIMESTAMPTZ DEFAULT NULL
|
deleted_at TIMESTAMPTZ -- Optional: for soft deletes
|
||||||
);
|
);
|
||||||
|
|
||||||
-- Attempt a direct insertion (this should fail)
|
-- Triggers are automatically applied to new tables in secure schemas!
|
||||||
INSERT INTO secure_data.test_table (name) VALUES ('Test');
|
```
|
||||||
|
|
||||||
-- Use the secure operation function (this should succeed)
|
### 4. Perform Secure Operations
|
||||||
SELECT c77_secure_db_operation(
|
|
||||||
jsonb_build_object(
|
```sql
|
||||||
'schema_name', 'secure_data',
|
-- INSERT: Use the secure operation function
|
||||||
'table_name', 'test_table',
|
SELECT c77_secure_db_operation(jsonb_build_object(
|
||||||
|
'schema_name', 'myapp',
|
||||||
|
'table_name', 'users',
|
||||||
'operation', 'insert',
|
'operation', 'insert',
|
||||||
'data', jsonb_build_object(
|
'data', jsonb_build_object(
|
||||||
'name', 'Secure Test'
|
'name', 'John Doe',
|
||||||
|
'email', 'john@example.com'
|
||||||
)
|
)
|
||||||
|
));
|
||||||
|
|
||||||
|
-- UPDATE: Include the primary key in data
|
||||||
|
SELECT c77_secure_db_operation(jsonb_build_object(
|
||||||
|
'schema_name', 'myapp',
|
||||||
|
'table_name', 'users',
|
||||||
|
'operation', 'update',
|
||||||
|
'data', jsonb_build_object(
|
||||||
|
'id', 1,
|
||||||
|
'name', 'John Smith',
|
||||||
|
'email', 'john.smith@example.com'
|
||||||
|
)
|
||||||
|
));
|
||||||
|
|
||||||
|
-- SOFT DELETE: Mark as deleted (preserves data)
|
||||||
|
SELECT c77_secure_db_operation(jsonb_build_object(
|
||||||
|
'schema_name', 'myapp',
|
||||||
|
'table_name', 'users',
|
||||||
|
'operation', 'soft_delete',
|
||||||
|
'data', jsonb_build_object('id', 1)
|
||||||
|
));
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5. Verify Data Integrity
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- Check if a record has been tampered with
|
||||||
|
SELECT c77_secure_db_check_freshness(
|
||||||
|
'myapp',
|
||||||
|
'users',
|
||||||
|
jsonb_build_object(
|
||||||
|
'id', 1,
|
||||||
|
'name', 'John Smith',
|
||||||
|
'email', 'john.smith@example.com'
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
-- Verify the record was inserted with content_hash
|
-- Verify all records in a table
|
||||||
SELECT * FROM secure_data.test_table;
|
SELECT c77_secure_db_verify_content_hashes('myapp', 'users');
|
||||||
|
```
|
||||||
|
|
||||||
|
## RBAC Integration (Optional)
|
||||||
|
|
||||||
|
If you have c77_rbac installed, you can add permission-based security:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- Set up RBAC permissions
|
||||||
|
SELECT c77_rbac_grant_feature('user_manager', 'secure_db_insert');
|
||||||
|
SELECT c77_rbac_grant_feature('user_manager', 'secure_db_update');
|
||||||
|
SELECT c77_rbac_assign_subject('123', 'user_manager', 'department', 'engineering');
|
||||||
|
|
||||||
|
-- Set user context in your application
|
||||||
|
SET "c77_rbac.external_id" TO '123';
|
||||||
|
|
||||||
|
-- Use secure operations with RBAC checking
|
||||||
|
SELECT c77_secure_db_operation(
|
||||||
|
jsonb_build_object(
|
||||||
|
'schema_name', 'myapp',
|
||||||
|
'table_name', 'users',
|
||||||
|
'operation', 'insert',
|
||||||
|
'data', jsonb_build_object('name', 'Jane Doe', 'email', 'jane@example.com')
|
||||||
|
),
|
||||||
|
true, -- check_rbac = true
|
||||||
|
'secure_db_insert' -- required_feature
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
## Laravel Integration
|
||||||
|
|
||||||
|
In your Laravel application:
|
||||||
|
|
||||||
|
```php
|
||||||
|
// In your middleware or service provider
|
||||||
|
DB::statement('SET "c77_rbac.external_id" TO ?', [auth()->id()]);
|
||||||
|
|
||||||
|
// Use the secure operation
|
||||||
|
$result = DB::selectOne('
|
||||||
|
SELECT c77_secure_db_operation(?) as result
|
||||||
|
', [json_encode([
|
||||||
|
'schema_name' => 'myapp',
|
||||||
|
'table_name' => 'users',
|
||||||
|
'operation' => 'insert',
|
||||||
|
'data' => [
|
||||||
|
'name' => $request->name,
|
||||||
|
'email' => $request->email
|
||||||
|
]
|
||||||
|
])]);
|
||||||
|
|
||||||
|
$response = json_decode($result->result, true);
|
||||||
|
|
||||||
|
if (!$response['success']) {
|
||||||
|
throw new Exception($response['error']);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Security Best Practices
|
||||||
|
|
||||||
|
### 1. Never Use Direct SQL
|
||||||
|
```sql
|
||||||
|
-- ❌ NEVER DO THIS (will be blocked)
|
||||||
|
INSERT INTO myapp.users (name, email) VALUES ('John', 'john@example.com');
|
||||||
|
|
||||||
|
-- ✅ ALWAYS DO THIS
|
||||||
|
SELECT c77_secure_db_operation(...);
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Regular Integrity Checks
|
||||||
|
```sql
|
||||||
|
-- Run this regularly to detect tampering
|
||||||
|
SELECT c77_secure_db_verify_content_hashes('myapp', 'users');
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Monitor Audit Logs
|
||||||
|
```sql
|
||||||
|
-- Check recent operations
|
||||||
|
SELECT * FROM c77_secure_db_operation_audit
|
||||||
|
WHERE created_at > now() - interval '1 hour'
|
||||||
|
ORDER BY created_at DESC;
|
||||||
|
|
||||||
|
-- Check for errors
|
||||||
|
SELECT * FROM c77_secure_db_operation_audit
|
||||||
|
WHERE success = false AND created_at > now() - interval '24 hours';
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Regular Maintenance
|
||||||
|
```sql
|
||||||
|
-- Clean up expired tokens (run daily)
|
||||||
|
SELECT c77_secure_db_cleanup_expired_tokens();
|
||||||
|
|
||||||
|
-- System health check
|
||||||
|
SELECT c77_secure_db_health_check();
|
||||||
```
|
```
|
||||||
|
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
|
|
||||||
### Common Issues
|
### Common Issues
|
||||||
|
|
||||||
1. **Extension files not found**
|
**Issue**: "Direct modifications are not allowed"
|
||||||
|
- **Cause**: Trying to use direct SQL instead of secure operations
|
||||||
|
- **Solution**: Use `c77_secure_db_operation()` function
|
||||||
|
|
||||||
If you see an error like "could not open extension control file", ensure the `.control` file is in the correct location.
|
**Issue**: "RBAC enabled but no user context set"
|
||||||
|
- **Cause**: RBAC checking enabled but `c77_rbac.external_id` not set
|
||||||
|
- **Solution**: Set the session variable: `SET "c77_rbac.external_id" TO 'user_id'`
|
||||||
|
|
||||||
Solution: Verify the location with `pg_config --sharedir` and check that the file is in the `extension` subdirectory.
|
**Issue**: "Insufficient permissions"
|
||||||
|
- **Cause**: User doesn't have required RBAC feature
|
||||||
|
- **Solution**: Grant the feature: `SELECT c77_rbac_grant_feature('role', 'feature')`
|
||||||
|
|
||||||
2. **pgcrypto not installed**
|
### Debug Commands
|
||||||
|
|
||||||
The extension requires pgcrypto to be installed first.
|
|
||||||
|
|
||||||
Solution: Run `CREATE EXTENSION pgcrypto;` before trying to create the c77_secure_db extension.
|
|
||||||
|
|
||||||
3. **Permission denied for schema public**
|
|
||||||
|
|
||||||
If you get a permission error when creating the extension, you may not have sufficient privileges.
|
|
||||||
|
|
||||||
Solution: Connect as a database superuser to create the extension.
|
|
||||||
|
|
||||||
4. **Event trigger creation fails**
|
|
||||||
|
|
||||||
If the event trigger fails to create, it might already exist or you might not have permission.
|
|
||||||
|
|
||||||
Solution: Check if the trigger exists with `SELECT * FROM pg_event_trigger;` and drop it if needed.
|
|
||||||
|
|
||||||
### Getting Help
|
|
||||||
|
|
||||||
If you encounter issues not covered in this guide, please:
|
|
||||||
|
|
||||||
1. Check the PostgreSQL logs for detailed error messages
|
|
||||||
2. Verify that all prerequisite steps have been completed
|
|
||||||
3. Contact the extension maintainer for support
|
|
||||||
|
|
||||||
## Upgrading
|
|
||||||
|
|
||||||
To upgrade the extension in the future:
|
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
ALTER EXTENSION c77_secure_db UPDATE;
|
-- Check if schema is registered as secure
|
||||||
|
SELECT * FROM c77_secure_db_secure_schemas;
|
||||||
|
|
||||||
|
-- Check recent operations
|
||||||
|
SELECT * FROM c77_secure_db_operation_audit ORDER BY created_at DESC LIMIT 10;
|
||||||
|
|
||||||
|
-- Test RBAC integration
|
||||||
|
SELECT c77_secure_db_test_rbac_integration();
|
||||||
|
|
||||||
|
-- Get operation template for your table
|
||||||
|
SELECT c77_secure_db_get_operation_template('myapp', 'users', 'insert');
|
||||||
```
|
```
|
||||||
|
|
||||||
## Uninstalling
|
## Advanced Features
|
||||||
|
|
||||||
If needed, you can remove the extension:
|
### Custom Hash Exclusions
|
||||||
|
|
||||||
|
You can exclude specific columns from hash calculation by adding a comment to the `content_hash` column:
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
|
-- Exclude 'last_login' from hash calculation
|
||||||
|
COMMENT ON COLUMN myapp.users.content_hash IS
|
||||||
|
'{"exclude_hash_columns": ["last_login", "login_count"]}';
|
||||||
|
```
|
||||||
|
|
||||||
|
### Bulk Operations
|
||||||
|
|
||||||
|
For processing multiple records efficiently:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- Bulk freshness check
|
||||||
|
SELECT c77_secure_db_check_freshness_bulk(
|
||||||
|
'myapp',
|
||||||
|
'users',
|
||||||
|
'[
|
||||||
|
{"id": 1, "name": "John", "email": "john@example.com"},
|
||||||
|
{"id": 2, "name": "Jane", "email": "jane@example.com"}
|
||||||
|
]'::jsonb
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Operation Templates
|
||||||
|
|
||||||
|
Generate SQL templates for your tables:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- Get template for insert operation
|
||||||
|
SELECT c77_secure_db_get_operation_template('myapp', 'users', 'insert');
|
||||||
|
|
||||||
|
-- Get template for update operation
|
||||||
|
SELECT c77_secure_db_get_operation_template('myapp', 'users', 'update');
|
||||||
|
```
|
||||||
|
|
||||||
|
## Migration from v1.0
|
||||||
|
|
||||||
|
If you're upgrading from the old vulnerable version:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- 1. Drop the old extension (backup your data first!)
|
||||||
DROP EXTENSION c77_secure_db CASCADE;
|
DROP EXTENSION c77_secure_db CASCADE;
|
||||||
|
|
||||||
|
-- 2. Install the new version
|
||||||
|
CREATE EXTENSION c77_secure_db;
|
||||||
|
|
||||||
|
-- 3. Re-register your secure schemas
|
||||||
|
SELECT c77_secure_db_manage_secure_schemas('add', 'your_schema');
|
||||||
|
|
||||||
|
-- 4. Run security tests to verify everything works
|
||||||
|
SELECT c77_secure_db_run_all_tests();
|
||||||
```
|
```
|
||||||
|
|
||||||
Note: This will not drop any secured tables, but the security triggers will be removed.
|
## Performance Tuning
|
||||||
|
|
||||||
|
### Indexes for Large Tables
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- Add indexes for better performance on large audit tables
|
||||||
|
CREATE INDEX CONCURRENTLY idx_audit_user_time
|
||||||
|
ON c77_secure_db_operation_audit(user_name, created_at);
|
||||||
|
|
||||||
|
CREATE INDEX CONCURRENTLY idx_audit_schema_table_time
|
||||||
|
ON c77_secure_db_operation_audit(schema_name, table_name, created_at);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Token Cleanup
|
||||||
|
|
||||||
|
Set up automatic token cleanup:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- Add to your daily maintenance script
|
||||||
|
SELECT c77_secure_db_cleanup_expired_tokens();
|
||||||
|
|
||||||
|
-- Or use pg_cron if available
|
||||||
|
SELECT cron.schedule('cleanup-secure-db-tokens', '0 2 * * *', 'SELECT c77_secure_db_cleanup_expired_tokens();');
|
||||||
|
```
|
||||||
|
|
||||||
|
## Monitoring and Alerting
|
||||||
|
|
||||||
|
### Key Metrics to Monitor
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- Error rate (should be very low)
|
||||||
|
SELECT
|
||||||
|
count(*) FILTER (WHERE success = false)::numeric / count(*) * 100 as error_rate_percent
|
||||||
|
FROM c77_secure_db_operation_audit
|
||||||
|
WHERE created_at > now() - interval '24 hours';
|
||||||
|
|
||||||
|
-- Average execution time
|
||||||
|
SELECT avg(execution_time_ms) as avg_execution_ms
|
||||||
|
FROM c77_secure_db_operation_audit
|
||||||
|
WHERE created_at > now() - interval '1 hour' AND execution_time_ms IS NOT NULL;
|
||||||
|
|
||||||
|
-- Active tokens (should be very low, usually 0)
|
||||||
|
SELECT count(*) as active_tokens
|
||||||
|
FROM c77_secure_db_auth_tokens
|
||||||
|
WHERE expires_at > now();
|
||||||
|
```
|
||||||
|
|
||||||
|
### Alert Conditions
|
||||||
|
|
||||||
|
Set up alerts for:
|
||||||
|
- Error rate > 5%
|
||||||
|
- Average execution time > 1000ms
|
||||||
|
- More than 100 active tokens
|
||||||
|
- Any failed operations with "CRITICAL" in the error message
|
||||||
|
|
||||||
|
## File Structure
|
||||||
|
|
||||||
|
Your extension should have these files:
|
||||||
|
|
||||||
|
```
|
||||||
|
c77_secure_db.control # Extension control file
|
||||||
|
c77_secure_db--1.0.sql # Main extension SQL
|
||||||
|
```
|
||||||
|
|
||||||
|
## Security Architecture
|
||||||
|
|
||||||
|
### Token-Based Security
|
||||||
|
- 5-second expiring tokens
|
||||||
|
- Single-use only
|
||||||
|
- Session-specific
|
||||||
|
- Cannot be bypassed
|
||||||
|
|
||||||
|
### Content Hashing
|
||||||
|
- SHA-256 cryptographic hashes
|
||||||
|
- Configurable excluded columns
|
||||||
|
- Automatic hash calculation and verification
|
||||||
|
- Tamper detection
|
||||||
|
|
||||||
|
### Audit Trail
|
||||||
|
- Every operation logged
|
||||||
|
- User context tracking
|
||||||
|
- Performance metrics
|
||||||
|
- Error details
|
||||||
|
|
||||||
|
### RBAC Integration
|
||||||
|
- Optional but recommended
|
||||||
|
- Feature-based permissions
|
||||||
|
- Scope-based access control
|
||||||
|
- Graceful degradation when not available
|
||||||
|
|
||||||
|
## Support and Contributing
|
||||||
|
|
||||||
|
For issues or questions:
|
||||||
|
1. Check the troubleshooting section
|
||||||
|
2. Run the test suite: `SELECT c77_secure_db_run_all_tests()`
|
||||||
|
3. Check audit logs for error details
|
||||||
|
4. Review PostgreSQL logs
|
||||||
|
|
||||||
|
Remember: **Security is paramount**. If tests fail, do not use in production until issues are resolved.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Note**: This is a complete rewrite of the extension with security-first design. The old session variable approach has been completely removed and replaced with secure token-based authorization.
|
6
Makefile
6
Makefile
@ -1,6 +0,0 @@
|
|||||||
EXTENSION = c77_secure_db
|
|
||||||
DATA = c77_secure_db--1.0.0.sql
|
|
||||||
|
|
||||||
PG_CONFIG = $(shell which pg_config)
|
|
||||||
PGXS := $(shell $(PG_CONFIG) --pgxs)
|
|
||||||
include $(PGXS)
|
|
484
README.md
484
README.md
@ -1,218 +1,392 @@
|
|||||||
# c77_secure_db
|
# c77_secure_db
|
||||||
|
|
||||||
PostgreSQL extension for secure database operations with tamper detection and transaction control.
|
**Enterprise-grade PostgreSQL extension for secure database operations with tamper detection and transaction control.**
|
||||||
|
|
||||||
## Overview
|
[](https://www.postgresql.org/)
|
||||||
|
[](LICENSE)
|
||||||
|
[](CHANGELOG.md)
|
||||||
|
|
||||||
The `c77_secure_db` extension provides a comprehensive set of functions to ensure data integrity and prevent unauthorized modification of data in PostgreSQL tables. It implements content hashing to detect tampering and enforces all modifications to go through a secure function rather than direct SQL commands.
|
## 🔒 **Security-First Database Protection**
|
||||||
|
|
||||||
Key features:
|
c77_secure_db provides database-level security that cannot be bypassed by application bugs or SQL injection attacks. All data modifications go through secure, audited operations with cryptographic tamper detection.
|
||||||
- Prevents direct table modifications (INSERT, UPDATE, DELETE) through triggers
|
|
||||||
- Calculates and verifies content hashes to detect data tampering
|
|
||||||
- Automatically manages timestamps (created_at, updated_at, deleted_at)
|
|
||||||
- Provides soft delete functionality
|
|
||||||
- Supports verification of data integrity across entire tables
|
|
||||||
- Handles batch operations efficiently
|
|
||||||
|
|
||||||
## Requirements
|
### **Why c77_secure_db?**
|
||||||
|
|
||||||
- PostgreSQL 11 or higher
|
- **🛡️ Unbypassable Security**: Token-based authorization prevents all unauthorized access
|
||||||
- pgcrypto extension
|
- **🔍 Tamper Detection**: SHA-256 content hashing detects any unauthorized data changes
|
||||||
|
- **📊 Complete Audit Trail**: Every operation logged with user context and performance metrics
|
||||||
|
- **🔗 RBAC Integration**: Seamless integration with c77_rbac extension for advanced permissions
|
||||||
|
- **⚡ Production Ready**: Optimized for high-performance enterprise workloads
|
||||||
|
- **🏗️ Framework Agnostic**: Works with Laravel, Django, Node.js, and any PostgreSQL client
|
||||||
|
|
||||||
## Installation
|
## 🚀 **Quick Start**
|
||||||
|
|
||||||
### From Source
|
### Installation
|
||||||
|
|
||||||
1. Clone the repository:
|
|
||||||
```bash
|
```bash
|
||||||
git clone https://github.com/yourusername/c77_secure_db.git
|
# Copy files to PostgreSQL extension directory
|
||||||
cd c77_secure_db
|
sudo cp c77_secure_db.control $(pg_config --sharedir)/extension/
|
||||||
|
sudo cp c77_secure_db--1.0.sql $(pg_config --sharedir)/extension/
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Build and install the extension:
|
|
||||||
```bash
|
|
||||||
make
|
|
||||||
make install
|
|
||||||
```
|
|
||||||
|
|
||||||
3. Create the extension in your database:
|
|
||||||
```sql
|
```sql
|
||||||
CREATE EXTENSION pgcrypto; -- required dependency
|
-- Install extension (requires superuser)
|
||||||
|
sudo -u postgres psql
|
||||||
|
CREATE EXTENSION IF NOT EXISTS pgcrypto;
|
||||||
CREATE EXTENSION c77_secure_db;
|
CREATE EXTENSION c77_secure_db;
|
||||||
|
|
||||||
|
-- Verify installation (CRITICAL - must pass!)
|
||||||
|
SELECT c77_secure_db_run_all_tests();
|
||||||
|
|
||||||
|
-- Set up application user
|
||||||
|
CREATE USER myapp_user WITH PASSWORD 'secure_password';
|
||||||
|
GRANT c77_secure_db_user TO myapp_user;
|
||||||
```
|
```
|
||||||
|
|
||||||
### Manual Installation
|
### Basic Usage
|
||||||
|
|
||||||
If you don't want to use `make`, you can manually install the extension:
|
|
||||||
|
|
||||||
1. Copy `c77_secure_db.control` to your PostgreSQL shared extension directory:
|
|
||||||
```bash
|
|
||||||
cp c77_secure_db.control $(pg_config --sharedir)/extension/
|
|
||||||
```
|
|
||||||
|
|
||||||
2. Copy the SQL file to your PostgreSQL extension directory:
|
|
||||||
```bash
|
|
||||||
cp c77_secure_db--1.0.0.sql $(pg_config --sharedir)/extension/
|
|
||||||
```
|
|
||||||
|
|
||||||
3. Create the extension in your database:
|
|
||||||
```sql
|
|
||||||
CREATE EXTENSION pgcrypto; -- required dependency
|
|
||||||
CREATE EXTENSION c77_secure_db;
|
|
||||||
```
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
### Setting Up a Secure Schema
|
|
||||||
|
|
||||||
1. Create a schema for your secure tables:
|
|
||||||
```sql
|
|
||||||
CREATE SCHEMA secure_data;
|
|
||||||
```
|
|
||||||
|
|
||||||
2. Register the schema with the secure database system:
|
|
||||||
```sql
|
|
||||||
SELECT c77_manage_secure_schemas('add', 'secure_data');
|
|
||||||
```
|
|
||||||
|
|
||||||
3. Apply triggers to existing tables in the schema:
|
|
||||||
```sql
|
|
||||||
SELECT c77_apply_prevent_triggers('secure_data');
|
|
||||||
```
|
|
||||||
|
|
||||||
### Creating Secure Tables
|
|
||||||
|
|
||||||
When creating tables in your secure schema, include the required columns for security and auditing:
|
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
CREATE TABLE secure_data.sensitive_data (
|
-- Create secure schema
|
||||||
|
CREATE SCHEMA myapp;
|
||||||
|
SELECT c77_secure_db_manage_secure_schemas('add', 'myapp');
|
||||||
|
|
||||||
|
-- Create secure table
|
||||||
|
CREATE TABLE myapp.users (
|
||||||
id BIGSERIAL PRIMARY KEY,
|
id BIGSERIAL PRIMARY KEY,
|
||||||
name TEXT NOT NULL,
|
name TEXT NOT NULL,
|
||||||
description TEXT,
|
email TEXT UNIQUE NOT NULL,
|
||||||
|
-- Required security columns
|
||||||
content_hash TEXT,
|
content_hash TEXT,
|
||||||
hash_version INTEGER DEFAULT 1,
|
hash_version INTEGER DEFAULT 1,
|
||||||
created_at TIMESTAMPTZ DEFAULT NOW(),
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
updated_at TIMESTAMPTZ DEFAULT NOW(),
|
updated_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
deleted_at TIMESTAMPTZ DEFAULT NULL
|
deleted_at TIMESTAMPTZ
|
||||||
);
|
);
|
||||||
```
|
|
||||||
|
|
||||||
The triggers will be automatically applied to new tables in registered schemas.
|
-- Secure operations (direct SQL is automatically blocked)
|
||||||
|
SELECT c77_secure_db_operation(jsonb_build_object(
|
||||||
### Performing Secure Operations
|
'schema_name', 'myapp',
|
||||||
|
'table_name', 'users',
|
||||||
Instead of using direct SQL commands, use the `c77_secure_db_operation` function:
|
|
||||||
|
|
||||||
```sql
|
|
||||||
-- Insert
|
|
||||||
SELECT c77_secure_db_operation(
|
|
||||||
jsonb_build_object(
|
|
||||||
'schema_name', 'secure_data',
|
|
||||||
'table_name', 'sensitive_data',
|
|
||||||
'operation', 'insert',
|
'operation', 'insert',
|
||||||
'data', jsonb_build_object(
|
'data', jsonb_build_object(
|
||||||
'name', 'Example Entry',
|
'name', 'John Doe',
|
||||||
'description', 'This is a test'
|
'email', 'john@example.com'
|
||||||
)
|
)
|
||||||
)
|
));
|
||||||
);
|
```
|
||||||
|
|
||||||
-- Update
|
## ✨ **Key Features**
|
||||||
|
|
||||||
|
### **Token-Based Security**
|
||||||
|
- **5-second expiring tokens** prevent replay attacks
|
||||||
|
- **Single-use authorization** - tokens cannot be reused
|
||||||
|
- **Session-specific** - tied to database connection
|
||||||
|
- **Automatic cleanup** - no token buildup
|
||||||
|
|
||||||
|
### **Content Hash Verification**
|
||||||
|
- **SHA-256 cryptographic hashing** for tamper detection
|
||||||
|
- **Configurable exclusions** - exclude frequently changing columns
|
||||||
|
- **Automatic calculation** - hashes computed transparently
|
||||||
|
- **Bulk verification** - check entire tables for integrity
|
||||||
|
|
||||||
|
### **Comprehensive Audit Logging**
|
||||||
|
- **Every operation logged** with complete context
|
||||||
|
- **Performance metrics** - execution time tracking
|
||||||
|
- **User attribution** - who did what, when
|
||||||
|
- **Error tracking** - detailed failure analysis
|
||||||
|
|
||||||
|
### **RBAC Integration**
|
||||||
|
- **Optional c77_rbac integration** - works standalone or with advanced permissions
|
||||||
|
- **Feature-based security** - granular permission control
|
||||||
|
- **Scope-based access** - department, region, or custom scopes
|
||||||
|
- **Graceful degradation** - works without RBAC if not needed
|
||||||
|
|
||||||
|
## 🔧 **Advanced Features**
|
||||||
|
|
||||||
|
### **Bulk Operations**
|
||||||
|
```sql
|
||||||
|
-- Verify multiple records at once
|
||||||
|
SELECT c77_secure_db_check_freshness_bulk(
|
||||||
|
'myapp', 'users',
|
||||||
|
'[{"id":1,"name":"John"},{"id":2,"name":"Jane"}]'::jsonb
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
### **Hash Verification**
|
||||||
|
```sql
|
||||||
|
-- Check all records in a table
|
||||||
|
SELECT c77_secure_db_verify_content_hashes('myapp', 'users');
|
||||||
|
|
||||||
|
-- Fix any hash mismatches
|
||||||
|
SELECT c77_secure_db_verify_content_hashes('myapp', 'users', true);
|
||||||
|
```
|
||||||
|
|
||||||
|
### **RBAC-Protected Operations**
|
||||||
|
```sql
|
||||||
|
-- Set user context
|
||||||
|
SET "c77_rbac.external_id" TO '123';
|
||||||
|
|
||||||
|
-- Use operation with permission checking
|
||||||
SELECT c77_secure_db_operation(
|
SELECT c77_secure_db_operation(
|
||||||
jsonb_build_object(
|
jsonb_build_object(...),
|
||||||
'schema_name', 'secure_data',
|
true, -- check RBAC
|
||||||
'table_name', 'sensitive_data',
|
'secure_db_insert' -- required permission
|
||||||
'operation', 'update',
|
|
||||||
'primary_key', 'id',
|
|
||||||
'data', jsonb_build_object(
|
|
||||||
'id', 1,
|
|
||||||
'name', 'Updated Example',
|
|
||||||
'description', 'This has been updated'
|
|
||||||
)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
-- Delete (soft delete if deleted_at column exists)
|
|
||||||
SELECT c77_secure_db_operation(
|
|
||||||
jsonb_build_object(
|
|
||||||
'schema_name', 'secure_data',
|
|
||||||
'table_name', 'sensitive_data',
|
|
||||||
'operation', 'delete',
|
|
||||||
'primary_key', 'id',
|
|
||||||
'data', jsonb_build_object(
|
|
||||||
'id', 1
|
|
||||||
)
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
```
|
```
|
||||||
|
|
||||||
### Generating Operation Templates
|
## 🏗️ **Framework Integration**
|
||||||
|
|
||||||
You can generate operation templates for any table:
|
### **Laravel**
|
||||||
|
```php
|
||||||
|
// Service class integration
|
||||||
|
class SecureDbService {
|
||||||
|
public function insert(string $table, array $data): array {
|
||||||
|
$result = DB::selectOne('SELECT c77_secure_db_operation(?) as result', [
|
||||||
|
json_encode([
|
||||||
|
'schema_name' => 'myapp',
|
||||||
|
'table_name' => $table,
|
||||||
|
'operation' => 'insert',
|
||||||
|
'data' => $data
|
||||||
|
])
|
||||||
|
]);
|
||||||
|
|
||||||
```sql
|
return json_decode($result->result, true);
|
||||||
SELECT c77_get_operation_template('secure_data', 'sensitive_data', 'insert');
|
}
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
This will generate a complete SQL template that you can copy and modify.
|
### **Node.js**
|
||||||
|
```javascript
|
||||||
### Verifying Data Integrity
|
// Express integration
|
||||||
|
const secureDb = {
|
||||||
To check if a record has been tampered with:
|
async insert(table, data) {
|
||||||
|
const result = await pool.query(
|
||||||
```sql
|
'SELECT c77_secure_db_operation($1) as result',
|
||||||
SELECT c77_check_freshness(
|
[JSON.stringify({
|
||||||
'secure_data',
|
schema_name: 'myapp',
|
||||||
'sensitive_data',
|
table_name: table,
|
||||||
jsonb_build_object('id', 1, 'name', 'Example Entry', 'description', 'This is a test')
|
operation: 'insert',
|
||||||
|
data: data
|
||||||
|
})]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
return JSON.parse(result.rows[0].result);
|
||||||
|
}
|
||||||
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
To verify content hashes for all records in a table:
|
### **Django**
|
||||||
|
```python
|
||||||
|
# Django service integration
|
||||||
|
class SecureDbService:
|
||||||
|
def insert(self, table, data):
|
||||||
|
with connection.cursor() as cursor:
|
||||||
|
cursor.execute(
|
||||||
|
"SELECT c77_secure_db_operation(%s) as result",
|
||||||
|
[json.dumps({
|
||||||
|
'schema_name': 'myapp',
|
||||||
|
'table_name': table,
|
||||||
|
'operation': 'insert',
|
||||||
|
'data': data
|
||||||
|
})]
|
||||||
|
)
|
||||||
|
result = cursor.fetchone()[0]
|
||||||
|
return json.loads(result)
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📊 **Monitoring & Maintenance**
|
||||||
|
|
||||||
|
### **Health Monitoring**
|
||||||
|
```sql
|
||||||
|
-- System health check
|
||||||
|
SELECT c77_secure_db_health_check();
|
||||||
|
|
||||||
|
-- Performance monitoring
|
||||||
|
SELECT
|
||||||
|
operation_type,
|
||||||
|
avg(execution_time_ms) as avg_time,
|
||||||
|
count(*) as operation_count
|
||||||
|
FROM c77_secure_db_operation_audit
|
||||||
|
WHERE created_at > now() - interval '1 hour'
|
||||||
|
GROUP BY operation_type;
|
||||||
|
```
|
||||||
|
|
||||||
|
### **Maintenance**
|
||||||
|
```sql
|
||||||
|
-- Daily cleanup
|
||||||
|
SELECT c77_secure_db_cleanup_expired_tokens();
|
||||||
|
|
||||||
|
-- Weekly integrity check
|
||||||
|
SELECT c77_secure_db_verify_content_hashes('myapp', 'users');
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🛡️ **Security Architecture**
|
||||||
|
|
||||||
|
### **Multi-Layer Protection**
|
||||||
|
|
||||||
|
1. **Trigger Layer**: Prevents all direct SQL modifications
|
||||||
|
2. **Token Layer**: Authorizes legitimate operations with expiring tokens
|
||||||
|
3. **Hash Layer**: Detects unauthorized data tampering
|
||||||
|
4. **Audit Layer**: Logs all operations for compliance
|
||||||
|
5. **RBAC Layer**: Optional permission-based access control
|
||||||
|
|
||||||
|
### **Threat Mitigation**
|
||||||
|
|
||||||
|
- ✅ **SQL Injection**: Cannot bypass trigger protection
|
||||||
|
- ✅ **Data Tampering**: Detected by content hash verification
|
||||||
|
- ✅ **Unauthorized Access**: Blocked by token validation
|
||||||
|
- ✅ **Replay Attacks**: Prevented by single-use tokens
|
||||||
|
- ✅ **Session Hijacking**: Mitigated by session-specific tokens
|
||||||
|
- ✅ **Application Bugs**: Cannot bypass database-level security
|
||||||
|
|
||||||
|
## 🔄 **Migration from v1.x**
|
||||||
|
|
||||||
|
**⚠️ BREAKING CHANGES**: Version 2.0 is a complete security rewrite.
|
||||||
|
|
||||||
|
The vulnerable session variable approach has been completely removed:
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
SELECT c77_verify_content_hashes('secure_data', 'sensitive_data');
|
-- ❌ v1.x had this vulnerability (NEVER use this approach)
|
||||||
|
SET "myapp.allow_direct_modification" TO 'true'; -- Could bypass security!
|
||||||
|
|
||||||
|
-- ✅ v2.0 uses secure token-based authorization (unbypassable)
|
||||||
|
-- All security is handled internally by the extension
|
||||||
```
|
```
|
||||||
|
|
||||||
To fix any hash mismatches:
|
**Migration Steps:**
|
||||||
|
1. Backup your data
|
||||||
|
2. Drop old extension: `DROP EXTENSION c77_secure_db CASCADE;`
|
||||||
|
3. Install v2.0: `CREATE EXTENSION c77_secure_db;`
|
||||||
|
4. Re-register secure schemas
|
||||||
|
5. Run security tests: `SELECT c77_secure_db_run_all_tests();`
|
||||||
|
|
||||||
|
## 📚 **Documentation**
|
||||||
|
|
||||||
|
- **[USAGE.md](USAGE.md)** - Comprehensive usage guide with examples
|
||||||
|
- **[INSTALL.md](INSTALL.md)** - Detailed installation instructions
|
||||||
|
- **[CHANGELOG.md](CHANGELOG.md)** - Version history and changes
|
||||||
|
- **[SECURITY.md](SECURITY.md)** - Security policies and reporting
|
||||||
|
|
||||||
|
## ⚡ **Performance**
|
||||||
|
|
||||||
|
Designed for production workloads:
|
||||||
|
|
||||||
|
- **Optimized hash calculations** - Efficient SHA-256 implementation
|
||||||
|
- **Indexed operations** - Fast token lookups and audit queries
|
||||||
|
- **Bulk processing** - Handle thousands of records efficiently
|
||||||
|
- **Minimal overhead** - < 10ms typical operation time
|
||||||
|
- **Scalable architecture** - Tested with millions of records
|
||||||
|
|
||||||
|
## 🧪 **Testing**
|
||||||
|
|
||||||
|
Built-in comprehensive test suite:
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
SELECT c77_verify_content_hashes('secure_data', 'sensitive_data', true);
|
-- Run all tests (must pass before production use)
|
||||||
|
SELECT c77_secure_db_run_all_tests();
|
||||||
|
|
||||||
|
-- Security-specific tests
|
||||||
|
SELECT c77_secure_db_test_security();
|
||||||
|
|
||||||
|
-- RBAC integration tests
|
||||||
|
SELECT c77_secure_db_test_rbac_integration();
|
||||||
```
|
```
|
||||||
|
|
||||||
## Function Reference
|
## 🏢 **Production Use Cases**
|
||||||
|
|
||||||
### Main Functions
|
### **Healthcare**
|
||||||
|
- HIPAA compliance with audit trails
|
||||||
|
- Patient data integrity verification
|
||||||
|
- Role-based access by department
|
||||||
|
|
||||||
- `c77_secure_db_operation(jsonb)`: Securely performs database operations
|
### **Financial Services**
|
||||||
- `c77_verify_content_hashes(text, text, boolean, integer)`: Verifies content hashes for all records in a table
|
- Transaction integrity protection
|
||||||
- `c77_check_freshness(text, text, jsonb)`: Verifies if a record has been modified
|
- Regulatory audit requirements
|
||||||
- `c77_calculate_content_hash(text, text, jsonb)`: Calculates a content hash for a record
|
- Multi-level approval workflows
|
||||||
- `c77_get_operation_template(text, text, text)`: Generates a template for secure operations
|
|
||||||
- `c77_manage_secure_schemas(text, text)`: Manages secure schemas
|
|
||||||
|
|
||||||
### Support Functions
|
### **E-commerce**
|
||||||
|
- Customer data protection
|
||||||
|
- Order processing security
|
||||||
|
- Payment data integrity
|
||||||
|
|
||||||
- `c77_prevent_direct_modification()`: Trigger function to prevent direct modifications
|
### **Government**
|
||||||
- `c77_apply_prevent_triggers(text)`: Applies prevention triggers to all tables in a schema
|
- Classification-based access control
|
||||||
- `c77_auto_apply_prevent_triggers()`: Event trigger function for automatically applying triggers
|
- Data integrity verification
|
||||||
|
- Complete audit trails
|
||||||
|
|
||||||
## Integration with Application Frameworks
|
## 🤝 **Contributing**
|
||||||
|
|
||||||
### Laravel Integration
|
Contributions are welcome! Please:
|
||||||
|
|
||||||
This extension can be paired with a Laravel integration package to provide a seamless experience. Check out the Laravel integration guide for more details.
|
1. Fork the repository
|
||||||
|
2. Create a feature branch
|
||||||
|
3. Add tests for new functionality
|
||||||
|
4. Ensure all tests pass
|
||||||
|
5. Submit a pull request
|
||||||
|
|
||||||
## Security Considerations
|
### **Development Setup**
|
||||||
|
|
||||||
- The `myapp.allow_direct_modification` setting controls whether direct modifications are allowed. This extension manages this setting internally and resets it after each operation.
|
```bash
|
||||||
- Ensure that only trusted users have permission to execute the functions in this extension.
|
# Clone repository
|
||||||
- For maximum security, consider revoking direct INSERT, UPDATE, and DELETE permissions on secure tables for application users.
|
git clone https://github.com/yourusername/c77_secure_db.git
|
||||||
|
cd c77_secure_db
|
||||||
|
|
||||||
## License
|
# Install in development PostgreSQL
|
||||||
|
make install
|
||||||
|
|
||||||
This project is licensed under the MIT License - see the LICENSE file for details.
|
# Run tests
|
||||||
|
make test
|
||||||
|
```
|
||||||
|
|
||||||
## Contributing
|
## 📋 **Requirements**
|
||||||
|
|
||||||
Contributions are welcome! Please feel free to submit a Pull Request.
|
- **PostgreSQL**: 14 or later
|
||||||
|
- **Extensions**: pgcrypto (required), c77_rbac (optional)
|
||||||
|
- **Installation**: Superuser privileges required for installation
|
||||||
|
- **Usage**: Regular database users (with granted roles)
|
||||||
|
- **Platform**: Linux, macOS, Windows (with PostgreSQL)
|
||||||
|
|
||||||
|
## 📝 **License**
|
||||||
|
|
||||||
|
MIT License - see [LICENSE](LICENSE) file for details.
|
||||||
|
|
||||||
|
## 🆘 **Support**
|
||||||
|
|
||||||
|
- **Documentation**: Check [USAGE.md](USAGE.md) for comprehensive guides
|
||||||
|
- **Issues**: Report bugs via GitHub Issues
|
||||||
|
- **Security**: See [SECURITY.md](SECURITY.md) for vulnerability reporting
|
||||||
|
- **Discussions**: Use GitHub Discussions for questions
|
||||||
|
|
||||||
|
## 🔗 **Related Projects**
|
||||||
|
|
||||||
|
- **[c77_rbac](https://github.com/yourusername/c77_rbac)** - Role-Based Access Control extension
|
||||||
|
- **PostgreSQL Extensions** - Part of the c77_ extension family
|
||||||
|
|
||||||
|
## ⭐ **Why Choose c77_secure_db?**
|
||||||
|
|
||||||
|
> "Traditional application-level security can be bypassed by bugs, SQL injection, or direct database access. c77_secure_db provides unbypassable database-level protection with cryptographic integrity verification."
|
||||||
|
|
||||||
|
### **Before c77_secure_db**
|
||||||
|
```sql
|
||||||
|
-- ❌ Vulnerable to bypasses
|
||||||
|
INSERT INTO users (name) VALUES ('Hacker'); -- Could work!
|
||||||
|
```
|
||||||
|
|
||||||
|
### **After c77_secure_db**
|
||||||
|
```sql
|
||||||
|
-- ❌ Automatically blocked
|
||||||
|
INSERT INTO users (name) VALUES ('Hacker');
|
||||||
|
-- ERROR: Direct modifications not allowed
|
||||||
|
|
||||||
|
-- ✅ Must use secure API
|
||||||
|
SELECT c77_secure_db_operation(...); -- Audited, authorized, verified
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Get started today and secure your PostgreSQL database with enterprise-grade protection!**
|
||||||
|
|
||||||
|
```sql
|
||||||
|
CREATE EXTENSION c77_secure_db;
|
||||||
|
SELECT c77_secure_db_run_all_tests(); -- Must pass!
|
||||||
|
```
|
461
SECURITY.md
Normal file
461
SECURITY.md
Normal file
@ -0,0 +1,461 @@
|
|||||||
|
# Security Policy
|
||||||
|
|
||||||
|
## 🛡️ **Our Security Commitment**
|
||||||
|
|
||||||
|
The c77_secure_db extension is designed with security as the primary concern. This document outlines our security policies, vulnerability reporting procedures, and the security architecture of the extension.
|
||||||
|
|
||||||
|
## 🚨 **Reporting Security Vulnerabilities**
|
||||||
|
|
||||||
|
### **Please DO NOT report security vulnerabilities through public GitHub issues.**
|
||||||
|
|
||||||
|
If you discover a security vulnerability in c77_secure_db, please report it responsibly:
|
||||||
|
|
||||||
|
### **Preferred Reporting Method**
|
||||||
|
- **Email**: [security@yourcompany.com](mailto:security@yourcompany.com)
|
||||||
|
- **Subject**: `[SECURITY] c77_secure_db Vulnerability Report`
|
||||||
|
- **Encryption**: Use our PGP key if possible (key ID: YOUR_PGP_KEY_ID)
|
||||||
|
|
||||||
|
### **What to Include**
|
||||||
|
1. **Description**: Clear description of the vulnerability
|
||||||
|
2. **Steps to Reproduce**: Detailed steps to reproduce the issue
|
||||||
|
3. **Impact Assessment**: Your assessment of the potential impact
|
||||||
|
4. **Proof of Concept**: If available, a proof-of-concept (responsibly disclosed)
|
||||||
|
5. **Suggested Fix**: If you have ideas for remediation
|
||||||
|
6. **Contact Information**: How we can reach you for follow-up
|
||||||
|
|
||||||
|
### **Response Timeline**
|
||||||
|
- **Initial Response**: Within 24 hours of report
|
||||||
|
- **Vulnerability Assessment**: Within 72 hours
|
||||||
|
- **Fix Development**: Timeline varies based on severity
|
||||||
|
- **Security Advisory**: Published after fix is available
|
||||||
|
|
||||||
|
### **Responsible Disclosure**
|
||||||
|
We request that you:
|
||||||
|
- Give us reasonable time to address the issue before public disclosure
|
||||||
|
- Avoid accessing or modifying data that doesn't belong to you
|
||||||
|
- Don't perform actions that could harm the availability of the service
|
||||||
|
- Only test against your own installations
|
||||||
|
|
||||||
|
## 🔐 **Security Architecture**
|
||||||
|
|
||||||
|
### **Multi-Layer Security Model**
|
||||||
|
|
||||||
|
c77_secure_db implements defense-in-depth with multiple security layers:
|
||||||
|
|
||||||
|
#### **Layer 1: Trigger Protection**
|
||||||
|
- **Purpose**: Prevent all direct database modifications
|
||||||
|
- **Mechanism**: PostgreSQL triggers on all protected tables
|
||||||
|
- **Coverage**: INSERT, UPDATE, DELETE operations
|
||||||
|
- **Bypass Prevention**: Cannot be disabled without superuser access
|
||||||
|
|
||||||
|
#### **Layer 2: Token Authorization**
|
||||||
|
- **Purpose**: Authorize legitimate operations
|
||||||
|
- **Mechanism**: Short-lived, single-use authorization tokens
|
||||||
|
- **Token Lifespan**: 5 seconds maximum
|
||||||
|
- **Session Binding**: Tokens tied to specific database sessions
|
||||||
|
- **Replay Prevention**: Single-use tokens prevent replay attacks
|
||||||
|
|
||||||
|
#### **Layer 3: Content Integrity**
|
||||||
|
- **Purpose**: Detect unauthorized data modifications
|
||||||
|
- **Mechanism**: SHA-256 cryptographic hashing
|
||||||
|
- **Coverage**: All business data (excluding system columns)
|
||||||
|
- **Verification**: On-demand and scheduled integrity checks
|
||||||
|
|
||||||
|
#### **Layer 4: Audit Trail**
|
||||||
|
- **Purpose**: Complete operation logging for forensics
|
||||||
|
- **Coverage**: All secure operations, successes and failures
|
||||||
|
- **Retention**: Configurable retention periods for compliance
|
||||||
|
- **Immutability**: Audit logs protected by same security layers
|
||||||
|
|
||||||
|
#### **Layer 5: Access Control (Optional)**
|
||||||
|
- **Purpose**: Role-based permission enforcement
|
||||||
|
- **Integration**: c77_rbac extension for advanced permissions
|
||||||
|
- **Granularity**: Feature-based and scope-based access control
|
||||||
|
- **Fallback**: Secure operation without RBAC if not available
|
||||||
|
|
||||||
|
### **Threat Model**
|
||||||
|
|
||||||
|
#### **Threats Mitigated**
|
||||||
|
|
||||||
|
| Threat Category | Mitigation Strategy | Security Layer |
|
||||||
|
|----------------|-------------------|----------------|
|
||||||
|
| **SQL Injection** | Trigger protection blocks direct SQL | Layer 1 |
|
||||||
|
| **Application Bypass** | Token validation required for all operations | Layer 2 |
|
||||||
|
| **Data Tampering** | Content hash verification detects changes | Layer 3 |
|
||||||
|
| **Replay Attacks** | Single-use, time-limited tokens | Layer 2 |
|
||||||
|
| **Session Hijacking** | Session-specific token binding | Layer 2 |
|
||||||
|
| **Privilege Escalation** | Controlled function execution with SECURITY DEFINER | All Layers |
|
||||||
|
| **Audit Log Tampering** | Audit data protected by same security layers | Layer 4 |
|
||||||
|
| **Unauthorized Access** | RBAC integration with scope-based permissions | Layer 5 |
|
||||||
|
|
||||||
|
#### **Assumptions**
|
||||||
|
|
||||||
|
Our security model assumes:
|
||||||
|
- PostgreSQL superuser access is properly controlled
|
||||||
|
- Database network communication is encrypted (TLS)
|
||||||
|
- Application servers are reasonably secure
|
||||||
|
- System administrators follow security best practices
|
||||||
|
- Regular security updates are applied
|
||||||
|
|
||||||
|
#### **Known Limitations**
|
||||||
|
|
||||||
|
- **PostgreSQL Superuser**: Can bypass all protections (by design)
|
||||||
|
- **Physical Access**: Direct file system access can compromise data
|
||||||
|
- **Memory Dumps**: Active tokens might be visible in memory dumps
|
||||||
|
- **Time Synchronization**: Token expiration depends on accurate system time
|
||||||
|
- **Extension Dependencies**: Security depends on pgcrypto extension integrity
|
||||||
|
|
||||||
|
### **Cryptographic Details**
|
||||||
|
|
||||||
|
#### **Content Hashing**
|
||||||
|
- **Algorithm**: SHA-256
|
||||||
|
- **Input**: Sorted key-value pairs of business data
|
||||||
|
- **Salt**: None (deterministic hashing for verification)
|
||||||
|
- **Exclusions**: System columns (timestamps, hashes, etc.)
|
||||||
|
- **Performance**: Optimized for production workloads
|
||||||
|
|
||||||
|
#### **Token Generation**
|
||||||
|
- **Source**: PostgreSQL's `gen_random_uuid()` function
|
||||||
|
- **Entropy**: Based on system randomness
|
||||||
|
- **Format**: UUID v4 standard
|
||||||
|
- **Storage**: Temporary database table with automatic cleanup
|
||||||
|
|
||||||
|
## 🔒 **Security Controls**
|
||||||
|
|
||||||
|
### **Access Controls**
|
||||||
|
|
||||||
|
#### **Installation Requirements**
|
||||||
|
- **Superuser Required**: Initial installation requires PostgreSQL superuser
|
||||||
|
- **Post-Installation**: Regular users can operate with granted roles
|
||||||
|
|
||||||
|
#### **Runtime Permissions**
|
||||||
|
- **c77_secure_db_readonly**: Read-only operations (freshness checks, health monitoring)
|
||||||
|
- **c77_secure_db_user**: Standard secure operations (insert, update, delete)
|
||||||
|
- **c77_secure_db_admin**: Administrative functions (hash verification, schema management)
|
||||||
|
|
||||||
|
#### **RBAC Integration**
|
||||||
|
- **Optional**: Works with or without c77_rbac extension
|
||||||
|
- **Granular**: Feature-based permissions (secure_db_insert, secure_db_update, etc.)
|
||||||
|
- **Scoped**: Department, region, or custom scope-based access
|
||||||
|
- **Audited**: All RBAC decisions logged in audit trail
|
||||||
|
|
||||||
|
### **Data Protection**
|
||||||
|
|
||||||
|
#### **Data at Rest**
|
||||||
|
- **Database Files**: Protected by PostgreSQL's standard file permissions
|
||||||
|
- **Hash Storage**: Content hashes stored alongside data in same security context
|
||||||
|
- **Audit Logs**: Subject to same database security as operational data
|
||||||
|
- **Tokens**: Automatically purged expired tokens (default: daily cleanup)
|
||||||
|
|
||||||
|
#### **Data in Transit**
|
||||||
|
- **Application to Database**: Use PostgreSQL TLS connections
|
||||||
|
- **Token Transmission**: Tokens transmitted via secure database session
|
||||||
|
- **Audit Data**: Logged locally within database, no network transmission
|
||||||
|
|
||||||
|
#### **Data Processing**
|
||||||
|
- **Hash Calculation**: Performed within database using pgcrypto
|
||||||
|
- **Token Validation**: Atomic database operations with automatic cleanup
|
||||||
|
- **Operation Logging**: Immediate logging within same transaction context
|
||||||
|
|
||||||
|
### **Monitoring and Alerting**
|
||||||
|
|
||||||
|
#### **Security Monitoring**
|
||||||
|
```sql
|
||||||
|
-- Key security metrics to monitor
|
||||||
|
SELECT
|
||||||
|
'Error Rate' as metric,
|
||||||
|
count(*) FILTER (WHERE success = false)::numeric / count(*) * 100 as percentage
|
||||||
|
FROM c77_secure_db_operation_audit
|
||||||
|
WHERE created_at > now() - interval '1 hour';
|
||||||
|
|
||||||
|
-- Token anomalies
|
||||||
|
SELECT count(*) as active_tokens
|
||||||
|
FROM c77_secure_db_auth_tokens
|
||||||
|
WHERE expires_at > now();
|
||||||
|
|
||||||
|
-- Unusual access patterns
|
||||||
|
SELECT user_name, count(*) as operations
|
||||||
|
FROM c77_secure_db_operation_audit
|
||||||
|
WHERE created_at > now() - interval '1 hour'
|
||||||
|
GROUP BY user_name
|
||||||
|
HAVING count(*) > 100;
|
||||||
|
```
|
||||||
|
|
||||||
|
#### **Recommended Alerts**
|
||||||
|
- **Error Rate > 5%**: Indicates potential security issues or attacks
|
||||||
|
- **Active Tokens > 100**: May indicate token cleanup problems
|
||||||
|
- **Hash Mismatches**: Critical security alert requiring immediate investigation
|
||||||
|
- **Off-Hours Activity**: Unusual activity outside business hours
|
||||||
|
- **Repeated Failures**: Multiple failed operations from same user
|
||||||
|
|
||||||
|
## 🔄 **Security Update Process**
|
||||||
|
|
||||||
|
### **Severity Classification**
|
||||||
|
|
||||||
|
#### **Critical (CVSS 9.0-10.0)**
|
||||||
|
- **Timeline**: Patch within 24-48 hours
|
||||||
|
- **Examples**: Authentication bypass, data corruption, privilege escalation
|
||||||
|
- **Response**: Emergency release, immediate security advisory
|
||||||
|
|
||||||
|
#### **High (CVSS 7.0-8.9)**
|
||||||
|
- **Timeline**: Patch within 1 week
|
||||||
|
- **Examples**: Information disclosure, denial of service
|
||||||
|
- **Response**: Priority release, security advisory
|
||||||
|
|
||||||
|
#### **Medium (CVSS 4.0-6.9)**
|
||||||
|
- **Timeline**: Patch within 30 days
|
||||||
|
- **Examples**: Less severe information disclosure, limited DoS
|
||||||
|
- **Response**: Regular release cycle, documented in changelog
|
||||||
|
|
||||||
|
#### **Low (CVSS 0.1-3.9)**
|
||||||
|
- **Timeline**: Next regular release
|
||||||
|
- **Examples**: Minor information disclosure, edge cases
|
||||||
|
- **Response**: Standard release process
|
||||||
|
|
||||||
|
### **Update Distribution**
|
||||||
|
|
||||||
|
#### **Security Advisories**
|
||||||
|
- **Format**: GitHub Security Advisories
|
||||||
|
- **Content**: CVE ID, affected versions, mitigation steps, upgrade instructions
|
||||||
|
- **Distribution**: GitHub, mailing list, website
|
||||||
|
|
||||||
|
#### **Patch Releases**
|
||||||
|
- **Naming**: Increment patch version (e.g., 2.0 → 2.0.1)
|
||||||
|
- **Content**: Security fixes only, minimal functional changes
|
||||||
|
- **Testing**: Automated security test suite must pass
|
||||||
|
- **Backwards Compatibility**: Maintained unless security requires breaking changes
|
||||||
|
|
||||||
|
#### **Upgrade Instructions**
|
||||||
|
```sql
|
||||||
|
-- Security update process
|
||||||
|
-- 1. Backup your database
|
||||||
|
pg_dump your_database > backup_before_security_update.sql
|
||||||
|
|
||||||
|
-- 2. Install new extension files
|
||||||
|
sudo cp c77_secure_db--2.0.1.sql $(pg_config --sharedir)/extension/
|
||||||
|
|
||||||
|
-- 3. Update extension
|
||||||
|
ALTER EXTENSION c77_secure_db UPDATE TO '2.0.1';
|
||||||
|
|
||||||
|
-- 4. Verify security update
|
||||||
|
SELECT c77_secure_db_run_all_tests();
|
||||||
|
-- Must return: "overall_status": "ALL_TESTS_PASSED"
|
||||||
|
|
||||||
|
-- 5. Check health after update
|
||||||
|
SELECT c77_secure_db_health_check();
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📋 **Compliance and Standards**
|
||||||
|
|
||||||
|
### **Security Standards Alignment**
|
||||||
|
|
||||||
|
#### **NIST Cybersecurity Framework**
|
||||||
|
- **Identify**: Asset inventory, risk assessment procedures
|
||||||
|
- **Protect**: Access controls, data security, protective technology
|
||||||
|
- **Detect**: Security monitoring, anomaly detection
|
||||||
|
- **Respond**: Incident response procedures, forensic capabilities
|
||||||
|
- **Recover**: Recovery planning, backup and restore procedures
|
||||||
|
|
||||||
|
#### **OWASP Guidelines**
|
||||||
|
- **A01 Broken Access Control**: Prevented by trigger protection and RBAC
|
||||||
|
- **A02 Cryptographic Failures**: SHA-256 hashing with proper implementation
|
||||||
|
- **A03 Injection**: SQL injection prevented by trigger layer
|
||||||
|
- **A08 Software Integrity Failures**: Content hash verification
|
||||||
|
- **A09 Security Logging**: Comprehensive audit trail
|
||||||
|
|
||||||
|
#### **Database Security Best Practices**
|
||||||
|
- **Principle of Least Privilege**: Granular role-based permissions
|
||||||
|
- **Defense in Depth**: Multiple security layers
|
||||||
|
- **Audit Logging**: Complete operation trail
|
||||||
|
- **Data Integrity**: Cryptographic verification
|
||||||
|
- **Access Controls**: Authentication and authorization
|
||||||
|
|
||||||
|
### **Regulatory Considerations**
|
||||||
|
|
||||||
|
#### **HIPAA (Healthcare)**
|
||||||
|
- **Administrative Safeguards**: Access management, audit procedures
|
||||||
|
- **Physical Safeguards**: Database server protection (external to extension)
|
||||||
|
- **Technical Safeguards**: Access controls, audit logs, data integrity
|
||||||
|
|
||||||
|
#### **SOX (Financial)**
|
||||||
|
- **Internal Controls**: Automated security controls, segregation of duties
|
||||||
|
- **Audit Trail**: Complete transaction logging with timestamps
|
||||||
|
- **Data Integrity**: Hash verification for financial data
|
||||||
|
|
||||||
|
#### **GDPR (Privacy)**
|
||||||
|
- **Data Protection**: Encryption at rest and in transit (implementation-dependent)
|
||||||
|
- **Audit Requirements**: Complete processing logs
|
||||||
|
- **Right to Deletion**: Secure deletion capabilities (soft delete support)
|
||||||
|
|
||||||
|
## 🔍 **Security Testing**
|
||||||
|
|
||||||
|
### **Automated Security Tests**
|
||||||
|
|
||||||
|
The extension includes comprehensive security tests:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- Run complete security test suite
|
||||||
|
SELECT c77_secure_db_run_all_tests();
|
||||||
|
|
||||||
|
-- Specific security tests
|
||||||
|
SELECT c77_secure_db_test_security();
|
||||||
|
|
||||||
|
-- RBAC integration tests
|
||||||
|
SELECT c77_secure_db_test_rbac_integration();
|
||||||
|
```
|
||||||
|
|
||||||
|
#### **Test Coverage**
|
||||||
|
- **Bypass Prevention**: Attempts to circumvent trigger protection
|
||||||
|
- **Token Security**: Token expiration, single-use validation, session binding
|
||||||
|
- **Hash Integrity**: Content hash calculation and verification
|
||||||
|
- **RBAC Integration**: Permission enforcement, scope validation
|
||||||
|
- **Error Handling**: Security-relevant error conditions
|
||||||
|
- **Performance**: Security overhead measurement
|
||||||
|
|
||||||
|
### **Security Validation Requirements**
|
||||||
|
|
||||||
|
#### **Pre-Release Testing**
|
||||||
|
- [ ] All security tests pass with 100% success rate
|
||||||
|
- [ ] No bypass vulnerabilities identified
|
||||||
|
- [ ] Performance impact within acceptable limits
|
||||||
|
- [ ] RBAC integration functions correctly
|
||||||
|
- [ ] Error handling doesn't leak sensitive information
|
||||||
|
- [ ] Audit logging captures all required events
|
||||||
|
|
||||||
|
#### **Production Deployment Validation**
|
||||||
|
```sql
|
||||||
|
-- Mandatory post-deployment security check
|
||||||
|
DO $
|
||||||
|
DECLARE
|
||||||
|
v_test_results jsonb;
|
||||||
|
BEGIN
|
||||||
|
-- Run security tests
|
||||||
|
SELECT c77_secure_db_run_all_tests() INTO v_test_results;
|
||||||
|
|
||||||
|
-- Verify all tests passed
|
||||||
|
IF (v_test_results->>'overall_status') != 'ALL_TESTS_PASSED' THEN
|
||||||
|
RAISE EXCEPTION 'DEPLOYMENT FAILED: Security tests did not pass. Status: %',
|
||||||
|
v_test_results->>'overall_status'
|
||||||
|
USING HINT = 'Do not use in production until all security tests pass';
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
RAISE NOTICE 'Security validation passed - extension ready for production use';
|
||||||
|
END $;
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🚨 **Incident Response**
|
||||||
|
|
||||||
|
### **Security Incident Classifications**
|
||||||
|
|
||||||
|
#### **P0 - Critical Security Breach**
|
||||||
|
- **Definition**: Active exploitation, data compromise, or system compromise
|
||||||
|
- **Response Time**: Immediate (< 1 hour)
|
||||||
|
- **Actions**:
|
||||||
|
- Isolate affected systems
|
||||||
|
- Preserve forensic evidence
|
||||||
|
- Notify security team and management
|
||||||
|
- Begin incident response procedures
|
||||||
|
|
||||||
|
#### **P1 - High Security Risk**
|
||||||
|
- **Definition**: Vulnerability discovered, attempted exploitation, or suspicious activity
|
||||||
|
- **Response Time**: Within 4 hours
|
||||||
|
- **Actions**:
|
||||||
|
- Assess impact and risk
|
||||||
|
- Implement temporary mitigations
|
||||||
|
- Begin patch development
|
||||||
|
- Monitor for exploitation attempts
|
||||||
|
|
||||||
|
#### **P2 - Medium Security Issue**
|
||||||
|
- **Definition**: Lower-risk vulnerability or security concern
|
||||||
|
- **Response Time**: Within 24 hours
|
||||||
|
- **Actions**:
|
||||||
|
- Document and prioritize
|
||||||
|
- Plan remediation
|
||||||
|
- Schedule fix in next release cycle
|
||||||
|
|
||||||
|
### **Forensic Capabilities**
|
||||||
|
|
||||||
|
#### **Audit Trail Analysis**
|
||||||
|
```sql
|
||||||
|
-- Incident investigation queries
|
||||||
|
-- Identify suspicious activity patterns
|
||||||
|
SELECT
|
||||||
|
user_name,
|
||||||
|
operation_type,
|
||||||
|
count(*) as frequency,
|
||||||
|
min(created_at) as first_occurrence,
|
||||||
|
max(created_at) as last_occurrence,
|
||||||
|
array_agg(DISTINCT error_message) FILTER (WHERE success = false) as errors
|
||||||
|
FROM c77_secure_db_operation_audit
|
||||||
|
WHERE created_at BETWEEN 'incident_start_time' AND 'incident_end_time'
|
||||||
|
GROUP BY user_name, operation_type
|
||||||
|
ORDER BY frequency DESC;
|
||||||
|
|
||||||
|
-- Hash verification for tampered data
|
||||||
|
SELECT c77_secure_db_verify_content_hashes('affected_schema', 'affected_table');
|
||||||
|
|
||||||
|
-- Token analysis during incident window
|
||||||
|
SELECT
|
||||||
|
session_id,
|
||||||
|
operation_type,
|
||||||
|
count(*) as token_count,
|
||||||
|
min(created_at) as first_token,
|
||||||
|
max(expires_at) as last_expiry
|
||||||
|
FROM c77_secure_db_auth_tokens
|
||||||
|
WHERE created_at BETWEEN 'incident_start_time' AND 'incident_end_time'
|
||||||
|
GROUP BY session_id, operation_type;
|
||||||
|
```
|
||||||
|
|
||||||
|
#### **Evidence Preservation**
|
||||||
|
- **Audit Logs**: Immutable record of all operations
|
||||||
|
- **Hash Values**: Cryptographic proof of data state
|
||||||
|
- **Token Records**: Authorization trail for forensic analysis
|
||||||
|
- **System Logs**: PostgreSQL logs with detailed operation information
|
||||||
|
|
||||||
|
## 📞 **Security Contacts**
|
||||||
|
|
||||||
|
### **Security Team**
|
||||||
|
- **Primary Contact**: security@yourcompany.com
|
||||||
|
- **Response Time**: 24 hours maximum
|
||||||
|
- **Escalation**: Available for critical issues
|
||||||
|
|
||||||
|
### **Development Team**
|
||||||
|
- **Technical Contact**: developers@yourcompany.com
|
||||||
|
- **Availability**: Business hours
|
||||||
|
- **Expertise**: Extension architecture and implementation
|
||||||
|
|
||||||
|
### **Emergency Contacts**
|
||||||
|
- **After Hours**: emergency@yourcompany.com
|
||||||
|
- **Critical Issues**: Available 24/7
|
||||||
|
- **Response**: Within 1 hour for P0 incidents
|
||||||
|
|
||||||
|
## 📚 **Additional Resources**
|
||||||
|
|
||||||
|
### **Security Documentation**
|
||||||
|
- **[BEST_PRACTICES.md](BEST_PRACTICES.md)**: Comprehensive security best practices
|
||||||
|
- **[USAGE.md](USAGE.md)**: Security-focused usage examples
|
||||||
|
- **[EXAMPLES.md](EXAMPLES.md)**: Secure implementation patterns
|
||||||
|
|
||||||
|
### **External Resources**
|
||||||
|
- **PostgreSQL Security**: https://www.postgresql.org/docs/current/security.html
|
||||||
|
- **OWASP Database Security**: https://owasp.org/www-project-database-security/
|
||||||
|
- **NIST Cybersecurity Framework**: https://www.nist.gov/cyberframework
|
||||||
|
|
||||||
|
### **Security Tools**
|
||||||
|
- **pgaudit**: PostgreSQL auditing extension
|
||||||
|
- **pg_stat_statements**: Query performance and security monitoring
|
||||||
|
- **log_statement**: PostgreSQL statement logging for security analysis
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📄 **Security Policy Updates**
|
||||||
|
|
||||||
|
This security policy is reviewed quarterly and updated as needed to reflect:
|
||||||
|
- New threats and vulnerabilities
|
||||||
|
- Changes in security best practices
|
||||||
|
- Updates to compliance requirements
|
||||||
|
- Lessons learned from security incidents
|
||||||
|
|
||||||
|
**Last Updated**: January 2025
|
||||||
|
**Next Review**: April 2025
|
||||||
|
**Version**: 2.0
|
File diff suppressed because it is too large
Load Diff
1859
c77_secure_db--1.0.sql
Normal file
1859
c77_secure_db--1.0.sql
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,6 @@
|
|||||||
# c77_secure_db extension control file
|
# c77_secure_db extension control file
|
||||||
comment = 'Secure database operations with tamper detection and transaction control'
|
comment = 'Secure database operations with tamper detection and transaction control'
|
||||||
default_version = '1.0.0'
|
default_version = '1.0'
|
||||||
relocatable = false
|
relocatable = false
|
||||||
requires = 'pgcrypto'
|
requires = 'pgcrypto'
|
||||||
|
suggests = 'c77_rbac'
|
Loading…
x
Reference in New Issue
Block a user