[SEC+UX] Hardening sicurezza + miglioramenti UX pre-audit
SICUREZZA: - index.php: rimosso CORS wildcard in debug mode (solo origini autorizzate) - AuthController: getClientIP() con X-Forwarded-For sicuro (proxy-aware) - AuthController: refresh token con SELECT FOR UPDATE in transazione atomica - AIService: anonimizzazione dati org nei prompt Anthropic API (no nome/fatturato) UX AUDIT-READY: - dashboard.html: gauge rinominato 'Avanzamento implementazione misure Art.21' - incidents.html: decision tree Art.23 con 5 criteri per 'Is Significant?' - policies.html: banner warning obbligatorio su bozze generate da AI - risks.html: tooltip dettagliati scala Likelihood/Impact (ISO 27005) - assessment.html: progress bar % completamento risposta domande DB: - migration 006: indici performance + audit_log immutabile (trigger) + soft delete Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
0e78ec24c1
commit
782389849f
@@ -0,0 +1,85 @@
|
||||
-- ============================================================
|
||||
-- NIS2 Agile - Migration 006: Security & Performance Improvements
|
||||
-- Data: 2026-02-20
|
||||
-- Eseguire come: mysql -u root -p nis2_agile_db < 006_security_improvements.sql
|
||||
-- ============================================================
|
||||
|
||||
-- ── 1. Indici performance su incidents ────────────────────────────────────
|
||||
-- Per query filtrate per org + scadenze NIS2
|
||||
ALTER TABLE incidents
|
||||
ADD INDEX IF NOT EXISTS idx_inc_org_status (organization_id, status),
|
||||
ADD INDEX IF NOT EXISTS idx_inc_org_significant (organization_id, is_significant),
|
||||
ADD INDEX IF NOT EXISTS idx_inc_early_warning_due (organization_id, early_warning_due),
|
||||
ADD INDEX IF NOT EXISTS idx_inc_notification_due (organization_id, notification_due),
|
||||
ADD INDEX IF NOT EXISTS idx_inc_final_report_due (organization_id, final_report_due);
|
||||
|
||||
-- ── 2. Indici performance su risks ────────────────────────────────────────
|
||||
ALTER TABLE risks
|
||||
ADD INDEX IF NOT EXISTS idx_risks_org_status (organization_id, status),
|
||||
ADD INDEX IF NOT EXISTS idx_risks_score (organization_id, inherent_risk_score DESC);
|
||||
|
||||
-- ── 3. Indici performance su audit_logs (immutabilità) ────────────────────
|
||||
-- L'audit log deve essere append-only e ricercabile rapidamente
|
||||
ALTER TABLE audit_logs
|
||||
ADD INDEX IF NOT EXISTS idx_audit_org_created (organization_id, created_at DESC),
|
||||
ADD INDEX IF NOT EXISTS idx_audit_entity (entity_type, entity_id);
|
||||
|
||||
-- ── 4. Trigger per rendere audit_log immutabile ───────────────────────────
|
||||
-- Blocca UPDATE e DELETE sull'audit log (solo INSERT consentito)
|
||||
DROP TRIGGER IF EXISTS prevent_audit_log_update;
|
||||
CREATE TRIGGER prevent_audit_log_update
|
||||
BEFORE UPDATE ON audit_logs
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
SIGNAL SQLSTATE '45000'
|
||||
SET MESSAGE_TEXT = 'audit_logs is append-only: UPDATE not permitted';
|
||||
END;
|
||||
|
||||
DROP TRIGGER IF EXISTS prevent_audit_log_delete;
|
||||
CREATE TRIGGER prevent_audit_log_delete
|
||||
BEFORE DELETE ON audit_logs
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
SIGNAL SQLSTATE '45000'
|
||||
SET MESSAGE_TEXT = 'audit_logs is append-only: DELETE not permitted';
|
||||
END;
|
||||
|
||||
-- ── 5. Colonna deleted_at per soft delete su tabelle critiche ─────────────
|
||||
-- Permette di "eliminare" record senza perdere traccia storica
|
||||
|
||||
-- Risks: soft delete
|
||||
ALTER TABLE risks
|
||||
ADD COLUMN IF NOT EXISTS deleted_at TIMESTAMP NULL DEFAULT NULL AFTER updated_at;
|
||||
|
||||
ALTER TABLE risks
|
||||
ADD INDEX IF NOT EXISTS idx_risks_deleted (organization_id, deleted_at);
|
||||
|
||||
-- Policies: soft delete
|
||||
ALTER TABLE policies
|
||||
ADD COLUMN IF NOT EXISTS deleted_at TIMESTAMP NULL DEFAULT NULL AFTER updated_at;
|
||||
|
||||
ALTER TABLE policies
|
||||
ADD INDEX IF NOT EXISTS idx_policies_deleted (organization_id, deleted_at);
|
||||
|
||||
-- Suppliers: soft delete
|
||||
ALTER TABLE suppliers
|
||||
ADD COLUMN IF NOT EXISTS deleted_at TIMESTAMP NULL DEFAULT NULL AFTER updated_at;
|
||||
|
||||
-- ── 6. Indice su refresh_tokens per performance ───────────────────────────
|
||||
ALTER TABLE refresh_tokens
|
||||
ADD INDEX IF NOT EXISTS idx_refresh_user_expires (user_id, expires_at);
|
||||
|
||||
-- ── 7. Pulizia automatica refresh token scaduti ───────────────────────────
|
||||
-- Evento schedulato (richiede event scheduler abilitato)
|
||||
DROP EVENT IF EXISTS cleanup_expired_refresh_tokens;
|
||||
CREATE EVENT IF NOT EXISTS cleanup_expired_refresh_tokens
|
||||
ON SCHEDULE EVERY 6 HOUR
|
||||
STARTS CURRENT_TIMESTAMP
|
||||
DO
|
||||
DELETE FROM refresh_tokens WHERE expires_at < NOW() - INTERVAL 1 DAY;
|
||||
|
||||
-- ── 8. Verifica ───────────────────────────────────────────────────────────
|
||||
SELECT 'Migration 006 completed successfully' AS status;
|
||||
|
||||
-- Abilita event scheduler (da eseguire manualmente se necessario):
|
||||
-- SET GLOBAL event_scheduler = ON;
|
||||
Reference in New Issue
Block a user