[FEAT] Integrazione analisi docs/nis2 v1.7.0 — scoring asset, tassonomia incidenti, PIR, NIST CSF, fonti certe
Fase 1 - Asset Relevance Scoring NIS2 (GV.OC-04): metodologia 0-100 a 6 criteri, AssetScoringService + endpoint scoringGrid/score/relevantSystems + UI assets.html + registro stampabile. Fase 2 - Tassonomia incidenti Determina ACN 164179/2025: IS-1..4 + regime essenziale/importante (Allegati 3/4). Fase 3 - Post-Incident Review (5-Whys) + metriche TTD/TTC/TTR + timestamp di fase. Fase 4 - Mapping NIST CSF 2.0 (43 controlli) reference-only. Fonti certe: registry config/nis2_sources.php + grounding AI (vieta riferimenti inventati) + citazioni help.js + ingest PDF normativi nella KB RAG (scripts/ingest-nis2-sources.php). Migrazioni 020/021/022 (additive idempotenti). Fix VectorService IP Qdrant (drift .5->.3). Analisi concorrenza Evix (docs/EVIX_ANALISI_CONCORRENZA.html, gap-driven). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
a7a21faa82
commit
5c545ea3d0
25
CLAUDE.md
25
CLAUDE.md
@ -911,3 +911,28 @@ Standard cross-suite NAVIGAI per piattaforma multitenant esplicita di AgileHub.
|
|||||||
**Cosa impatta questo prodotto**: se in futuro questo prodotto chiamerà API multitenant-aware di AgileHub (es. /api/marketing, /api/rag, /api/ai/personas), deve passare JWT con tenant_id + tenant_slug claims oppure header `X-Tenant-Slug`. Vedi §6 contracts shared lib `@agile/tenant-auth` per pattern integrazione (Node + Python).
|
**Cosa impatta questo prodotto**: se in futuro questo prodotto chiamerà API multitenant-aware di AgileHub (es. /api/marketing, /api/rag, /api/ai/personas), deve passare JWT con tenant_id + tenant_slug claims oppure header `X-Tenant-Slug`. Vedi §6 contracts shared lib `@agile/tenant-auth` per pattern integrazione (Node + Python).
|
||||||
|
|
||||||
Status adoption: acknowledged 2026-05-17.
|
Status adoption: acknowledged 2026-05-17.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Integrazione analisi `docs/nis2/` — v1.7.0 (2026-05-29)
|
||||||
|
|
||||||
|
> Integrati i mockup + testi normativi PDF in `docs/nis2/`. Dettaglio e comandi deploy: `docs/nis2/INTEGRAZIONE_COMPLETATA.md`. **Migrazioni 020-022 e ingest KB DA ESEGUIRE su Hetzner** (host MySQL, non `docker exec nis2-db`).
|
||||||
|
|
||||||
|
### Nuove migrazioni (additive, idempotenti)
|
||||||
|
- `020_asset_relevance.sql` — assets += `relevance_score`, `relevance_criteria` JSON, `relevance_class`, `is_nis2_relevant`, `relevance_assessed_at/by`
|
||||||
|
- `021_incident_nis2_taxonomy.sql` — incidents += `nis2_incident_type` ENUM(IS-1..IS-4), `entity_obligation` ENUM(essential/important)
|
||||||
|
- `022_incident_metrics_pir.sql` — incidents += `triaged_at`/`contained_at`/`eradicated_at`/`recovered_at`; nuova tabella `incident_pir`
|
||||||
|
|
||||||
|
### Nuovi file
|
||||||
|
- `application/config/nis2_sources.php` — **registry canonico FONTI NORMATIVE CERTE** (single source of truth AI + help)
|
||||||
|
- `application/services/AssetScoringService.php` — scoring rilevanza NIS2 0-100 (6 criteri, GV.OC-04)
|
||||||
|
- `scripts/ingest-nis2-sources.php` — ingest PDF normativi nella KB Qdrant `nis2_kb` scope SYSTEM
|
||||||
|
|
||||||
|
### Nuovi endpoint
|
||||||
|
- Assets: `GET /api/assets/scoringGrid`, `POST /api/assets/{id}/score`, `GET /api/assets/relevantSystems`
|
||||||
|
- Incidents: `GET /api/incidents/{id}/metrics`, `GET /api/incidents/{id}/pir`, `POST /api/incidents/{id}/pir`
|
||||||
|
- Audit: `GET /api/audit/nistCsfMapping`, `GET /api/audit/relevantSystemsRegister` (registro GV.OC-04 stampabile)
|
||||||
|
|
||||||
|
### REGOLA: Fonti certe (AI + help)
|
||||||
|
Ogni affermazione normativa di AI e help **deve citare** una fonte di `application/config/nis2_sources.php`.
|
||||||
|
`AIService::authoritativeSourcesBlock()` è iniettato nei system prompt e **vieta riferimenti inventati**.
|
||||||
|
|||||||
75
application/config/nis2_sources.php
Normal file
75
application/config/nis2_sources.php
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* NIS2 Agile - Registro Fonti Normative Certe
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
* SINGLE SOURCE OF TRUTH per le fonti normative autoritative citabili.
|
||||||
|
*
|
||||||
|
* Principio (richiesta utente 2026-05-29): ogni scelta/risposta della
|
||||||
|
* piattaforma — sia nell'AI sia nell'help — DEVE riferirsi a fonti certe e
|
||||||
|
* citarle esplicitamente. Vietato inventare riferimenti normativi.
|
||||||
|
*
|
||||||
|
* I PDF originali risiedono in docs/nis2/ (repo) e sono ingeriti nella
|
||||||
|
* Knowledge Base (collection Qdrant nis2_kb, scope SYSTEM) per il grounding RAG.
|
||||||
|
*
|
||||||
|
* Usato da:
|
||||||
|
* - AIService (iniezione nei system prompt: "cita queste fonti")
|
||||||
|
* - public/js/help.js (riferimenti normativi nell'help contestuale, via /api/... o statico)
|
||||||
|
* - scripts/ingest-nis2-sources.php (ingest PDF -> KB)
|
||||||
|
*/
|
||||||
|
|
||||||
|
return [
|
||||||
|
'nis2_directive' => [
|
||||||
|
'key' => 'nis2_directive',
|
||||||
|
'short' => 'Direttiva NIS2',
|
||||||
|
'citation' => 'Direttiva (UE) 2022/2555 (NIS2)',
|
||||||
|
'full' => 'Direttiva (UE) 2022/2555 del Parlamento europeo e del Consiglio del 14 dicembre 2022 relativa a misure per un livello comune elevato di cibersicurezza nell\'Unione (NIS2)',
|
||||||
|
'file' => 'docs/nis2/Dir2022_2555_UE_NIS2_ITA.pdf',
|
||||||
|
'authority' => 'Parlamento europeo e Consiglio UE',
|
||||||
|
'url' => 'https://eur-lex.europa.eu/legal-content/IT/TXT/?uri=CELEX:32022L2555',
|
||||||
|
],
|
||||||
|
'cer_directive' => [
|
||||||
|
'key' => 'cer_directive',
|
||||||
|
'short' => 'Direttiva CER',
|
||||||
|
'citation' => 'Direttiva (UE) 2022/2557 (CER)',
|
||||||
|
'full' => 'Direttiva (UE) 2022/2557 del Parlamento europeo e del Consiglio del 14 dicembre 2022 relativa alla resilienza dei soggetti critici (Critical Entities Resilience)',
|
||||||
|
'file' => 'docs/nis2/Dir2022_2557_UE_ITA.pdf',
|
||||||
|
'authority' => 'Parlamento europeo e Consiglio UE',
|
||||||
|
'url' => 'https://eur-lex.europa.eu/legal-content/IT/TXT/?uri=CELEX:32022L2557',
|
||||||
|
],
|
||||||
|
'dlgs_138_2024' => [
|
||||||
|
'key' => 'dlgs_138_2024',
|
||||||
|
'short' => 'D.Lgs. 138/2024',
|
||||||
|
'citation' => 'D.Lgs. 4 settembre 2024, n. 138',
|
||||||
|
'full' => 'Decreto legislativo 4 settembre 2024, n. 138 - Recepimento della direttiva (UE) 2022/2555 (decreto NIS)',
|
||||||
|
'file' => null,
|
||||||
|
'authority' => 'Repubblica Italiana',
|
||||||
|
'url' => 'https://www.gazzettaufficiale.it/eli/id/2024/09/01/24G00155/sg',
|
||||||
|
],
|
||||||
|
'determina_164179_2025' => [
|
||||||
|
'key' => 'determina_164179_2025',
|
||||||
|
'short' => 'Determina ACN 164179/2025',
|
||||||
|
'citation' => 'Determinazione ACN n. 164179 del 14 aprile 2025',
|
||||||
|
'full' => 'Determinazione del Direttore generale dell\'Agenzia per la Cybersicurezza Nazionale n. 164179 del 14 aprile 2025, in attuazione del D.Lgs. 138/2024, che stabilisce modalita e specifiche di base per gli obblighi di cui agli articoli 23, 24, 25, 29 e 32 (incluse classificazione e notifica degli incidenti significativi, Allegati 3 e 4).',
|
||||||
|
'file' => 'docs/nis2/Determina164179_apr2025.pdf',
|
||||||
|
'authority' => 'Agenzia per la Cybersicurezza Nazionale (ACN)',
|
||||||
|
'url' => 'https://www.acn.gov.it/',
|
||||||
|
],
|
||||||
|
'determina_333017_2025' => [
|
||||||
|
'key' => 'determina_333017_2025',
|
||||||
|
'short' => 'Determina ACN 333017/2025',
|
||||||
|
'citation' => 'Determinazione ACN n. 333017 del settembre 2025',
|
||||||
|
'full' => 'Determinazione del Direttore generale ACN n. 333017 (settembre 2025): termini, modalita e procedimenti di utilizzo e accesso alla piattaforma digitale ACN, ulteriori informazioni che i soggetti devono fornire e designazione dei rappresentanti NIS sul territorio nazionale.',
|
||||||
|
'file' => 'docs/nis2/Determina333017_sett2025.pdf',
|
||||||
|
'authority' => 'Agenzia per la Cybersicurezza Nazionale (ACN)',
|
||||||
|
'url' => 'https://www.acn.gov.it/',
|
||||||
|
],
|
||||||
|
'ambiti_nis2' => [
|
||||||
|
'key' => 'ambiti_nis2',
|
||||||
|
'short' => 'Ambiti NIS2 (Allegati I/II)',
|
||||||
|
'citation' => 'Allegati I e II - Settori NIS2',
|
||||||
|
'full' => 'Ambiti di applicazione NIS2 - Allegato I (Settori ad alta criticita: energia, trasporti, bancario, infrastrutture dei mercati finanziari, sanitario, acqua potabile, acque reflue, infrastrutture digitali, gestione servizi TIC B2B, PA, spazio) e Allegato II (Altri settori critici).',
|
||||||
|
'file' => 'docs/nis2/AmbitiNIS2_ITA.pdf',
|
||||||
|
'authority' => 'ACN / Allegati al D.Lgs. 138/2024',
|
||||||
|
'url' => 'https://www.acn.gov.it/',
|
||||||
|
],
|
||||||
|
];
|
||||||
@ -6,6 +6,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
require_once __DIR__ . '/BaseController.php';
|
require_once __DIR__ . '/BaseController.php';
|
||||||
|
require_once __DIR__ . '/../services/AssetScoringService.php';
|
||||||
|
|
||||||
class AssetController extends BaseController
|
class AssetController extends BaseController
|
||||||
{
|
{
|
||||||
@ -29,6 +30,10 @@ class AssetController extends BaseController
|
|||||||
$where .= ' AND status = ?';
|
$where .= ' AND status = ?';
|
||||||
$params[] = $this->getParam('status');
|
$params[] = $this->getParam('status');
|
||||||
}
|
}
|
||||||
|
if ($this->hasParam('nis2_relevant')) {
|
||||||
|
$where .= ' AND is_nis2_relevant = ?';
|
||||||
|
$params[] = $this->getParam('nis2_relevant') ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
$total = Database::count('assets', $where, $params);
|
$total = Database::count('assets', $where, $params);
|
||||||
$assets = Database::fetchAll(
|
$assets = Database::fetchAll(
|
||||||
@ -157,4 +162,116 @@ class AssetController extends BaseController
|
|||||||
|
|
||||||
$this->jsonSuccess(['nodes' => $nodes, 'edges' => $edges]);
|
$this->jsonSuccess(['nodes' => $nodes, 'edges' => $edges]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GET /api/assets/scoringGrid
|
||||||
|
* Ritorna la griglia ufficiale di valutazione rilevanza NIS2 (GV.OC-04)
|
||||||
|
* per costruire la UI di scoring lato client.
|
||||||
|
*/
|
||||||
|
public function scoringGrid(): void
|
||||||
|
{
|
||||||
|
$this->requireOrgAccess();
|
||||||
|
$this->jsonSuccess([
|
||||||
|
'grid' => AssetScoringService::GRID,
|
||||||
|
'threshold' => AssetScoringService::RELEVANCE_THRESHOLD,
|
||||||
|
'classes' => [
|
||||||
|
['key' => 'critico', 'min' => 80, 'max' => 100, 'label' => 'Critico - Priorita Massima'],
|
||||||
|
['key' => 'alto', 'min' => 60, 'max' => 79, 'label' => 'Alto - Priorita Alta'],
|
||||||
|
['key' => 'medio', 'min' => 40, 'max' => 59, 'label' => 'Medio - Rilevante'],
|
||||||
|
['key' => 'basso', 'min' => 20, 'max' => 39, 'label' => 'Basso - Monitoraggio'],
|
||||||
|
['key' => 'trascurabile', 'min' => 0, 'max' => 19, 'label' => 'Trascurabile'],
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* POST /api/assets/{id}/score
|
||||||
|
* Calcola e salva la rilevanza NIS2 dell'asset a partire dalle selezioni
|
||||||
|
* sui 6 criteri. Body: { criteria: { c1_operational_criticality: 'critical', ... } }
|
||||||
|
*/
|
||||||
|
public function score(int $id): void
|
||||||
|
{
|
||||||
|
$this->requireOrgRole(['org_admin', 'compliance_manager']);
|
||||||
|
|
||||||
|
$asset = Database::fetchOne(
|
||||||
|
'SELECT id FROM assets WHERE id = ? AND organization_id = ?',
|
||||||
|
[$id, $this->getCurrentOrgId()]
|
||||||
|
);
|
||||||
|
if (!$asset) {
|
||||||
|
$this->jsonError('Asset non trovato', 404, 'ASSET_NOT_FOUND');
|
||||||
|
}
|
||||||
|
|
||||||
|
$criteria = $this->getParam('criteria');
|
||||||
|
if (!is_array($criteria)) {
|
||||||
|
$this->jsonError('Campo "criteria" mancante o non valido', 422, 'INVALID_CRITERIA');
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$result = AssetScoringService::calculate($criteria);
|
||||||
|
} catch (InvalidArgumentException $e) {
|
||||||
|
$this->jsonError($e->getMessage(), 422, 'INVALID_CRITERIA');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Database::update('assets', [
|
||||||
|
'relevance_score' => $result['score'],
|
||||||
|
'relevance_criteria' => json_encode($result['breakdown'], JSON_UNESCAPED_UNICODE),
|
||||||
|
'relevance_class' => $result['class'],
|
||||||
|
'is_nis2_relevant' => $result['is_relevant'] ? 1 : 0,
|
||||||
|
'criticality' => $result['criticality'],
|
||||||
|
'relevance_assessed_at' => date('Y-m-d H:i:s'),
|
||||||
|
'relevance_assessed_by' => $this->getCurrentUserId(),
|
||||||
|
], 'id = ? AND organization_id = ?', [$id, $this->getCurrentOrgId()]);
|
||||||
|
|
||||||
|
$this->logAudit('asset_scored', 'asset', $id, [
|
||||||
|
'score' => $result['score'],
|
||||||
|
'class' => $result['class'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->jsonSuccess([
|
||||||
|
'score' => $result['score'],
|
||||||
|
'class' => $result['class'],
|
||||||
|
'is_nis2_relevant' => $result['is_relevant'],
|
||||||
|
'breakdown' => $result['breakdown'],
|
||||||
|
'required_measures'=> AssetScoringService::requiredMeasures($result['class']),
|
||||||
|
], 'Rilevanza NIS2 calcolata');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GET /api/assets/relevantSystems
|
||||||
|
* Elenco dei sistemi classificati rilevanti NIS2 (score >= 40), ordinati
|
||||||
|
* per punteggio. Alimenta il registro formale "Sistemi Rilevanti" (GV.OC-04).
|
||||||
|
*/
|
||||||
|
public function relevantSystems(): void
|
||||||
|
{
|
||||||
|
$this->requireOrgAccess();
|
||||||
|
|
||||||
|
$rows = Database::fetchAll(
|
||||||
|
"SELECT a.id, a.name, a.asset_type, a.category, a.ip_address, a.location,
|
||||||
|
a.relevance_score, a.relevance_class, a.relevance_criteria,
|
||||||
|
a.relevance_assessed_at, u.full_name AS owner_name
|
||||||
|
FROM assets a
|
||||||
|
LEFT JOIN users u ON u.id = a.owner_user_id
|
||||||
|
WHERE a.organization_id = ? AND a.is_nis2_relevant = 1
|
||||||
|
ORDER BY a.relevance_score DESC, a.name",
|
||||||
|
[$this->getCurrentOrgId()]
|
||||||
|
);
|
||||||
|
|
||||||
|
$stats = ['critico' => 0, 'alto' => 0, 'medio' => 0];
|
||||||
|
foreach ($rows as &$r) {
|
||||||
|
$r['relevance_criteria'] = json_decode($r['relevance_criteria'] ?? 'null', true);
|
||||||
|
$r['required_measures'] = AssetScoringService::requiredMeasures($r['relevance_class'] ?? '');
|
||||||
|
if (isset($stats[$r['relevance_class']])) {
|
||||||
|
$stats[$r['relevance_class']]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unset($r);
|
||||||
|
|
||||||
|
$this->jsonSuccess([
|
||||||
|
'systems' => $rows,
|
||||||
|
'count' => count($rows),
|
||||||
|
'by_class' => $stats,
|
||||||
|
'threshold' => AssetScoringService::RELEVANCE_THRESHOLD,
|
||||||
|
]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -195,6 +195,83 @@ class AuditController extends BaseController
|
|||||||
$this->jsonSuccess($mapping);
|
$this->jsonSuccess($mapping);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GET /api/audit/nistCsfMapping
|
||||||
|
* Layer di mapping NIST CSF 2.0 (43 controlli) -> NIS2 Art.21 / D.Lgs.138/2024 -> modulo piattaforma.
|
||||||
|
* Reference-only (nessuna persistenza): arricchisce l'assessment Art.21 con i codici controllo
|
||||||
|
* NIST CSF 2.0 usati come standard de-facto. Fonte mapping: NIST CSF 2.0 + Direttiva (UE) 2022/2555.
|
||||||
|
*/
|
||||||
|
public function getNistCsfMapping(): void
|
||||||
|
{
|
||||||
|
$this->requireOrgAccess();
|
||||||
|
|
||||||
|
// [code, function, nis2, module]
|
||||||
|
$rows = [
|
||||||
|
// GOVERN
|
||||||
|
['GV.OC-04', 'Govern', '21.1', 'Asset - Sistemi rilevanti (GV.OC-04)'],
|
||||||
|
['GV.RM-03', 'Govern', '21.2.a', 'Risk Management'],
|
||||||
|
['GV.RR-02', 'Govern', '20', 'Organizzazione - Ruoli e responsabilita'],
|
||||||
|
['GV.RR-04', 'Govern', '20', 'Organizzazione - Risorse cybersecurity'],
|
||||||
|
['GV.PO-01', 'Govern', '21.2.a', 'Policy - Politica di sicurezza'],
|
||||||
|
['GV.PO-02', 'Govern', '21.2.a', 'Policy - Revisione politiche'],
|
||||||
|
['GV.SC-01', 'Govern', '21.2.d', 'Supply Chain - Strategia'],
|
||||||
|
['GV.SC-02', 'Govern', '21.2.d', 'Supply Chain - Ruoli fornitori'],
|
||||||
|
['GV.SC-04', 'Govern', '21.2.d', 'Supply Chain - Valutazione fornitori'],
|
||||||
|
['GV.SC-05', 'Govern', '21.2.d', 'Supply Chain - Requisiti contrattuali'],
|
||||||
|
['GV.SC-07', 'Govern', '21.2.d', 'Supply Chain - Monitoraggio rischio fornitori'],
|
||||||
|
// IDENTIFY
|
||||||
|
['ID.AM-01', 'Identify', '21.2.i', 'Asset - Inventario hardware'],
|
||||||
|
['ID.AM-02', 'Identify', '21.2.i', 'Asset - Inventario software'],
|
||||||
|
['ID.AM-03', 'Identify', '21.2.i', 'Asset - Diagrammi flussi/rete (essenziali)'],
|
||||||
|
['ID.AM-04', 'Identify', '21.2.i', 'Asset - Catalogo servizi'],
|
||||||
|
['ID.RA-01', 'Identify', '21.2.a', 'Risk Management - Vulnerabilita'],
|
||||||
|
['ID.RA-05', 'Identify', '21.2.a', 'Risk Management - Valutazione rischio'],
|
||||||
|
['ID.RA-06', 'Identify', '21.2.a', 'Risk Management - Trattamento rischio'],
|
||||||
|
['ID.RA-08', 'Identify', '21.2.e', 'Risk Management - Gestione vulnerabilita/disclosure'],
|
||||||
|
['ID.IM-01', 'Identify', '21.2.f', 'Audit - Miglioramento da valutazioni'],
|
||||||
|
['ID.IM-04', 'Identify', '21.2.c', 'Incidenti - Piani BC/DR e test'],
|
||||||
|
// PROTECT
|
||||||
|
['PR.AA-01', 'Protect', '21.2.i', 'Asset/Access - Gestione identita'],
|
||||||
|
['PR.AA-03', 'Protect', '21.2.i', 'Access - Autenticazione'],
|
||||||
|
['PR.AA-05', 'Protect', '21.2.i', 'Access - Privilegi e accessi'],
|
||||||
|
['PR.AA-06', 'Protect', '21.2.i', 'Access - Accesso fisico'],
|
||||||
|
['PR.AT-01', 'Protect', '21.2.g', 'Training - Awareness'],
|
||||||
|
['PR.AT-02', 'Protect', '21.2.g', 'Training - Ruoli privilegiati'],
|
||||||
|
['PR.DS-01', 'Protect', '21.2.h', 'Policy - Protezione dati a riposo'],
|
||||||
|
['PR.DS-02', 'Protect', '21.2.h', 'Policy - Protezione dati in transito'],
|
||||||
|
['PR.DS-11', 'Protect', '21.2.c', 'Incidenti - Backup'],
|
||||||
|
['PR.PS-01', 'Protect', '21.2.e', 'Policy - Configurazione sicura'],
|
||||||
|
['PR.PS-02', 'Protect', '21.2.e', 'Asset - Gestione software'],
|
||||||
|
['PR.PS-03', 'Protect', '21.2.e', 'Asset - Gestione hardware'],
|
||||||
|
['PR.PS-04', 'Protect', '21.2.b', 'Audit - Log generation'],
|
||||||
|
['PR.PS-06', 'Protect', '21.2.e', 'Policy - Secure development lifecycle'],
|
||||||
|
['PR.IR-01', 'Protect', '21.2.i', 'Asset - Protezione reti'],
|
||||||
|
['PR.IR-03', 'Protect', '21.2.c', 'Incidenti - Resilienza/ridondanza'],
|
||||||
|
// DETECT
|
||||||
|
['DE.CM-01', 'Detect', '21.2.b', 'Incidenti - Monitoraggio reti'],
|
||||||
|
['DE.CM-09', 'Detect', '21.2.b', 'Incidenti - Monitoraggio asset/sistemi'],
|
||||||
|
// RESPOND / RECOVER
|
||||||
|
['RS.MA-01', 'Respond', '21.2.b / 23', 'Incidenti - Gestione incidenti'],
|
||||||
|
['RS.CO-02', 'Respond', '23', 'Incidenti - Notifica CSIRT'],
|
||||||
|
['RC.RP-01', 'Recover', '21.2.c', 'Incidenti - Piano di ripristino'],
|
||||||
|
['RC.CO-03', 'Recover', '21.2.c', 'Incidenti - Post-Incident Review'],
|
||||||
|
];
|
||||||
|
|
||||||
|
$mapping = array_map(fn($r) => [
|
||||||
|
'csf_code' => $r[0],
|
||||||
|
'function' => $r[1],
|
||||||
|
'nis2_art' => $r[2],
|
||||||
|
'module' => $r[3],
|
||||||
|
], $rows);
|
||||||
|
|
||||||
|
$this->jsonSuccess([
|
||||||
|
'mapping' => $mapping,
|
||||||
|
'count' => count($mapping),
|
||||||
|
'functions' => ['Govern', 'Identify', 'Protect', 'Detect', 'Respond', 'Recover'],
|
||||||
|
'source' => 'NIST Cybersecurity Framework 2.0 + Direttiva (UE) 2022/2555 (NIS2) Art.20-21-23 / D.Lgs. 138/2024',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GET /api/audit/executive-report
|
* GET /api/audit/executive-report
|
||||||
* Genera report esecutivo HTML (stampabile come PDF)
|
* Genera report esecutivo HTML (stampabile come PDF)
|
||||||
@ -211,6 +288,22 @@ class AuditController extends BaseController
|
|||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GET /api/audit/relevantSystemsRegister
|
||||||
|
* Registro formale "Sistemi Rilevanti NIS2" (GV.OC-04), HTML stampabile.
|
||||||
|
*/
|
||||||
|
public function relevantSystemsRegister(): void
|
||||||
|
{
|
||||||
|
$this->requireOrgRole(['org_admin', 'compliance_manager', 'board_member', 'auditor']);
|
||||||
|
|
||||||
|
$reportService = new ReportService();
|
||||||
|
$html = $reportService->generateRelevantSystemsRegister($this->getCurrentOrgId());
|
||||||
|
|
||||||
|
header('Content-Type: text/html; charset=utf-8');
|
||||||
|
echo $html;
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GET /api/audit/export/{type}
|
* GET /api/audit/export/{type}
|
||||||
* Esporta dati in CSV
|
* Esporta dati in CSV
|
||||||
|
|||||||
@ -59,6 +59,17 @@ class IncidentController extends BaseController
|
|||||||
$detectedAt = $this->getParam('detected_at');
|
$detectedAt = $this->getParam('detected_at');
|
||||||
$isSignificant = (bool) $this->getParam('is_significant', false);
|
$isSignificant = (bool) $this->getParam('is_significant', false);
|
||||||
|
|
||||||
|
// Regime obblighi NIS2 (Determina ACN 164179/2025): Allegato 3 essenziali / Allegato 4 importanti.
|
||||||
|
$org = Database::fetchOne('SELECT entity_type FROM organizations WHERE id = ?', [$this->getCurrentOrgId()]);
|
||||||
|
$entityObligation = ($org && ($org['entity_type'] ?? '') === 'essential') ? 'essential' : 'important';
|
||||||
|
|
||||||
|
// IS-4 (incidenti ricorrenti) non si applica ai soggetti importanti.
|
||||||
|
$isType = $this->getParam('nis2_incident_type');
|
||||||
|
$validIs = $entityObligation === 'essential' ? ['IS-1','IS-2','IS-3','IS-4'] : ['IS-1','IS-2','IS-3'];
|
||||||
|
if ($isType !== null && !in_array($isType, $validIs, true)) {
|
||||||
|
$isType = null;
|
||||||
|
}
|
||||||
|
|
||||||
$data = [
|
$data = [
|
||||||
'organization_id' => $this->getCurrentOrgId(),
|
'organization_id' => $this->getCurrentOrgId(),
|
||||||
'incident_code' => $this->generateCode('INC'),
|
'incident_code' => $this->generateCode('INC'),
|
||||||
@ -67,6 +78,8 @@ class IncidentController extends BaseController
|
|||||||
'classification' => $this->getParam('classification'),
|
'classification' => $this->getParam('classification'),
|
||||||
'severity' => $this->getParam('severity'),
|
'severity' => $this->getParam('severity'),
|
||||||
'is_significant' => $isSignificant ? 1 : 0,
|
'is_significant' => $isSignificant ? 1 : 0,
|
||||||
|
'nis2_incident_type' => $isType,
|
||||||
|
'entity_obligation' => $entityObligation,
|
||||||
'detected_at' => $detectedAt,
|
'detected_at' => $detectedAt,
|
||||||
'affected_services' => $this->getParam('affected_services'),
|
'affected_services' => $this->getParam('affected_services'),
|
||||||
'affected_users_count' => $this->getParam('affected_users_count'),
|
'affected_users_count' => $this->getParam('affected_users_count'),
|
||||||
@ -173,9 +186,9 @@ class IncidentController extends BaseController
|
|||||||
$updates = [];
|
$updates = [];
|
||||||
$allowedFields = [
|
$allowedFields = [
|
||||||
'title', 'description', 'classification', 'severity', 'is_significant',
|
'title', 'description', 'classification', 'severity', 'is_significant',
|
||||||
'status', 'affected_services', 'affected_users_count', 'cross_border_impact',
|
'nis2_incident_type', 'status', 'affected_services', 'affected_users_count',
|
||||||
'malicious_action', 'root_cause', 'remediation_actions', 'lessons_learned',
|
'cross_border_impact', 'malicious_action', 'root_cause', 'remediation_actions',
|
||||||
'assigned_to',
|
'lessons_learned', 'assigned_to',
|
||||||
];
|
];
|
||||||
|
|
||||||
foreach ($allowedFields as $field) {
|
foreach ($allowedFields as $field) {
|
||||||
@ -184,9 +197,24 @@ class IncidentController extends BaseController
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Se chiuso, registra data
|
// Timbra automaticamente i timestamp di fase al primo ingresso nello stato
|
||||||
if (isset($updates['status']) && $updates['status'] === 'closed') {
|
// (per il calcolo metriche TTD/TTC/TTR). Non sovrascrive valori gia' presenti.
|
||||||
$updates['closed_at'] = date('Y-m-d H:i:s');
|
if (isset($updates['status'])) {
|
||||||
|
$now = date('Y-m-d H:i:s');
|
||||||
|
$stamp = [
|
||||||
|
'analyzing' => 'triaged_at',
|
||||||
|
'containing' => 'contained_at',
|
||||||
|
'eradicating'=> 'eradicated_at',
|
||||||
|
'recovering' => 'recovered_at',
|
||||||
|
];
|
||||||
|
$col = $stamp[$updates['status']] ?? null;
|
||||||
|
if ($col !== null && empty($incident[$col])) {
|
||||||
|
$updates[$col] = $now;
|
||||||
|
}
|
||||||
|
if ($updates['status'] === 'closed') {
|
||||||
|
$updates['closed_at'] = $now;
|
||||||
|
if (empty($incident['recovered_at'])) $updates['recovered_at'] = $now;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Se diventa significativo, calcola scadenze
|
// Se diventa significativo, calcola scadenze
|
||||||
@ -392,4 +420,127 @@ class IncidentController extends BaseController
|
|||||||
$this->jsonError('Errore AI: ' . $e->getMessage(), 500, 'AI_ERROR');
|
$this->jsonError('Errore AI: ' . $e->getMessage(), 500, 'AI_ERROR');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GET /api/incidents/{id}/metrics
|
||||||
|
* Calcola TTD/TTC/TTR e downtime dai timestamp di fase (in minuti).
|
||||||
|
*/
|
||||||
|
public function metrics(int $id): void
|
||||||
|
{
|
||||||
|
$this->requireOrgAccess();
|
||||||
|
$inc = Database::fetchOne(
|
||||||
|
'SELECT detected_at, triaged_at, contained_at, eradicated_at, recovered_at, closed_at, affected_users_count
|
||||||
|
FROM incidents WHERE id = ? AND organization_id = ?',
|
||||||
|
[$id, $this->getCurrentOrgId()]
|
||||||
|
);
|
||||||
|
if (!$inc) {
|
||||||
|
$this->jsonError('Incidente non trovato', 404, 'INCIDENT_NOT_FOUND');
|
||||||
|
}
|
||||||
|
$this->jsonSuccess($this->computeMetrics($inc));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Differenza in minuti tra due datetime, null se mancante. */
|
||||||
|
private function minutesBetween(?string $from, ?string $to): ?int
|
||||||
|
{
|
||||||
|
if (empty($from) || empty($to)) return null;
|
||||||
|
$a = strtotime($from); $b = strtotime($to);
|
||||||
|
if ($a === false || $b === false) return null;
|
||||||
|
return (int) round(($b - $a) / 60);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function computeMetrics(array $inc): array
|
||||||
|
{
|
||||||
|
$det = $inc['detected_at'] ?? null;
|
||||||
|
return [
|
||||||
|
'ttd_minutes' => $this->minutesBetween($det, $inc['triaged_at'] ?? null),
|
||||||
|
'ttc_minutes' => $this->minutesBetween($det, $inc['contained_at'] ?? null),
|
||||||
|
'ttr_minutes' => $this->minutesBetween($det, $inc['recovered_at'] ?? null),
|
||||||
|
'downtime_minutes' => $this->minutesBetween($det, $inc['recovered_at'] ?? $inc['closed_at'] ?? null),
|
||||||
|
'affected_users' => isset($inc['affected_users_count']) ? (int) $inc['affected_users_count'] : null,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GET /api/incidents/{id}/pir
|
||||||
|
* Ritorna la Post-Incident Review (RC.CO-03) con le metriche calcolate.
|
||||||
|
*/
|
||||||
|
public function getPir(int $id): void
|
||||||
|
{
|
||||||
|
$this->requireOrgAccess();
|
||||||
|
$inc = Database::fetchOne(
|
||||||
|
'SELECT * FROM incidents WHERE id = ? AND organization_id = ?',
|
||||||
|
[$id, $this->getCurrentOrgId()]
|
||||||
|
);
|
||||||
|
if (!$inc) {
|
||||||
|
$this->jsonError('Incidente non trovato', 404, 'INCIDENT_NOT_FOUND');
|
||||||
|
}
|
||||||
|
$pir = Database::fetchOne('SELECT * FROM incident_pir WHERE incident_id = ?', [$id]);
|
||||||
|
if ($pir && !empty($pir['improvement_actions'])) {
|
||||||
|
$pir['improvement_actions'] = json_decode($pir['improvement_actions'], true);
|
||||||
|
}
|
||||||
|
$this->jsonSuccess([
|
||||||
|
'pir' => $pir,
|
||||||
|
'metrics' => $this->computeMetrics($inc),
|
||||||
|
'reference' => 'RC.CO-03 (NIST CSF) - PIR da completare entro 2 settimane dalla chiusura per incidenti critici',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* POST /api/incidents/{id}/pir
|
||||||
|
* Crea o aggiorna la Post-Incident Review (upsert).
|
||||||
|
*/
|
||||||
|
public function savePir(int $id): void
|
||||||
|
{
|
||||||
|
$this->requireOrgRole(['org_admin', 'compliance_manager']);
|
||||||
|
$inc = Database::fetchOne(
|
||||||
|
'SELECT * FROM incidents WHERE id = ? AND organization_id = ?',
|
||||||
|
[$id, $this->getCurrentOrgId()]
|
||||||
|
);
|
||||||
|
if (!$inc) {
|
||||||
|
$this->jsonError('Incidente non trovato', 404, 'INCIDENT_NOT_FOUND');
|
||||||
|
}
|
||||||
|
|
||||||
|
$m = $this->computeMetrics($inc);
|
||||||
|
$actions = $this->getParam('improvement_actions');
|
||||||
|
|
||||||
|
$fields = [
|
||||||
|
'organization_id' => $this->getCurrentOrgId(),
|
||||||
|
'problem_statement' => $this->getParam('problem_statement'),
|
||||||
|
'why_1' => $this->getParam('why_1'), 'why_2' => $this->getParam('why_2'),
|
||||||
|
'why_3' => $this->getParam('why_3'), 'why_4' => $this->getParam('why_4'),
|
||||||
|
'why_5' => $this->getParam('why_5'),
|
||||||
|
'root_cause' => $this->getParam('root_cause'),
|
||||||
|
'ttd_minutes' => $m['ttd_minutes'],
|
||||||
|
'ttc_minutes' => $m['ttc_minutes'],
|
||||||
|
'ttr_minutes' => $m['ttr_minutes'],
|
||||||
|
'downtime_minutes' => $m['downtime_minutes'],
|
||||||
|
'affected_users' => $m['affected_users'],
|
||||||
|
'estimated_cost_eur' => $this->getParam('estimated_cost_eur'),
|
||||||
|
'notification_compliance' => $this->getParam('notification_compliance') !== null ? (int)(bool)$this->getParam('notification_compliance') : null,
|
||||||
|
'what_went_well' => $this->getParam('what_went_well'),
|
||||||
|
'what_to_improve' => $this->getParam('what_to_improve'),
|
||||||
|
'improvement_actions' => is_array($actions) ? json_encode($actions, JSON_UNESCAPED_UNICODE) : null,
|
||||||
|
'participants' => $this->getParam('participants'),
|
||||||
|
'reviewed_by' => $this->getCurrentUserId(),
|
||||||
|
'reviewed_at' => date('Y-m-d H:i:s'),
|
||||||
|
'status' => $this->getParam('status', 'draft'),
|
||||||
|
];
|
||||||
|
|
||||||
|
$existing = Database::fetchOne('SELECT id FROM incident_pir WHERE incident_id = ?', [$id]);
|
||||||
|
if ($existing) {
|
||||||
|
Database::update('incident_pir', $fields, 'incident_id = ?', [$id]);
|
||||||
|
$pirId = (int) $existing['id'];
|
||||||
|
} else {
|
||||||
|
$fields['incident_id'] = $id;
|
||||||
|
$pirId = Database::insert('incident_pir', $fields);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Se la root cause e' definita, allineala anche all'incidente (campo legacy)
|
||||||
|
if (!empty($fields['root_cause'])) {
|
||||||
|
Database::update('incidents', ['root_cause' => $fields['root_cause']], 'id = ?', [$id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->logAudit('incident_pir_saved', 'incident', $id, ['pir_id' => $pirId, 'status' => $fields['status']]);
|
||||||
|
$this->jsonSuccess(['pir_id' => $pirId, 'metrics' => $m], 'Post-Incident Review salvata');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -28,6 +28,32 @@ class AIService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Blocco "fonti certe" da iniettare nei system prompt.
|
||||||
|
* Elenca le fonti normative autoritative e impone di citarle, vietando
|
||||||
|
* riferimenti inventati. (Richiesta utente 2026-05-29 - grounding su fonti certe.)
|
||||||
|
*/
|
||||||
|
private function authoritativeSourcesBlock(): string
|
||||||
|
{
|
||||||
|
static $sources = null;
|
||||||
|
if ($sources === null) {
|
||||||
|
$sources = @include __DIR__ . '/../config/nis2_sources.php';
|
||||||
|
if (!is_array($sources)) $sources = [];
|
||||||
|
}
|
||||||
|
if (empty($sources)) return '';
|
||||||
|
|
||||||
|
$lines = [];
|
||||||
|
foreach ($sources as $s) {
|
||||||
|
$lines[] = '- ' . $s['citation'] . ' — ' . $s['authority'];
|
||||||
|
}
|
||||||
|
return "\n## FONTI NORMATIVE CERTE (cita SEMPRE quella pertinente)\n"
|
||||||
|
. implode("\n", $lines)
|
||||||
|
. "\n\nREGOLE SULLE FONTI (vincolanti):\n"
|
||||||
|
. "1. Ogni affermazione normativa DEVE essere ancorata a una di queste fonti, citata esplicitamente (es. \"ai sensi dell'art. 23 della Direttiva (UE) 2022/2555\" o \"Determinazione ACN n. 164179/2025, Allegato 3\").\n"
|
||||||
|
. "2. NON inventare numeri di articolo, determine, allegati o date: se non sei certo, dichiaralo e invita a verificare la fonte ufficiale.\n"
|
||||||
|
. "3. Preferisci sempre il riferimento normativo italiano (D.Lgs. 138/2024 + Determine ACN) per gli obblighi operativi, e la Direttiva UE per i principi.\n";
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Analizza risultati gap analysis e genera raccomandazioni
|
* Analizza risultati gap analysis e genera raccomandazioni
|
||||||
*/
|
*/
|
||||||
@ -162,8 +188,23 @@ PROMPT;
|
|||||||
*/
|
*/
|
||||||
public function classifyIncident(string $title, string $description, array $organization): array
|
public function classifyIncident(string $title, string $description, array $organization): array
|
||||||
{
|
{
|
||||||
|
$entityType = $organization['entity_type'] ?? 'important';
|
||||||
|
// Allegato 3 (soggetti essenziali) vs Allegato 4 (soggetti importanti):
|
||||||
|
// gli importanti NON hanno l'obbligo sugli incidenti ricorrenti (IS-4).
|
||||||
|
$isEssential = ($entityType === 'essential');
|
||||||
|
$allowedIs = $isEssential ? 'IS-1|IS-2|IS-3|IS-4' : 'IS-1|IS-2|IS-3';
|
||||||
|
$allegato = $isEssential ? 'Allegato 3 (soggetti essenziali)' : 'Allegato 4 (soggetti importanti)';
|
||||||
|
$sourcesBlock = $this->authoritativeSourcesBlock();
|
||||||
|
|
||||||
$prompt = <<<PROMPT
|
$prompt = <<<PROMPT
|
||||||
Sei un analista di incident response. Classifica il seguente incidente di sicurezza secondo i criteri NIS2.
|
Sei un analista di incident response NIS2. Classifica il seguente incidente secondo il quadro normativo italiano.
|
||||||
|
|
||||||
|
## Quadro normativo di riferimento (cita la fonte pertinente in ogni campo motivazionale)
|
||||||
|
- Obbligo di notifica: art. 23 D.Lgs. 138/2024 e Direttiva (UE) 2022/2555.
|
||||||
|
- Classificazione incidenti significativi e tempistiche: Determinazione ACN n. 164179/2025, {$allegato}.
|
||||||
|
- Tempistiche: preallarme entro 24h, notifica completa entro 72h, relazione finale entro 1 mese dalla conoscenza dell'incidente significativo.
|
||||||
|
- Tipologie significative applicabili a questo soggetto ({$entityType}): {$allowedIs}.
|
||||||
|
{$sourcesBlock}
|
||||||
|
|
||||||
## Incidente
|
## Incidente
|
||||||
- Titolo: {$title}
|
- Titolo: {$title}
|
||||||
@ -171,21 +212,23 @@ Sei un analista di incident response. Classifica il seguente incidente di sicure
|
|||||||
|
|
||||||
## Organizzazione
|
## Organizzazione
|
||||||
- Settore: {$organization['sector']}
|
- Settore: {$organization['sector']}
|
||||||
- Tipo entità: {$organization['entity_type']}
|
- Tipo entità: {$entityType}
|
||||||
|
|
||||||
Rispondi in formato JSON:
|
Rispondi in formato JSON:
|
||||||
{
|
{
|
||||||
"classification": "cyber_attack|data_breach|system_failure|human_error|natural_disaster|supply_chain|other",
|
"classification": "cyber_attack|data_breach|system_failure|human_error|natural_disaster|supply_chain|other",
|
||||||
|
"nis2_incident_type": "{$allowedIs}|none",
|
||||||
"severity": "low|medium|high|critical",
|
"severity": "low|medium|high|critical",
|
||||||
"is_significant": true/false,
|
"is_significant": true/false,
|
||||||
"significance_reason": "Motivo se significativo secondo NIS2",
|
"significance_reason": "Motivo con citazione esplicita della fonte (es. Determina ACN 164179/2025, {$allegato})",
|
||||||
"requires_csirt_notification": true/false,
|
"requires_csirt_notification": true/false,
|
||||||
|
"notification_basis": "Riferimento normativo dell'obbligo (es. art. 23 D.Lgs. 138/2024)",
|
||||||
"suggested_actions": ["Azione immediata 1", "Azione immediata 2"],
|
"suggested_actions": ["Azione immediata 1", "Azione immediata 2"],
|
||||||
"potential_impact": "Descrizione impatto potenziale",
|
"potential_impact": "Descrizione impatto potenziale",
|
||||||
"iocs_to_check": ["Indicatore 1", "Indicatore 2"]
|
"iocs_to_check": ["Indicatore 1", "Indicatore 2"]
|
||||||
}
|
}
|
||||||
|
|
||||||
Rispondi SOLO con il JSON.
|
Non inventare riferimenti: usa solo le fonti elencate sopra. Rispondi SOLO con il JSON.
|
||||||
PROMPT;
|
PROMPT;
|
||||||
|
|
||||||
$response = $this->callAPI($prompt);
|
$response = $this->callAPI($prompt);
|
||||||
@ -219,6 +262,12 @@ Rispondi sempre in italiano, in modo professionale, preciso e conciso.
|
|||||||
Non includere dati identificativi dell'organizzazione nelle risposte.
|
Non includere dati identificativi dell'organizzazione nelle risposte.
|
||||||
SYSTEM;
|
SYSTEM;
|
||||||
|
|
||||||
|
// Grounding su fonti certe: applicato solo al prompt di default
|
||||||
|
// (i system prompt espliciti gestiscono le fonti per conto proprio).
|
||||||
|
if ($systemPrompt === null) {
|
||||||
|
$system .= "\n" . $this->authoritativeSourcesBlock();
|
||||||
|
}
|
||||||
|
|
||||||
$body = [
|
$body = [
|
||||||
'model' => $this->model,
|
'model' => $this->model,
|
||||||
'max_tokens' => $this->maxTokens,
|
'max_tokens' => $this->maxTokens,
|
||||||
@ -602,7 +651,8 @@ PROMPT;
|
|||||||
}
|
}
|
||||||
|
|
||||||
$systemPrompt = "Sei un esperto consulente di cybersecurity NIS2 (EU 2022/2555) e D.Lgs. 138/2024.\n"
|
$systemPrompt = "Sei un esperto consulente di cybersecurity NIS2 (EU 2022/2555) e D.Lgs. 138/2024.\n"
|
||||||
. "Rispondi in modo preciso e cita le fonti del contesto quando rilevanti.\n";
|
. "Rispondi in modo preciso e cita le fonti del contesto quando rilevanti.\n"
|
||||||
|
. $this->authoritativeSourcesBlock();
|
||||||
if (!empty($contextBlock)) {
|
if (!empty($contextBlock)) {
|
||||||
$systemPrompt .= "\n## Contesto documentale (knowledge base)\n" . $contextBlock
|
$systemPrompt .= "\n## Contesto documentale (knowledge base)\n" . $contextBlock
|
||||||
. "\n\nQuando rispondi, cita esplicitamente i numeri tra parentesi quadre [1], [2], ... che corrispondono ai documenti del contesto.";
|
. "\n\nQuando rispondi, cita esplicitamente i numeri tra parentesi quadre [1], [2], ... che corrispondono ai documenti del contesto.";
|
||||||
|
|||||||
202
application/services/AssetScoringService.php
Normal file
202
application/services/AssetScoringService.php
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* NIS2 Agile - Asset Scoring Service
|
||||||
|
*
|
||||||
|
* Metodologia di scoring rilevanza NIS2 (requisito GV.OC-04).
|
||||||
|
* Adattata dai mockup docs/nis2/assets.html + doc-relevant-systems.html.
|
||||||
|
*
|
||||||
|
* 6 criteri pesati, punteggio 0-100:
|
||||||
|
* C1 Criticita Operativa 0-25
|
||||||
|
* C2 Impatto Interruzione 0-25
|
||||||
|
* C3 Dati Trattati 0-20
|
||||||
|
* C4 Dipendenze 0-15
|
||||||
|
* C5 Esposizione 0-10
|
||||||
|
* C6 Obblighi Normativi 0-5
|
||||||
|
*
|
||||||
|
* Soglia rilevanza NIS2: score >= 40.
|
||||||
|
* Classi: >=80 critico | 60-79 alto | 40-59 medio | 20-39 basso | <20 trascurabile.
|
||||||
|
*
|
||||||
|
* La logica e' PURA (nessun side effect / DB): si presta a unit test e riuso.
|
||||||
|
*/
|
||||||
|
class AssetScoringService
|
||||||
|
{
|
||||||
|
public const RELEVANCE_THRESHOLD = 40;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Griglia ufficiale: per ogni criterio, la lista di opzioni selezionabili
|
||||||
|
* (value => punti) con label per la UI. value e' una chiave stabile usata
|
||||||
|
* dal frontend e salvata in relevance_criteria JSON.
|
||||||
|
*/
|
||||||
|
public const GRID = [
|
||||||
|
'c1_operational_criticality' => [
|
||||||
|
'label' => 'Criticita Operativa',
|
||||||
|
'max' => 25,
|
||||||
|
'help' => 'Quanto il sistema e essenziale per l\'erogazione dei servizi core business.',
|
||||||
|
'options' => [
|
||||||
|
'critical' => ['label' => 'Critico', 'points' => 25],
|
||||||
|
'very_high' => ['label' => 'Molto Alto', 'points' => 20],
|
||||||
|
'high' => ['label' => 'Alto', 'points' => 15],
|
||||||
|
'medium' => ['label' => 'Medio', 'points' => 10],
|
||||||
|
'low' => ['label' => 'Basso', 'points' => 5],
|
||||||
|
'negligible' => ['label' => 'Trascurabile', 'points' => 0],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'c2_disruption_impact' => [
|
||||||
|
'label' => 'Impatto Interruzione',
|
||||||
|
'max' => 25,
|
||||||
|
'help' => 'Conseguenze di un\'interruzione in termini di durata e utenti impattati.',
|
||||||
|
'options' => [
|
||||||
|
'gt24h_gt70' => ['label' => '>24h + >70% utenti', 'points' => 25],
|
||||||
|
'h8_24_50_70' => ['label' => '8-24h + 50-70% utenti', 'points' => 20],
|
||||||
|
'h4_8_30_50' => ['label' => '4-8h + 30-50% utenti', 'points' => 15],
|
||||||
|
'h1_4_10_30' => ['label' => '1-4h + 10-30% utenti', 'points' => 10],
|
||||||
|
'lt1h_lt10' => ['label' => '<1h + <10% utenti', 'points' => 5],
|
||||||
|
'none' => ['label' => 'Nessun impatto', 'points' => 0],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'c3_data_processed' => [
|
||||||
|
'label' => 'Dati Trattati',
|
||||||
|
'max' => 20,
|
||||||
|
'help' => 'Sensibilita e criticita dei dati gestiti dal sistema.',
|
||||||
|
'options' => [
|
||||||
|
'gdpr_art9' => ['label' => 'Dati Sensibili Art.9 GDPR', 'points' => 20],
|
||||||
|
'personal_large' => ['label' => 'Dati Personali larga scala', 'points' => 15],
|
||||||
|
'personal_fin' => ['label' => 'Dati Personali + Finanziari', 'points' => 10],
|
||||||
|
'confidential' => ['label' => 'Dati Aziendali Riservati', 'points' => 5],
|
||||||
|
'public' => ['label' => 'Dati Pubblici', 'points' => 0],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'c4_dependencies' => [
|
||||||
|
'label' => 'Dipendenze',
|
||||||
|
'max' => 15,
|
||||||
|
'help' => 'Quanti altri sistemi critici dipendono da questo sistema.',
|
||||||
|
'options' => [
|
||||||
|
'ge5_critical' => ['label' => '>=5 sistemi critici', 'points' => 15],
|
||||||
|
'n3_4_critical' => ['label' => '3-4 sistemi critici', 'points' => 12],
|
||||||
|
'n2_critical' => ['label' => '2 sistemi critici', 'points' => 9],
|
||||||
|
'n1_critical' => ['label' => '1 sistema critico', 'points' => 6],
|
||||||
|
'noncritical' => ['label' => '1-2 sistemi non critici', 'points' => 3],
|
||||||
|
'none' => ['label' => 'Nessuna dipendenza', 'points' => 0],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'c5_exposure' => [
|
||||||
|
'label' => 'Esposizione',
|
||||||
|
'max' => 10,
|
||||||
|
'help' => 'Superficie di attacco ed esposizione del sistema.',
|
||||||
|
'options' => [
|
||||||
|
'internet_no_mfa' => ['label' => 'Internet pubblico senza MFA', 'points' => 10],
|
||||||
|
'internet_mfa' => ['label' => 'Internet con MFA', 'points' => 8],
|
||||||
|
'partner_net' => ['label' => 'Reti partner/fornitori', 'points' => 6],
|
||||||
|
'intranet' => ['label' => 'Rete aziendale intranet', 'points' => 4],
|
||||||
|
'mgmt_isolated' => ['label' => 'Rete gestione isolata', 'points' => 2],
|
||||||
|
'air_gapped' => ['label' => 'Completamente isolato', 'points' => 0],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'c6_regulatory' => [
|
||||||
|
'label' => 'Obblighi Normativi',
|
||||||
|
'max' => 5,
|
||||||
|
'help' => 'Se il sistema e soggetto a obblighi normativi o contrattuali specifici.',
|
||||||
|
'options' => [
|
||||||
|
'nis2_required' => ['label' => 'Richiesto da NIS2', 'points' => 5],
|
||||||
|
'mandatory_cert' => ['label' => 'Certificazioni obbligatorie', 'points' => 4],
|
||||||
|
'strict_sla' => ['label' => 'Obblighi SLA stringenti', 'points' => 3],
|
||||||
|
'external_audit' => ['label' => 'Audit esterni regolari', 'points' => 2],
|
||||||
|
'none' => ['label' => 'Nessun obbligo', 'points' => 0],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calcola lo score a partire dalle selezioni dell'utente.
|
||||||
|
*
|
||||||
|
* @param array $criteria mappa criterioKey => optionValue
|
||||||
|
* es. ['c1_operational_criticality' => 'critical', ...]
|
||||||
|
* @return array{score:int, class:string, is_relevant:bool, breakdown:array, criticality:string}
|
||||||
|
* @throws InvalidArgumentException se un criterio/opzione non e valido
|
||||||
|
*/
|
||||||
|
public static function calculate(array $criteria): array
|
||||||
|
{
|
||||||
|
$score = 0;
|
||||||
|
$breakdown = [];
|
||||||
|
|
||||||
|
foreach (self::GRID as $key => $def) {
|
||||||
|
if (!array_key_exists($key, $criteria)) {
|
||||||
|
throw new InvalidArgumentException("Criterio mancante: {$key}");
|
||||||
|
}
|
||||||
|
$optVal = $criteria[$key];
|
||||||
|
if (!isset($def['options'][$optVal])) {
|
||||||
|
throw new InvalidArgumentException("Opzione non valida '{$optVal}' per criterio {$key}");
|
||||||
|
}
|
||||||
|
$pts = $def['options'][$optVal]['points'];
|
||||||
|
$score += $pts;
|
||||||
|
$breakdown[$key] = [
|
||||||
|
'value' => $optVal,
|
||||||
|
'label' => $def['options'][$optVal]['label'],
|
||||||
|
'points' => $pts,
|
||||||
|
'max' => $def['max'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
$class = self::classify($score);
|
||||||
|
|
||||||
|
return [
|
||||||
|
'score' => $score,
|
||||||
|
'class' => $class,
|
||||||
|
'is_relevant' => $score >= self::RELEVANCE_THRESHOLD,
|
||||||
|
'breakdown' => $breakdown,
|
||||||
|
// mapping verso l'enum legacy assets.criticality per coerenza UI esistente
|
||||||
|
'criticality' => self::toLegacyCriticality($score),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Classe testuale secondo le soglie ufficiali. */
|
||||||
|
public static function classify(int $score): string
|
||||||
|
{
|
||||||
|
if ($score >= 80) return 'critico';
|
||||||
|
if ($score >= 60) return 'alto';
|
||||||
|
if ($score >= 40) return 'medio';
|
||||||
|
if ($score >= 20) return 'basso';
|
||||||
|
return 'trascurabile';
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Allinea lo score all'enum assets.criticality preesistente (low/medium/high/critical). */
|
||||||
|
public static function toLegacyCriticality(int $score): string
|
||||||
|
{
|
||||||
|
if ($score >= 80) return 'critical';
|
||||||
|
if ($score >= 60) return 'high';
|
||||||
|
if ($score >= 40) return 'medium';
|
||||||
|
return 'low';
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Misure obbligatorie associate alla classe (per report GV.OC-04 / UI). */
|
||||||
|
public static function requiredMeasures(string $class): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'critico' => [
|
||||||
|
'Monitoraggio continuo 24/7 (SIEM/SOC)',
|
||||||
|
'Backup immutabile con test ripristino periodico',
|
||||||
|
'MFA obbligatoria + accessi privilegiati controllati (PAM)',
|
||||||
|
'Inclusione obbligatoria in BIA e piano di continuita',
|
||||||
|
'Test di vulnerabilita/penetration test almeno annuali',
|
||||||
|
],
|
||||||
|
'alto' => [
|
||||||
|
'Monitoraggio in orario lavorativo + alerting',
|
||||||
|
'Backup regolari con verifica integrita',
|
||||||
|
'MFA per accessi remoti',
|
||||||
|
'Inclusione in risk assessment ciclico',
|
||||||
|
],
|
||||||
|
'medio' => [
|
||||||
|
'Logging centralizzato',
|
||||||
|
'Backup periodici',
|
||||||
|
'Patch management documentato',
|
||||||
|
],
|
||||||
|
'basso' => [
|
||||||
|
'Inventario aggiornato',
|
||||||
|
'Patch management standard',
|
||||||
|
],
|
||||||
|
'trascurabile' => [
|
||||||
|
'Censimento in inventario asset',
|
||||||
|
],
|
||||||
|
][$class] ?? [];
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -255,6 +255,118 @@ class ReportService
|
|||||||
* @param int $orgId ID dell'organizzazione
|
* @param int $orgId ID dell'organizzazione
|
||||||
* @return string Documento HTML completo
|
* @return string Documento HTML completo
|
||||||
*/
|
*/
|
||||||
|
/**
|
||||||
|
* Registro formale "Elenco Sistemi Rilevanti NIS2" (requisito GV.OC-04).
|
||||||
|
* HTML stampabile (PDF via stampa browser). Cita le fonti normative certe.
|
||||||
|
* Adattato dal mockup docs/nis2/doc-relevant-systems.html.
|
||||||
|
*/
|
||||||
|
public function generateRelevantSystemsRegister(int $orgId): string
|
||||||
|
{
|
||||||
|
$org = Database::fetchOne('SELECT name, sector, entity_type FROM organizations WHERE id = ?', [$orgId]);
|
||||||
|
if (!$org) {
|
||||||
|
return $this->buildErrorHtml('Organizzazione non trovata');
|
||||||
|
}
|
||||||
|
|
||||||
|
$systems = Database::fetchAll(
|
||||||
|
"SELECT a.name, a.asset_type, a.category, a.ip_address, a.location,
|
||||||
|
a.relevance_score, a.relevance_class, a.relevance_assessed_at,
|
||||||
|
u.full_name AS owner_name
|
||||||
|
FROM assets a
|
||||||
|
LEFT JOIN users u ON u.id = a.owner_user_id
|
||||||
|
WHERE a.organization_id = ? AND a.is_nis2_relevant = 1
|
||||||
|
ORDER BY a.relevance_score DESC, a.name",
|
||||||
|
[$orgId]
|
||||||
|
);
|
||||||
|
|
||||||
|
$orgName = htmlspecialchars($org['name'] ?? '', ENT_QUOTES, 'UTF-8');
|
||||||
|
$entity = htmlspecialchars($org['entity_type'] ?? '', ENT_QUOTES, 'UTF-8');
|
||||||
|
$sector = htmlspecialchars($org['sector'] ?? '', ENT_QUOTES, 'UTF-8');
|
||||||
|
$date = date('d/m/Y');
|
||||||
|
$appName = defined('APP_NAME') ? APP_NAME : 'NIS2 Agile';
|
||||||
|
$appVer = defined('APP_VERSION') ? APP_VERSION : '1.0.0';
|
||||||
|
|
||||||
|
$classColors = ['critico' => '#dc2626', 'alto' => '#ea580c', 'medio' => '#ca8a04'];
|
||||||
|
$counts = ['critico' => 0, 'alto' => 0, 'medio' => 0];
|
||||||
|
|
||||||
|
$rowsHtml = '';
|
||||||
|
if (empty($systems)) {
|
||||||
|
$rowsHtml = '<tr><td colspan="7" style="text-align:center;color:#888;padding:24px;">Nessun sistema classificato come rilevante (score ≥ 40). Eseguire la valutazione di rilevanza dal modulo Inventario Asset.</td></tr>';
|
||||||
|
} else {
|
||||||
|
$n = 0;
|
||||||
|
foreach ($systems as $s) {
|
||||||
|
$n++;
|
||||||
|
$cls = $s['relevance_class'] ?? 'medio';
|
||||||
|
if (isset($counts[$cls])) $counts[$cls]++;
|
||||||
|
$color = $classColors[$cls] ?? '#6b7280';
|
||||||
|
$rowsHtml .= '<tr>'
|
||||||
|
. '<td>' . $n . '</td>'
|
||||||
|
. '<td><strong>' . htmlspecialchars($s['name'], ENT_QUOTES, 'UTF-8') . '</strong></td>'
|
||||||
|
. '<td>' . htmlspecialchars(($s['asset_type'] ?? '') . ($s['category'] ? ' / ' . $s['category'] : ''), ENT_QUOTES, 'UTF-8') . '</td>'
|
||||||
|
. '<td>' . htmlspecialchars($s['ip_address'] ?: '-', ENT_QUOTES, 'UTF-8') . '</td>'
|
||||||
|
. '<td>' . htmlspecialchars($s['owner_name'] ?: '-', ENT_QUOTES, 'UTF-8') . '</td>'
|
||||||
|
. '<td style="text-align:center;font-weight:700;">' . (int) $s['relevance_score'] . '/100</td>'
|
||||||
|
. '<td style="color:' . $color . ';font-weight:700;text-transform:uppercase;">' . htmlspecialchars($cls, ENT_QUOTES, 'UTF-8') . '</td>'
|
||||||
|
. '</tr>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$total = count($systems);
|
||||||
|
|
||||||
|
return <<<HTML
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="it"><head><meta charset="utf-8">
|
||||||
|
<title>Elenco Sistemi Rilevanti NIS2 - {$orgName}</title>
|
||||||
|
<style>
|
||||||
|
body{font-family:'Segoe UI',Arial,sans-serif;color:#1f2937;margin:40px;font-size:13px;}
|
||||||
|
.conf{background:#7f1d1d;color:#fff;text-align:center;padding:8px;font-weight:700;letter-spacing:1px;border-radius:6px;margin-bottom:18px;}
|
||||||
|
h1{font-size:22px;margin:0 0 4px;} h2{font-size:15px;border-bottom:2px solid #06b6d4;padding-bottom:4px;margin-top:28px;}
|
||||||
|
.meta{color:#6b7280;font-size:12px;margin-bottom:18px;}
|
||||||
|
table{width:100%;border-collapse:collapse;margin-top:10px;} th,td{border:1px solid #e5e7eb;padding:7px 9px;text-align:left;}
|
||||||
|
th{background:#f0f9ff;font-size:12px;} .stats{display:flex;gap:14px;margin:14px 0;}
|
||||||
|
.stat{flex:1;border:1px solid #e5e7eb;border-radius:8px;padding:10px;text-align:center;}
|
||||||
|
.stat .v{font-size:22px;font-weight:800;} .src{background:#f9fafb;border-left:4px solid #06b6d4;padding:10px 14px;font-size:11.5px;color:#374151;margin-top:24px;border-radius:0 6px 6px 0;}
|
||||||
|
.sign{margin-top:36px;display:flex;justify-content:space-between;} .sign div{width:45%;border-top:1px solid #9ca3af;padding-top:6px;font-size:12px;color:#4b5563;}
|
||||||
|
@media print{body{margin:12mm;} .noprint{display:none;}}
|
||||||
|
</style></head><body>
|
||||||
|
<div class="conf">⚠ DOCUMENTO RISERVATO - DISTRIBUZIONE LIMITATA ⚠</div>
|
||||||
|
<h1>{$orgName}</h1>
|
||||||
|
<h1 style="font-size:18px;color:#0e7490;">Elenco Formale dei Sistemi Rilevanti NIS2</h1>
|
||||||
|
<div class="meta">Documento ai sensi della Direttiva (UE) 2022/2555 e del D.Lgs. 138/2024 — Requisito GV.OC-04 (NIST CSF 2.0)<br>
|
||||||
|
Settore: {$sector} | Tipo soggetto: {$entity} | Data emissione: {$date} | Generato da {$appName} v{$appVer}</div>
|
||||||
|
|
||||||
|
<h2>1. Premessa e metodologia</h2>
|
||||||
|
<p>Il presente documento costituisce l'elenco formale dei sistemi informativi e di rete classificati come <strong>rilevanti</strong> ai fini della conformita alla Direttiva NIS2. La classificazione adotta una metodologia di scoring 0-100 su sei criteri (Criticita Operativa, Impatto Interruzione, Dati Trattati, Dipendenze, Esposizione, Obblighi Normativi). <strong>Soglia di rilevanza: punteggio ≥ 40.</strong> I sistemi con punteggio ≥ 80 sono considerati critici e richiedono misure di sicurezza massime e monitoraggio continuo.</p>
|
||||||
|
|
||||||
|
<div class="stats">
|
||||||
|
<div class="stat"><div class="v">{$total}</div>Sistemi rilevanti</div>
|
||||||
|
<div class="stat"><div class="v" style="color:#dc2626;">{$counts['critico']}</div>Critici (≥80)</div>
|
||||||
|
<div class="stat"><div class="v" style="color:#ea580c;">{$counts['alto']}</div>Alti (60-79)</div>
|
||||||
|
<div class="stat"><div class="v" style="color:#ca8a04;">{$counts['medio']}</div>Medi (40-59)</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2>2. Elenco sistemi rilevanti</h2>
|
||||||
|
<table>
|
||||||
|
<thead><tr><th>#</th><th>Sistema</th><th>Tipo/Categoria</th><th>IP</th><th>Responsabile</th><th>Punteggio</th><th>Classe</th></tr></thead>
|
||||||
|
<tbody>{$rowsHtml}</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<div class="src">
|
||||||
|
<strong>Fonti normative certe:</strong><br>
|
||||||
|
• Direttiva (UE) 2022/2555 (NIS2) — Parlamento europeo e Consiglio UE<br>
|
||||||
|
• D.Lgs. 4 settembre 2024, n. 138 — recepimento NIS2 (artt. 23, 24)<br>
|
||||||
|
• NIST Cybersecurity Framework 2.0 — controllo GV.OC-04 (elenco sistemi rilevanti)
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="sign">
|
||||||
|
<div>Redatto da (CISO / Responsabile Compliance)</div>
|
||||||
|
<div>Approvato da (Organo di gestione / Direzione)</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p class="noprint" style="margin-top:24px;"><button onclick="window.print()">Stampa / Salva PDF</button></p>
|
||||||
|
</body></html>
|
||||||
|
HTML;
|
||||||
|
}
|
||||||
|
|
||||||
public function generateExecutiveReport(int $orgId): string
|
public function generateExecutiveReport(int $orgId): string
|
||||||
{
|
{
|
||||||
$data = $this->generateComplianceReport($orgId);
|
$data = $this->generateComplianceReport($orgId);
|
||||||
|
|||||||
@ -19,7 +19,7 @@ class VectorService
|
|||||||
$url = getenv('QDRANT_URL')
|
$url = getenv('QDRANT_URL')
|
||||||
?: ($_SERVER['QDRANT_URL'] ?? null)
|
?: ($_SERVER['QDRANT_URL'] ?? null)
|
||||||
?: ($_ENV['QDRANT_URL'] ?? null)
|
?: ($_ENV['QDRANT_URL'] ?? null)
|
||||||
?: 'http://172.21.0.5:6333'; // IP nis2-qdrant nella docker_nis2-network
|
?: 'http://172.21.0.3:6333'; // IP nis2-qdrant (agg. 2026-05-29: era .5, container con IP dinamico driftato). TODO: assegnare ipv4_address statico in docker-compose per evitare ricorrenze.
|
||||||
$this->qdrantUrl = rtrim($url, '/');
|
$this->qdrantUrl = rtrim($url, '/');
|
||||||
$this->collection = $collection;
|
$this->collection = $collection;
|
||||||
}
|
}
|
||||||
|
|||||||
263
docs/EVIX_ANALISI_CONCORRENZA.html
Normal file
263
docs/EVIX_ANALISI_CONCORRENZA.html
Normal file
@ -0,0 +1,263 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="it">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<title>Evix Suite — Analisi Concorrenza & Best-of-Breed (Strategico/Interno)</title>
|
||||||
|
<style>
|
||||||
|
:root{
|
||||||
|
--cy:#06B6D4; --cy-d:#0e7490; --ink:#0f172a; --mut:#64748b; --line:#e2e8f0;
|
||||||
|
--ok:#16a34a; --warn:#ea580c; --bad:#dc2626; --bg:#f8fafc; --card:#fff;
|
||||||
|
--partial:#ca8a04;
|
||||||
|
}
|
||||||
|
*{box-sizing:border-box}
|
||||||
|
body{font-family:'Segoe UI',system-ui,Arial,sans-serif;color:var(--ink);background:var(--bg);margin:0;line-height:1.55;font-size:15px}
|
||||||
|
.wrap{max-width:1180px;margin:0 auto;padding:32px 24px 80px}
|
||||||
|
header.hero{background:linear-gradient(135deg,#0f172a,#0e7490);color:#fff;border-radius:18px;padding:36px 40px;margin-bottom:14px}
|
||||||
|
header.hero .tag{display:inline-block;background:rgba(255,255,255,.15);padding:4px 12px;border-radius:999px;font-size:12px;letter-spacing:1px;text-transform:uppercase}
|
||||||
|
header.hero h1{margin:14px 0 6px;font-size:30px}
|
||||||
|
header.hero p{margin:0;opacity:.9;max-width:760px}
|
||||||
|
.disclaimer{background:#fff7ed;border:1px solid #fed7aa;color:#9a3412;border-radius:12px;padding:14px 18px;font-size:13.5px;margin:14px 0 30px}
|
||||||
|
h2{font-size:22px;margin:40px 0 6px;border-left:5px solid var(--cy);padding-left:12px}
|
||||||
|
h2 .sub{display:block;font-size:13px;color:var(--mut);font-weight:400;margin-top:3px;padding-left:1px}
|
||||||
|
h3{font-size:17px;margin:26px 0 8px;color:var(--cy-d)}
|
||||||
|
p.lead{color:var(--mut)}
|
||||||
|
.grid{display:grid;gap:16px}
|
||||||
|
.modules{grid-template-columns:repeat(auto-fill,minmax(250px,1fr))}
|
||||||
|
.card{background:var(--card);border:1px solid var(--line);border-radius:14px;padding:18px}
|
||||||
|
.card h4{margin:0 0 4px;font-size:16px}
|
||||||
|
.badge{display:inline-block;font-size:11px;font-weight:700;padding:3px 9px;border-radius:999px;text-transform:uppercase;letter-spacing:.5px}
|
||||||
|
.b-ok{background:#dcfce7;color:#166534} .b-near{background:#fef9c3;color:#854d0e}
|
||||||
|
.b-gap{background:#fee2e2;color:#991b1b}
|
||||||
|
.card ul{margin:8px 0 0;padding-left:18px;font-size:13.5px;color:#334155}
|
||||||
|
.card ul.gap li{color:#9a3412}
|
||||||
|
table{width:100%;border-collapse:collapse;background:#fff;border:1px solid var(--line);border-radius:12px;overflow:hidden;font-size:13.5px;margin-top:10px}
|
||||||
|
th,td{padding:10px 12px;text-align:left;border-bottom:1px solid var(--line);vertical-align:top}
|
||||||
|
thead th{background:#ecfeff;color:var(--cy-d);font-size:12.5px;position:sticky;top:0}
|
||||||
|
tbody tr:last-child td{border-bottom:none}
|
||||||
|
.col-evix{background:#f0fdff}
|
||||||
|
.y{color:var(--ok);font-weight:700}.n{color:var(--bad);font-weight:700}.pp{color:var(--partial);font-weight:700}
|
||||||
|
.v{font-size:11px;color:var(--mut);font-style:italic}
|
||||||
|
.legend{display:flex;gap:18px;flex-wrap:wrap;font-size:13px;color:var(--mut);margin:10px 0 0}
|
||||||
|
.legend span{display:inline-flex;align-items:center;gap:6px}
|
||||||
|
.dot{width:11px;height:11px;border-radius:50%;display:inline-block}
|
||||||
|
.roadmap{border-left:3px solid var(--cy);padding-left:18px;margin-top:10px}
|
||||||
|
.roadmap .item{margin-bottom:14px}
|
||||||
|
.roadmap .when{font-size:12px;font-weight:700;color:var(--cy-d);text-transform:uppercase;letter-spacing:.5px}
|
||||||
|
footer{margin-top:50px;border-top:1px solid var(--line);padding-top:18px;font-size:12.5px;color:var(--mut)}
|
||||||
|
.src{background:#f1f5f9;border-radius:10px;padding:14px 18px;font-size:12.5px;color:#475569;margin-top:14px}
|
||||||
|
@media(max-width:680px){header.hero{padding:24px}.wrap{padding:18px}}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="wrap">
|
||||||
|
|
||||||
|
<header class="hero">
|
||||||
|
<span class="tag">Documento strategico interno · gap-driven</span>
|
||||||
|
<h1>Evix Suite — Analisi Concorrenza & posizionamento Best-of-Breed</h1>
|
||||||
|
<p>Obiettivo strategico: ogni modulo della suite Evix (i prodotti Agile) deve essere <strong>best-of-breed</strong> nel proprio dominio. Questo documento valuta onestamente dove lo siamo già e dove mancano feature per diventarlo, rispetto a piattaforme GRC internazionali e soluzioni NIS2/compliance italiane.</p>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<div class="disclaimer">
|
||||||
|
<strong>Nota metodologica (fonti certe).</strong> Le capacità di <strong>Evix/NIS2 Agile</strong> riportate sono verificate sul codice sorgente del prodotto (feature realmente implementate al 2026-05-29, v1.7.0). Le capacità dei <strong>concorrenti</strong> riflettono posizionamenti generali di pubblico dominio e <em>vanno verificate</em> prima di qualsiasi uso commerciale: le celle marcate <span class="v">[da verificare]</span> richiedono una fonte primaria (sito vendor, demo, analyst report). Questo è un documento <strong>interno</strong>, non un materiale di marketing.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2>1. La suite Evix come insieme di moduli
|
||||||
|
<span class="sub">Evix = brand-ombrello; ciascun prodotto Agile è un "modulo" della suite, integrabile via API condivise (agile-services) e SSO centralizzato.</span>
|
||||||
|
</h2>
|
||||||
|
<div class="grid modules">
|
||||||
|
<div class="card">
|
||||||
|
<h4>NIS2 Agile</h4>
|
||||||
|
<span class="badge b-ok">Maturo</span>
|
||||||
|
<ul><li>Compliance Direttiva (UE) 2022/2555 + D.Lgs. 138/2024</li><li>Oggetto principale di questa analisi</li></ul>
|
||||||
|
</div>
|
||||||
|
<div class="card">
|
||||||
|
<h4>231 Agile</h4>
|
||||||
|
<span class="badge b-near">In suite</span>
|
||||||
|
<ul><li>Modello Organizzativo 231</li><li>Integrato con NIS2 via Services API (mapping NIS2→MOG)</li></ul>
|
||||||
|
</div>
|
||||||
|
<div class="card">
|
||||||
|
<h4>SustainAI Agile</h4>
|
||||||
|
<span class="badge b-near">In suite</span>
|
||||||
|
<ul><li>Sostenibilità / ESG / CSRD</li><li>Stesso stack UI/RAG</li></ul>
|
||||||
|
</div>
|
||||||
|
<div class="card">
|
||||||
|
<h4>TRPG Agile</h4>
|
||||||
|
<span class="badge b-near">In suite</span>
|
||||||
|
<ul><li>Risk & privacy / governance</li><li>Allineamento Auth/SSO/Sessions in corso</li></ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p class="lead" style="margin-top:12px">Il vantaggio competitivo di suite (non del singolo modulo) è l'<strong>integrazione cross-prodotto</strong> + <strong>motore AI/RAG condiviso</strong> + <strong>multi-tenancy e white-label per studi di consulenza</strong>. Sotto, il dettaglio modulo-per-modulo del prodotto NIS2 (il più maturo); gli altri prodotti richiedono un audit analogo dedicato.</p>
|
||||||
|
|
||||||
|
<h2>2. Scorecard Best-of-Breed — moduli di NIS2 Agile
|
||||||
|
<span class="sub">Verde = già best-of-breed nel segmento NIS2 Italia · Giallo = competitivo, gap colmabili · Rosso = gap rilevante vs leader di categoria</span>
|
||||||
|
</h2>
|
||||||
|
<div class="grid modules">
|
||||||
|
|
||||||
|
<div class="card"><h4>Gap Analysis Art.21</h4><span class="badge b-ok">Best-of-breed (IT)</span>
|
||||||
|
<ul><li>80 domande su 10 categorie Art.21, scoring + analisi AI</li><li>Mapping ISO 27001 + ora NIST CSF 2.0 (43 controlli)</li></ul>
|
||||||
|
<ul class="gap gap"><li>Gap: benchmark settoriale anonimizzato assente</li></ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card"><h4>Asset & Sistemi Rilevanti</h4><span class="badge b-ok">Best-of-breed (IT)</span>
|
||||||
|
<ul><li>Scoring rilevanza 0-100 a 6 criteri (GV.OC-04)</li><li>Registro formale stampabile + classi critico/alto/medio</li></ul>
|
||||||
|
<ul class="gap"><li>Gap: auto-discovery asset e integrazione CMDB/cloud assenti</li></ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card"><h4>Gestione Incidenti</h4><span class="badge b-ok">Best-of-breed (IT)</span>
|
||||||
|
<ul><li>Art.23 24h/72h/30g + tassonomia IS-1..4 (Determina ACN 164179/2025)</li><li>PIR 5-Whys + metriche TTD/TTC/TTR; regime essenziale/importante</li></ul>
|
||||||
|
<ul class="gap"><li>Gap: ingestion automatica da SIEM/SOC/EDR (oggi manuale)</li></ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card"><h4>Risk Management</h4><span class="badge b-near">Competitivo</span>
|
||||||
|
<ul><li>Registro rischi, matrice 5×5 ISO 27005, AI suggest</li></ul>
|
||||||
|
<ul class="gap"><li>Gap vs leader: scenari quantitativi (FAIR), monte-carlo, KRI dashboard</li></ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card"><h4>Audit & Evidence</h4><span class="badge b-ok">Differenziante</span>
|
||||||
|
<ul><li>Hash-chain SHA-256 immutabile (integrità forense) + export certificato</li><li>Mapping ISO27001 e NIST CSF 2.0</li></ul>
|
||||||
|
<ul class="gap"><li>Gap: raccolta evidenze automatica (connettori) assente</li></ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card"><h4>Policy Management</h4><span class="badge b-near">Competitivo</span>
|
||||||
|
<ul><li>Generazione bozze AI + workflow approvazione</li></ul>
|
||||||
|
<ul class="gap"><li>Gap: versioning/diff avanzato, attestation dipendenti</li></ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card"><h4>Supply Chain</h4><span class="badge b-near">Competitivo</span>
|
||||||
|
<ul><li>Valutazione fornitori + risk scoring + Art.21.2(d)</li></ul>
|
||||||
|
<ul class="gap"><li>Gap: questionari self-assessment al fornitore, rating esterni</li></ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card"><h4>AI / Knowledge Base</h4><span class="badge b-ok">Differenziante</span>
|
||||||
|
<ul><li>RAG multi-livello (SYSTEM/FIRM/ORG) su Qdrant + Voyage</li><li>Grounding su testi normativi ufficiali con citazioni (fonti certe)</li></ul>
|
||||||
|
<ul class="gap"><li>Gap: nessun gap critico; estendere copertura KB normativa</li></ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card"><h4>Continuous Monitoring</h4><span class="badge b-gap">Gap rilevante</span>
|
||||||
|
<ul class="gap"><li>Assente: monitoraggio continuo dei controlli + evidence automation (core di Vanta/Drata)</li><li>Oggi: assessment puntuale + evidenze manuali</li></ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card"><h4>Integrazioni / Connettori</h4><span class="badge b-gap">Gap rilevante</span>
|
||||||
|
<ul class="gap"><li>Assente catalogo connettori (M365, Google, AWS/Azure, Jira, IdP, EDR)</li><li>Presente: Services API + Webhook HMAC (base solida per costruirli)</li></ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2>3. Matrice comparativa
|
||||||
|
<span class="sub">NIS2 Agile (Evix) vs categorie concorrenti. Confronto sul caso d'uso "compliance NIS2 per PMI/Enterprise e studi di consulenza in Italia".</span>
|
||||||
|
</h2>
|
||||||
|
<div class="legend">
|
||||||
|
<span><span class="dot" style="background:var(--ok)"></span> Sì / forte</span>
|
||||||
|
<span><span class="dot" style="background:var(--partial)"></span> Parziale</span>
|
||||||
|
<span><span class="dot" style="background:var(--bad)"></span> No / debole</span>
|
||||||
|
<span class="v">[dv] = dato concorrente da verificare</span>
|
||||||
|
</div>
|
||||||
|
<table>
|
||||||
|
<thead><tr>
|
||||||
|
<th>Capacità</th>
|
||||||
|
<th class="col-evix">NIS2 Agile (Evix)</th>
|
||||||
|
<th>GRC internazionali<br><span class="v">(ServiceNow, OneTrust, Archer)</span></th>
|
||||||
|
<th>Compliance automation<br><span class="v">(Vanta, Drata)</span></th>
|
||||||
|
<th>Soluzioni NIS2 IT<br><span class="v">[da verificare]</span></th>
|
||||||
|
<th>Consulenza + Excel</th>
|
||||||
|
</tr></thead>
|
||||||
|
<tbody>
|
||||||
|
<tr><td>NIS2 / D.Lgs.138 nativo + Determine ACN 2025</td>
|
||||||
|
<td class="col-evix y">Sì — aggiornato Determine 2025</td>
|
||||||
|
<td class="pp">Parziale, framework generici <span class="v">[dv]</span></td>
|
||||||
|
<td class="n">Debole (focus SOC2/ISO) <span class="v">[dv]</span></td>
|
||||||
|
<td class="pp">Variabile <span class="v">[dv]</span></td>
|
||||||
|
<td class="pp">Dipende dal consulente</td></tr>
|
||||||
|
<tr><td>AI nativa (gap, policy, classificazione incidenti) con grounding su fonti certe</td>
|
||||||
|
<td class="col-evix y">Sì — RAG citante testi ufficiali</td>
|
||||||
|
<td class="pp">In crescita <span class="v">[dv]</span></td>
|
||||||
|
<td class="pp">In crescita <span class="v">[dv]</span></td>
|
||||||
|
<td class="n">Raro <span class="v">[dv]</span></td>
|
||||||
|
<td class="n">No</td></tr>
|
||||||
|
<tr><td>Audit trail immutabile (hash-chain)</td>
|
||||||
|
<td class="col-evix y">Sì — SHA-256 chain</td>
|
||||||
|
<td class="y">Sì <span class="v">[dv]</span></td>
|
||||||
|
<td class="pp">Parziale <span class="v">[dv]</span></td>
|
||||||
|
<td class="n">Raro <span class="v">[dv]</span></td>
|
||||||
|
<td class="n">No</td></tr>
|
||||||
|
<tr><td>Continuous control monitoring + evidence automation</td>
|
||||||
|
<td class="col-evix n">No (gap)</td>
|
||||||
|
<td class="y">Sì <span class="v">[dv]</span></td>
|
||||||
|
<td class="y">Sì — core <span class="v">[dv]</span></td>
|
||||||
|
<td class="n">No <span class="v">[dv]</span></td>
|
||||||
|
<td class="n">No</td></tr>
|
||||||
|
<tr><td>Catalogo connettori/integrazioni (cloud, IdP, EDR, ticketing)</td>
|
||||||
|
<td class="col-evix pp">Parziale — API/webhook, no connettori pronti</td>
|
||||||
|
<td class="y">Sì <span class="v">[dv]</span></td>
|
||||||
|
<td class="y">Sì — molti <span class="v">[dv]</span></td>
|
||||||
|
<td class="n">Raro <span class="v">[dv]</span></td>
|
||||||
|
<td class="n">No</td></tr>
|
||||||
|
<tr><td>Multi-tenant + white-label per studi di consulenza</td>
|
||||||
|
<td class="col-evix y">Sì — firm + branding + KB FIRM</td>
|
||||||
|
<td class="pp">Parziale/costoso <span class="v">[dv]</span></td>
|
||||||
|
<td class="pp">Programmi partner <span class="v">[dv]</span></td>
|
||||||
|
<td class="pp">Variabile <span class="v">[dv]</span></td>
|
||||||
|
<td class="n">No</td></tr>
|
||||||
|
<tr><td>Integrazione cross-compliance (NIS2 ↔ 231 ↔ ESG)</td>
|
||||||
|
<td class="col-evix y">Sì — suite Evix + Services API</td>
|
||||||
|
<td class="pp">Moduli separati <span class="v">[dv]</span></td>
|
||||||
|
<td class="n">No <span class="v">[dv]</span></td>
|
||||||
|
<td class="n">No <span class="v">[dv]</span></td>
|
||||||
|
<td class="n">No</td></tr>
|
||||||
|
<tr><td>Costo / time-to-value per PMI italiana</td>
|
||||||
|
<td class="col-evix y">Basso — onboarding guidato + visura</td>
|
||||||
|
<td class="n">Alto / enterprise <span class="v">[dv]</span></td>
|
||||||
|
<td class="pp">Medio <span class="v">[dv]</span></td>
|
||||||
|
<td class="pp">Variabile <span class="v">[dv]</span></td>
|
||||||
|
<td class="pp">Alto in ore uomo</td></tr>
|
||||||
|
<tr><td>Reporting/dashboard enterprise & analytics</td>
|
||||||
|
<td class="col-evix pp">Parziale — report esecutivo + CSV</td>
|
||||||
|
<td class="y">Forte <span class="v">[dv]</span></td>
|
||||||
|
<td class="y">Forte <span class="v">[dv]</span></td>
|
||||||
|
<td class="pp">Variabile <span class="v">[dv]</span></td>
|
||||||
|
<td class="n">No</td></tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<h2>4. Dove siamo già Best-of-Breed
|
||||||
|
<span class="sub">Vantaggi difendibili, radicati su feature reali del prodotto.</span>
|
||||||
|
</h2>
|
||||||
|
<div class="grid modules">
|
||||||
|
<div class="card"><h4>🇮🇹 Aderenza normativa italiana</h4><ul><li>Unico a coprire Determina ACN 164179/2025 (IS-1..4, Allegati 3/4) e 333017/2025 a livello di workflow, non solo testo.</li></ul></div>
|
||||||
|
<div class="card"><h4>🤖 AI con fonti certe</h4><ul><li>Risposte AI ancorate ai testi normativi ufficiali con citazione esplicita e divieto di riferimenti inventati.</li></ul></div>
|
||||||
|
<div class="card"><h4>🔗 Integrità audit</h4><ul><li>Hash-chain SHA-256 + export certificato: integrità forense delle evidenze.</li></ul></div>
|
||||||
|
<div class="card"><h4>🏢 Modello consulenza/white-label</h4><ul><li>Multi-tenant, KB a 3 livelli, branding per studio: pensato per i consulenti, non solo l'azienda finale.</li></ul></div>
|
||||||
|
<div class="card"><h4>🧩 Suite integrata</h4><ul><li>NIS2 ↔ 231 ↔ ESG via Services API condivise: i competitor sono single-domain.</li></ul></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2>5. Gap → Roadmap per chiudere il "best-of-breed" su ogni modulo
|
||||||
|
<span class="sub">Priorità per impatto competitivo. Le voci P1 sono quelle che oggi ci fanno perdere confronti vs Vanta/Drata e GRC enterprise.</span>
|
||||||
|
</h2>
|
||||||
|
<div class="roadmap">
|
||||||
|
<div class="item"><div class="when">P1 · Colmare il gap "compliance automation"</div>
|
||||||
|
<strong>Continuous Control Monitoring + Evidence Automation.</strong> Connettori per raccolta automatica evidenze (M365, Google Workspace, AWS/Azure, IdP, EDR). È il core di Vanta/Drata e oggi è il nostro gap più visibile. Base esistente: Services API + Webhook HMAC.</div>
|
||||||
|
<div class="item"><div class="when">P1 · Ingestion incidenti</div>
|
||||||
|
<strong>Integrazione SIEM/SOC/EDR</strong> per apertura automatica incidenti (i mockup analizzati già prevedevano "Alert SIEM/SOC" come fonte). Trasforma il modulo incidenti da reattivo a proattivo.</div>
|
||||||
|
<div class="item"><div class="when">P2 · Asset</div>
|
||||||
|
<strong>Auto-discovery asset + import CMDB/cloud</strong> per alimentare automaticamente lo scoring di rilevanza GV.OC-04 appena introdotto.</div>
|
||||||
|
<div class="item"><div class="when">P2 · Risk quantitativo</div>
|
||||||
|
<strong>Risk analysis quantitativa (FAIR)</strong> + dashboard KRI, per competere con i GRC enterprise sul risk management.</div>
|
||||||
|
<div class="item"><div class="when">P2 · Reporting</div>
|
||||||
|
<strong>Dashboard analytics e benchmark settoriale anonimizzato</strong> (già nei TODO di progetto) — chiude il gap su reporting e aggiunge un dato che i competitor non hanno (rete multi-tenant).</div>
|
||||||
|
<div class="item"><div class="when">P3 · Supply chain & policy</div>
|
||||||
|
<strong>Portale self-assessment fornitori</strong> e <strong>attestation/versioning policy</strong> per completare i due moduli "competitivi" verso il best-of-breed.</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="src">
|
||||||
|
<strong>Fonti & verificabilità.</strong> Capacità Evix/NIS2 Agile: codice sorgente del prodotto (v1.7.0, 2026-05-29) e documentazione di progetto. Riferimenti normativi: Direttiva (UE) 2022/2555, D.Lgs. 138/2024, Determine ACN 164179/2025 e 333017/2025 (registro <code>application/config/nis2_sources.php</code>). <strong>Dati concorrenti marcati [da verificare]</strong>: posizionamenti generali di pubblico dominio, da confermare con fonte primaria prima di ogni uso esterno. I nomi dei vendor sono citati a scopo di benchmarking interno.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<footer>
|
||||||
|
Evix Suite — Analisi Concorrenza (strategico/interno) · generato 2026-05-29 (CEST) · NIS2 Agile v1.7.0 ·
|
||||||
|
Documento di lavoro: <strong>non distribuire esternamente senza validazione dei dati concorrenti</strong>.
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
BIN
docs/nis2/AmbitiNIS2_ITA.pdf
Normal file
BIN
docs/nis2/AmbitiNIS2_ITA.pdf
Normal file
Binary file not shown.
233
docs/nis2/AmbitiNIS2_ITA.pdf.txt
Normal file
233
docs/nis2/AmbitiNIS2_ITA.pdf.txt
Normal file
@ -0,0 +1,233 @@
|
|||||||
|
Agenda di Ricerca e Innovazione
|
||||||
|
per la Cybersicurezza
|
||||||
|
|
||||||
|
Settore
|
||||||
|
|
||||||
|
Sottosettore o tipologia di soggetto
|
||||||
|
Sottosettore o tipologia di Allegato
|
||||||
|
soggetto I: Settori ad alta criticità
|
||||||
|
|
||||||
|
Grandi imprese
|
||||||
|
|
||||||
|
(occupano almeno 250 dipendenti oppure hanno un fatturato
|
||||||
|
di almeno 50M€ oppure hanno un bilancio di almeno 43M€)
|
||||||
|
|
||||||
|
Medie imprese
|
||||||
|
|
||||||
|
(occupano almeno 50 dipendenti oppure hanno un fatturato
|
||||||
|
di almeno 10M€ oppure hanno un bilancio di almeno 10M€)
|
||||||
|
|
||||||
|
Piccole e micro imprese
|
||||||
|
|
||||||
|
Autorità di Settore
|
||||||
|
|
||||||
|
1. Energia elettrica
|
||||||
|
2. Teleriscaldamento e teleraffrescamento
|
||||||
|
1. Energia
|
||||||
|
|
||||||
|
3. Petrolio
|
||||||
|
4. Gas
|
||||||
|
5. Idrogeno
|
||||||
|
1. Trasporto aereo
|
||||||
|
|
||||||
|
2. Trasporti
|
||||||
|
|
||||||
|
2. Trasporto ferroviario
|
||||||
|
3. Trasporto per vie d'acqua
|
||||||
|
4. Trasporto su strada
|
||||||
|
|
||||||
|
3. Settore bancario
|
||||||
|
|
||||||
|
1. Enti creditizi quali definiti all'articolo 4, punto 1), del regolamento (UE) n. 575/2013 del Parlamento europeo e del Consiglio
|
||||||
|
(DORA lex specialis)
|
||||||
|
1. Gestori delle sedi di negoziazione quali definiti all'articolo 4, punto 24), della direttiva 2014/65/UE del Parlamento europeo e del Consiglio
|
||||||
|
|
||||||
|
4. Infrastrutture dei mercati finanziari
|
||||||
|
|
||||||
|
2. Controparti centrali (CCP) quali definite all'articolo 2, punto 1), del regolamento (UE) n. 648/2012 del Parlamento europeo e del Consiglio
|
||||||
|
(DORA lex specialis)
|
||||||
|
|
||||||
|
Essenziali
|
||||||
|
|
||||||
|
Importanti1
|
||||||
|
|
||||||
|
Non in ambito2
|
||||||
|
|
||||||
|
Essenziali
|
||||||
|
|
||||||
|
Importanti1
|
||||||
|
|
||||||
|
Non in ambito2
|
||||||
|
|
||||||
|
1. Prestatori di assistenza sanitaria quali definiti all'articolo 3, lettera g), della direttiva 2011/24/UE del Parlamento europeo e del Consiglio
|
||||||
|
2. Laboratori di riferimento dell'UE quali definiti all'articolo 15 del regolamento (UE) 2022/2371 del Parlamento europeo e del Consiglio
|
||||||
|
5. Settore sanitario
|
||||||
|
|
||||||
|
3. Soggetti che svolgono attività di ricerca e sviluppo relative ai medicinali quali definiti all'articolo 1, punto 2), della direttiva 2001/83/CE
|
||||||
|
del Parlamento europeo e del Consiglio
|
||||||
|
4. Soggetti che fabbricano prodotti farmaceutici di base e preparati farmaceutici di cui alla sezione C, divisione 21, della NACE Rev. 2
|
||||||
|
5. Soggetti che fabbricano dispositivi medici considerati critici durante un'emergenza di sanità pubblica (elenco dei dispositivi critici per
|
||||||
|
l'emergenza di sanità pubblica) di cui all'articolo 22 del regolamento (UE) 2022/123 del Parlamento europeo e del Consiglio
|
||||||
|
|
||||||
|
6. Acqua potabile
|
||||||
|
|
||||||
|
1. Fornitori e distributori di acque destinate al consumo umano, quali definiti all'articolo 2, punto 1, lettera a), della direttiva (UE) 2020/2184
|
||||||
|
del Parlamento europeo e del Consiglio, ma esclusi i distributori per i quali la distribuzione di acque destinate al consumo umano è una parte
|
||||||
|
non essenziale dell'attività generale di distribuzione di altri prodotti e beni
|
||||||
|
|
||||||
|
7. Acque reflue
|
||||||
|
|
||||||
|
1. Imprese che raccolgono, smaltiscono o trattano acque reflue urbane, domestiche o industriali quali definite all'articolo 2, punti da 1), 2) e 3),
|
||||||
|
della direttiva 91/271/CEE del Consiglio, escluse le imprese per cui la raccolta, lo smaltimento o il trattamento di acque reflue urbane,
|
||||||
|
domestiche o industriali è una parte non essenziale della loro attività generale
|
||||||
|
1. Fornitori di punti di interscambio Internet (Internet exchange point – IXP)
|
||||||
|
2. Fornitori di servizi di sistema dei nomi di dominio (domain name system – DNS), esclusi gli operatori dei server dei nomi radice
|
||||||
|
|
||||||
|
Essenziali
|
||||||
|
|
||||||
|
3. Gestori di registri dei nomi di dominio di primo livello (top level domain – TLD)
|
||||||
|
4. Fornitori di servizi di cloud computing
|
||||||
|
8. Infrastrutture digitali
|
||||||
|
|
||||||
|
Essenziali
|
||||||
|
|
||||||
|
5. Fornitori di servizi di data center
|
||||||
|
|
||||||
|
Importanti1
|
||||||
|
|
||||||
|
Non in ambito2
|
||||||
|
|
||||||
|
6. Fornitori di reti di distribuzione dei contenuti (content delivery network – CDN)
|
||||||
|
|
||||||
|
Essenziali
|
||||||
|
|
||||||
|
7. Prestatori di servizi fiduciari qualificati e non qualificati
|
||||||
|
8. Fornitori di reti pubbliche di comunicazione elettronica
|
||||||
|
|
||||||
|
10. Spazio
|
||||||
|
|
||||||
|
Importanti1
|
||||||
|
|
||||||
|
Essenziali
|
||||||
|
|
||||||
|
9. Fornitori di servizi di comunicazione elettronica accessibili al pubblico
|
||||||
|
9. Gestione dei servizi TIC
|
||||||
|
(business-to-business)
|
||||||
|
|
||||||
|
Essenziali i servizi fiduciari qualificati/Importanti1 quelli non qualificati
|
||||||
|
|
||||||
|
1. Fornitori di servizi gestiti
|
||||||
|
2. Fornitori di servizi di sicurezza gestiti
|
||||||
|
1. Operatori di infrastrutture terrestri possedute, gestite e operate dagli Stati membri o da privati, che sostengono la fornitura di servizi
|
||||||
|
spaziali, esclusi i fornitori di reti pubbliche di comunicazione elettronica
|
||||||
|
|
||||||
|
Essenziali
|
||||||
|
|
||||||
|
Importanti1
|
||||||
|
|
||||||
|
Non in ambito2
|
||||||
|
|
||||||
|
Essenziali
|
||||||
|
|
||||||
|
Importanti1
|
||||||
|
|
||||||
|
Non in ambito2
|
||||||
|
|
||||||
|
Allegato II: altri settori critici
|
||||||
|
1. Servizi postali e di corriere
|
||||||
|
|
||||||
|
1. Fornitori di servizi postali quali definiti all'articolo 2, punto 1 bis), della direttiva 97/67/CE, tra cui i fornitori di servizi di corriere
|
||||||
|
|
||||||
|
2. Gestione dei rifiuti
|
||||||
|
|
||||||
|
1. Imprese che si occupano della gestione dei rifiuti quali definite all'articolo 3, punto 9), della direttiva 2008/98/CE del Parlamento europeo
|
||||||
|
e del Consiglio, escluse quelle per cui la gestione dei rifiuti non è la principale attività economica
|
||||||
|
|
||||||
|
3. Fabbricazione, produzione e distribuzione
|
||||||
|
di sostanze chimiche
|
||||||
|
|
||||||
|
1. Imprese che si occupano della fabbricazione di sostanze e della distribuzione di sostanze o miscele di cui all'articolo 3, punti 9) e 14),
|
||||||
|
del regolamento (CE) n. 1907/2006 del Parlamento europeo e del Consiglio e imprese che si occupano della produzione di articoli quali definite
|
||||||
|
all'articolo 3, punto 3), del medesimo regolamento, da sostanze o miscele
|
||||||
|
|
||||||
|
4. Produzione, trasformazione e distribuzione
|
||||||
|
di alimenti
|
||||||
|
|
||||||
|
1. Imprese alimentari quali definite all'articolo 3, punto 2), del regolamento (CE) n. 178/2002 del Parlamento europeo e del Consiglio che
|
||||||
|
si occupano della distribuzione all'ingrosso e della produzione industriale e trasformazione
|
||||||
|
1. Fabbricazione di dispositivi medici e di dispositivi medico-diagnostici in vitro
|
||||||
|
|
||||||
|
Importanti1
|
||||||
|
|
||||||
|
Non in ambito2
|
||||||
|
|
||||||
|
2. Fabbricazione di computer e prodotti di elettronica e ottica
|
||||||
|
5. Fabbricazione
|
||||||
|
|
||||||
|
3. Fabbricazione di apparecchiature elettriche
|
||||||
|
4. Fabbricazione di macchinari e apparecchiature n.c.a.
|
||||||
|
5. Fabbricazione di autoveicoli, rimorchi e semirimorchi
|
||||||
|
6. Fabbricazione di altri mezzi di trasporto
|
||||||
|
1. Fornitori di mercati online
|
||||||
|
|
||||||
|
6. Fornitori di servizi digitali
|
||||||
|
|
||||||
|
2. Fornitori di motori di ricerca online
|
||||||
|
3. Fornitori di piattaforme di social network
|
||||||
|
|
||||||
|
Importanti1
|
||||||
|
|
||||||
|
4. Fornitori di servizi di registrazione dei nomi di dominio
|
||||||
|
7. Ricerca
|
||||||
|
|
||||||
|
Importanti1
|
||||||
|
|
||||||
|
1. Organizzazioni di ricerca
|
||||||
|
|
||||||
|
Non in ambito2
|
||||||
|
|
||||||
|
Allegato III: Amministrazioni centrali, regionali, locali e di altro tipo
|
||||||
|
Amministrazioni centrali:
|
||||||
|
1. Gli Organi costituzionali e di rilievo costituzionale
|
||||||
|
2. La Presidenza del Consiglio dei ministri e i Ministeri
|
||||||
|
3. Le Agenzie fiscali
|
||||||
|
4. Le Autorità amministrative indipendenti
|
||||||
|
|
||||||
|
Essenziali
|
||||||
|
|
||||||
|
Amministrazioni regionali:
|
||||||
|
1. Le Regioni e le Province autonome
|
||||||
|
|
||||||
|
Pubbliche Amministrazioni
|
||||||
|
|
||||||
|
Amministrazioni locali:
|
||||||
|
1. Le Città metropolitane
|
||||||
|
2. I Comuni con popolazione superiore a 100.000 abitanti
|
||||||
|
3. I Comuni capoluoghi di regione
|
||||||
|
4. Le Aziende sanitarie locali
|
||||||
|
|
||||||
|
Importanti1
|
||||||
|
|
||||||
|
Altri soggetti pubblici:
|
||||||
|
1. Gli Enti di regolazione dell'attività economica
|
||||||
|
2. Gli Enti produttori di servizi economici
|
||||||
|
3. Gli Enti a struttura associativa
|
||||||
|
4. Gli Enti produttori di servizi assistenziali, ricreativi e culturali
|
||||||
|
5. Gli Enti e le Istituzioni di ricerca
|
||||||
|
6. Gli Istituti zooprofilattici sperimentali
|
||||||
|
|
||||||
|
Allegato IV: Ulteriori tipologie di soggetti
|
||||||
|
1. Soggetti che forniscono servizi di trasporto pubblico locale
|
||||||
|
2. Istituti di istruzione che svolgono attività di ricerca
|
||||||
|
|
||||||
|
Soggetti a eventuale individuazione dell’Autorità
|
||||||
|
|
||||||
|
Ulteriori tipologie di soggetti
|
||||||
|
3. Soggetti che svolgono attività di interesse culturale
|
||||||
|
4. Società in house, società partecipate e società a controllo pubblico, come definite nel decreto legislativo 19 agosto 2016, n.175
|
||||||
|
|
||||||
|
Possibile individuazione dell’Autorità come essenziali
|
||||||
|
2
|
||||||
|
Possibile individuazione dell’Autorità come importanti o essenziali
|
||||||
|
1
|
||||||
|
|
||||||
BIN
docs/nis2/Determina164179_apr2025.pdf
Normal file
BIN
docs/nis2/Determina164179_apr2025.pdf
Normal file
Binary file not shown.
241
docs/nis2/Determina164179_apr2025.pdf.txt
Normal file
241
docs/nis2/Determina164179_apr2025.pdf.txt
Normal file
@ -0,0 +1,241 @@
|
|||||||
|
Agenzia per la Cybersicurezza Nazionale
|
||||||
|
Determinazione del Direttore Generale dell’Agenzia per la
|
||||||
|
cybersicurezza nazionale
|
||||||
|
di cui all’articolo 31, commi 1 e 2, del decreto legislativo 4 settembre 2024, n. 138, adottata
|
||||||
|
secondo le modalità di cui all’articolo 40, comma 5, lettera l), che, ai sensi dell’articolo 42,
|
||||||
|
comma 1, lettera c), in fase di prima applicazione, stabilisce le modalità e le specifiche di base
|
||||||
|
per l’adempimento agli obblighi di cui agli articoli 23, 24, 25, 29 e 32 del decreto medesimo.
|
||||||
|
IL DIRETTORE GENERALE
|
||||||
|
VISTO il decreto-legge 14 giugno 2021, n. 82, come convertito con modificazioni nella legge 4
|
||||||
|
agosto 2021, n. 109, recante “Disposizioni urgenti in materia di cybersicurezza, definizione
|
||||||
|
dell’architettura nazionale di cybersicurezza e istituzione dell’Agenzia per la cybersicurezza
|
||||||
|
nazionale”;
|
||||||
|
VISTO il decreto legislativo 4 settembre 2024, n. 138, recante “il recepimento della direttiva (UE)
|
||||||
|
2022/2555, relativa a misure per un livello comune elevato di cibersicurezza nell’Unione, recante
|
||||||
|
modifica del regolamento (UE) n. 910/2014 e della direttiva (UE) 2018/1972 e che abroga la
|
||||||
|
direttiva (UE) 2016/1148”, c.d. decreto NIS, ed in particolare l’articolo 31, commi 1 e 2, che
|
||||||
|
prevede che, ai fini di cui agli articoli 23, 24, 25, 27, 28 e 29, l'Autorità nazionale competente NIS
|
||||||
|
stabilisce obblighi proporzionati tenuto debitamente conto del grado di esposizione dei soggetti ai
|
||||||
|
rischi, delle dimensioni dei soggetti e della probabilità che si verifichino incidenti, nonché della
|
||||||
|
loro gravità, compreso il loro impatto sociale ed economico, nonché termini, modalità, specifiche
|
||||||
|
e tempi graduali di implementazione di tali obblighi;
|
||||||
|
VISTO l’articolo 40, comma 5, lettera l), del decreto NIS che prevede che tali obblighi sono stabiliti
|
||||||
|
con una o più Determinazioni dell’Agenzia per la cybersicurezza nazionale, sentito il Tavolo per
|
||||||
|
l’attuazione della disciplina NIS;
|
||||||
|
VISTO altresì l’articolo 42, comma 1, lettera c), del decreto NIS, che prevede, in fase di prima
|
||||||
|
applicazione, che l’Autorità nazionale competente NIS stabilisce le modalità e le specifiche di base
|
||||||
|
per l’adempimento ai predetti obblighi;
|
||||||
|
VISTO il decreto del Presidente del Consiglio dei ministri del 10 marzo 2023, recante la nomina
|
||||||
|
del Prefetto Bruno Frattasi a Direttore generale dell’Agenzia per la cybersicurezza nazionale;
|
||||||
|
VISTO il “Framework Nazionale per la Cybersecurity e la Data Protection”, edizione 2025
|
||||||
|
(Framework nazionale), realizzato dal Centro di ricerca di cyber intelligence and information
|
||||||
|
security (CIS) della Sapienza Università di Roma e dal Cybersecurity national lab del Consorzio
|
||||||
|
interuniversitario nazionale per l'informatica (CINI), in collaborazione con l’Agenzia per la
|
||||||
|
cybersicurezza nazionale (ACN), quale strumento di supporto per le organizzazioni pubbliche e
|
||||||
|
private in materia di strategie e processi volti alla sicurezza informatica;
|
||||||
|
CONSIDERATO che gli allegati tecnici recanti le predette specifiche di base, illustrate nella
|
||||||
|
seconda riunione plenaria del Tavolo per l’attuazione della disciplina NIS, tenutasi il 28 gennaio
|
||||||
|
1 di 6
|
||||||
|
|
||||||
|
Agenzia per la Cybersicurezza Nazionale
|
||||||
|
2025, sono stati condivisi con le Autorità di settore e con le associazioni di categoria anche per
|
||||||
|
mezzo dei tavoli settoriali di cui all’articolo 11, comma 4, lettera f), del decreto NIS;
|
||||||
|
PRESSO ATTO dei riscontri pervenuti;
|
||||||
|
SENTITO il Tavolo per l’attuazione della disciplina NIS nella riunione del 10 aprile 2025;
|
||||||
|
RITENUTO di avviare la procedura di informazione ai sensi della Direttiva (UE) n. 2015/1535 del
|
||||||
|
Parlamento europeo e del Consiglio del 9 settembre 2015;
|
||||||
|
CONSIDERATO il grado di esposizione dei soggetti ai rischi, le dimensioni dei soggetti e la
|
||||||
|
probabilità che si verifichino incidenti, nonché la loro gravità, compreso il loro impatto sociale ed
|
||||||
|
economico;
|
||||||
|
|
||||||
|
ADOTTA LA PRESENTE DETERMINAZIONE
|
||||||
|
|
||||||
|
Articolo 1
|
||||||
|
(Definizioni)
|
||||||
|
1. Ai fini della presente determinazione si intende per:
|
||||||
|
a) “decreto NIS”, il decreto legislativo 4 settembre 2024, n. 138;
|
||||||
|
b) “Agenzia per la cybersicurezza nazionale”, l’Agenzia per la cybersicurezza nazionale
|
||||||
|
di cui all’articolo 5, comma 1, del decreto-legge 14 giugno 2021, n. 82;
|
||||||
|
c) “Autorità nazionale competente NIS”, l’Autorità nazionale competente di cui
|
||||||
|
all’articolo 10, comma 1, del decreto NIS;
|
||||||
|
d) “Autorità di settore NIS”, le Amministrazioni di cui all’articolo 11, commi 1 e 2, del
|
||||||
|
decreto NIS;
|
||||||
|
e) “soggetto NIS”, un soggetto, di cui all’articolo 2, comma 1, lettera hhh), del decreto
|
||||||
|
NIS, di natura giuridica pubblica o privata che rientra nell’ambito di applicazione del
|
||||||
|
decreto NIS;
|
||||||
|
f) “soggetti essenziali”, i soggetti NIS considerati essenziali ai sensi del decreto NIS;
|
||||||
|
g) “soggetti importanti”, i soggetti NIS considerati importanti ai sensi del decreto NIS;
|
||||||
|
h) “comunicazione di inserimento nell’elenco dei soggetti NIS”, la comunicazione di cui
|
||||||
|
all’articolo 7, comma 3, lettera a), del decreto NIS;
|
||||||
|
i) “organi di amministrazione e direttivi”, gli organi di amministrazione e direttivi di cui
|
||||||
|
all’articolo 23 del decreto NIS, ivi incluso, laddove presente, il consiglio di
|
||||||
|
amministrazione dei soggetti NIS;
|
||||||
|
j) “misure di sicurezza di base”, specifiche di base per gli obblighi di cui agli articoli 23
|
||||||
|
e 24 del decreto NIS, sviluppate in accordo al Framework nazionale e organizzate in
|
||||||
|
funzioni, categorie, sottocategorie e requisiti;
|
||||||
|
k) “incidenti significativi di base”, le specifiche di base che descrivono gli incidenti
|
||||||
|
significativi di cui all’articolo 25 del decreto NIS;
|
||||||
|
|
||||||
|
2 di 6
|
||||||
|
|
||||||
|
Agenzia per la Cybersicurezza Nazionale
|
||||||
|
l) “sistemi informativi e di rete rilevanti”, sistemi informativi e di rete la cui
|
||||||
|
compromissione comporterebbe un impatto significativo sulla confidenzialità, integrità
|
||||||
|
e disponibilità delle attività e servizi per i quali il soggetto NIS rientra nell’ambito di
|
||||||
|
applicazione del decreto NIS;
|
||||||
|
m) “fornitori di servizi di registrazione dei nomi di dominio”, i fornitori di cui all’articolo
|
||||||
|
2, comma 1, lettera oo), del decreto NIS;
|
||||||
|
n) “gestori di registri dei nomi di dominio di primo livello”, i gestori di cui all’articolo 2,
|
||||||
|
comma 1, lettera pp), del decreto NIS;
|
||||||
|
o) “soggetti PSNC-NIS”, i soggetti di cui all'articolo 1, comma 2-bis, del decreto-legge n.
|
||||||
|
105 del 2019 che sono soggetti NIS;
|
||||||
|
p) “sistemi informativi e di rete PSNC”, sistemi informativi e di rete che sono inseriti
|
||||||
|
nell'elenco di cui all'articolo 1, comma 2, lettera b), del decreto-legge n. 105 del 2019
|
||||||
|
q) “operatori di servizi essenziali”, c.d. OSE, i soggetti NIS identificati prima della data di
|
||||||
|
entrata in vigore del decreto NIS come operatori di servizi essenziali ai sensi del decreto
|
||||||
|
legislativo 18 maggio 2018, n. 65;
|
||||||
|
r) “sistemi informativi e di rete OSE”, sistemi informativi e di rete dell’operatore di servizi
|
||||||
|
essenziali che abilitano i servizi essenziali per i quali l’operatore stesso è stato
|
||||||
|
identificato ai sensi del decreto legislativo 18 maggio 2018, n. 65;
|
||||||
|
s) “operatori telco”, i soggetti NIS che forniscono reti pubbliche di comunicazione
|
||||||
|
elettronica o servizi di comunicazioni elettroniche accessibili al pubblico ai sensi del
|
||||||
|
decreto legislativo 1° agosto 2003, n. 259, ad un numero di utenti pari o superiore, anche
|
||||||
|
alternativamente:
|
||||||
|
1) all’1% della base di utenti nazionale, calcolato sulla base dei dati pubblicati
|
||||||
|
dall’Osservatorio trimestrale delle comunicazioni a cura dell’Autorità per le
|
||||||
|
garanzie nelle comunicazioni;
|
||||||
|
2) a un milione;
|
||||||
|
t) “sistemi informativi e di rete telco”, sistemi informativi e di rete per l’accesso alla rete
|
||||||
|
fissa o mobile, da postazione o da terminale mobile, individuati come critici
|
||||||
|
dall’operatore telco in quanto potenzialmente in grado di servire, per ciascun servizio
|
||||||
|
indicato:
|
||||||
|
1) una percentuale dell’utenza pari o superiore all’1% della base di utenti nazionale
|
||||||
|
per quel servizio, sulla base dei dati pubblicati dall’Osservatorio trimestrale delle
|
||||||
|
comunicazioni a cura dell’Autorità per le garanzie nelle comunicazioni;
|
||||||
|
2) un’utenza pari o superiore a un milione.
|
||||||
|
Articolo 2
|
||||||
|
(Adozione delle specifiche di base)
|
||||||
|
1. In fase di prima applicazione del decreto NIS sono adottate le specifiche di base di cui agli
|
||||||
|
allegati 1, 2, 3 e 4, facenti parte integrante della presente determinazione.
|
||||||
|
2. Le misure di sicurezza di base, a carico degli organi di amministrazione e direttivi e in
|
||||||
|
materia di misure di gestione dei rischi per la sicurezza informatica, sono stabiliti:
|
||||||
|
a) per i soggetti importanti, nell’allegato 1;
|
||||||
|
b) per i soggetti essenziali, nell’allegato 2.
|
||||||
|
3 di 6
|
||||||
|
|
||||||
|
Agenzia per la Cybersicurezza Nazionale
|
||||||
|
3. Gli incidenti significativi di base sono stabiliti:
|
||||||
|
a) per i soggetti importanti, nell’allegato 3;
|
||||||
|
b) per i soggetti essenziali, nell’allegato 4.
|
||||||
|
Articolo 3
|
||||||
|
(Termini per l’adozione delle specifiche di base)
|
||||||
|
1. Il termine per l’adozione delle misure di sicurezza di base di cui agli allegati 1 e 2 è fissato
|
||||||
|
in diciotto mesi dalla ricezione, da parte del soggetto NIS della comunicazione di
|
||||||
|
inserimento nell’elenco dei soggetti NIS.
|
||||||
|
2. Il termine per l’adempimento dell’obbligo di notifica degli incidenti significativi di base
|
||||||
|
descritti negli allegati 3 e 4 è fissato in nove mesi dalla ricezione, da parte del soggetto NIS,
|
||||||
|
della comunicazione di inserimento nell’elenco dei soggetti NIS.
|
||||||
|
Articolo 4
|
||||||
|
(Sicurezza, stabilità e resilienza dei sistemi di nomi di dominio)
|
||||||
|
1. Fermo restando quanto previsto dall’articolo 29 del decreto NIS, entro diciotto mesi dalla
|
||||||
|
ricezione della comunicazione di inserimento nell’elenco dei soggetti NIS, i gestori di
|
||||||
|
registri dei nomi di dominio di primo livello e i fornitori di servizi di registrazione dei nomi
|
||||||
|
di dominio si adeguano alle previsioni di cui al predetto articolo, commi 1 e 2, nonché
|
||||||
|
adottano e rendono pubbliche le politiche e le procedure di cui al comma 3 del medesimo
|
||||||
|
articolo.
|
||||||
|
2. Le modalità di adeguamento alle previsioni di cui all’articolo 29, commi 1 e 2, nonché le
|
||||||
|
politiche e le procedure di cui al comma 3 del medesimo articolo sono approvate dagli organi
|
||||||
|
di amministrazione e direttivi.
|
||||||
|
3. Ai sensi dell’articolo 32, comma 3, i gestori di registri dei nomi di dominio di primo livello
|
||||||
|
e i fornitori di servizi di registrazione dei nomi di dominio adottano politiche al fine di
|
||||||
|
assicurare un livello di sicurezza informatica coerente con le specifiche di cui all’allegato 1.
|
||||||
|
4. Le politiche di sicurezza informatica di cui al comma 3 sono approvate dagli organi di
|
||||||
|
amministrazione e direttivi.
|
||||||
|
Articolo 5
|
||||||
|
(Obblighi di notifica per i soggetti PSNC-NIS)
|
||||||
|
1. Fermo restando quanto previsto dall’articolo 33 del decreto NIS, i soggetti PSNC-NIS
|
||||||
|
notificano gli incidenti significativi di base di cui all’allegato 4, ai sensi dell’articolo 25 del
|
||||||
|
decreto NIS, limitatamente ai sistemi informativi e di rete diversi da quelli PSNC.
|
||||||
|
2. Il termine per l’obbligo di cui al comma 1 decorre dalla data di entrata in vigore della
|
||||||
|
presente determinazione.
|
||||||
|
|
||||||
|
4 di 6
|
||||||
|
|
||||||
|
Agenzia per la Cybersicurezza Nazionale
|
||||||
|
Articolo 6
|
||||||
|
(Regime transitorio per gli operatori di servizi essenziali)
|
||||||
|
1. Fermo restando quanto previsto dall’articolo 2, comma 2, e dall’articolo 3, comma 1, gli
|
||||||
|
operatori di servizi essenziali, limitatamente ai sistemi informativi e di rete OSE, per quanto
|
||||||
|
non in contrasto con la legge e il decreto NIS, assicurano il mantenimento delle misure
|
||||||
|
tecniche e organizzative già adottate prima dell’entrata in vigore del decreto NIS ai sensi del
|
||||||
|
decreto legislativo 18 maggio 2018, n. 65.
|
||||||
|
2. Al fine di assicurare la continuità dell’obbligo di notifica di incidente di cui all’articolo 12,
|
||||||
|
comma 5, del decreto legislativo 18 maggio 2018, n. 65, dall’entrata in vigore della presente
|
||||||
|
determinazione, ai sensi dell’articolo 25 del decreto NIS, gli operatori di servizi essenziali,
|
||||||
|
limitatamente ai sistemi informativi e di rete OSE, notificano gli incidenti significativi di
|
||||||
|
base di cui:
|
||||||
|
a) all’allegato 3, qualora siano soggetti importanti;
|
||||||
|
b) all’allegato 4, qualora siano soggetti essenziali.
|
||||||
|
3. Il termine per gli adempimenti di cui al presente articolo decorre dalla data di entrata in
|
||||||
|
vigore della presente determinazione.
|
||||||
|
Articolo 7
|
||||||
|
(Regime transitorio per gli operatori telco)
|
||||||
|
1. Fermo restando quanto previsto dall’articolo 2, comma 2, e dall’articolo 3, comma 1, gli
|
||||||
|
operatori telco, limitatamente ai sistemi informativi e di rete telco, per quanto non in
|
||||||
|
contrasto con la legge e il decreto NIS, assicurano il mantenimento delle misure di sicurezza
|
||||||
|
e di integrità delle reti e dei servizi già adottate prima dell’entrata in vigore del decreto NIS
|
||||||
|
ai sensi del decreto del Ministro dello sviluppo economico del 12 dicembre 2018.
|
||||||
|
2. Al fine di assicurare la continuità dell’obbligo di notifica di incidente di cui all’articolo 40,
|
||||||
|
comma 3, lettera b), del decreto legislativo 1° agosto 2003, n. 259, ai sensi dell’articolo 25
|
||||||
|
del decreto NIS, dall’entrata in vigore della presente determinazione, gli operatori telco,
|
||||||
|
limitatamente ai sistemi informativi e di rete telco, notificano gli incidenti significativi di
|
||||||
|
base:
|
||||||
|
a) di cui all’allegato 3, qualora siano soggetti importanti;
|
||||||
|
b) di cui all’allegato 4, qualora siano soggetti essenziali.
|
||||||
|
3. Ai fini del comma 2, nella definizione del livello di servizio atteso di cui agli allegati 3 e 4,
|
||||||
|
gli operatori telco considerano come incidenti significativi di base i seguenti casi:
|
||||||
|
a) durata superiore ad un’ora e percentuale degli utenti colpiti superiore al quindici per
|
||||||
|
cento del totale degli utenti nazionali del servizio interessato;
|
||||||
|
b) durata superiore a due ore e percentuale degli utenti colpiti superiore al dieci per
|
||||||
|
cento del totale degli utenti nazionali del servizio interessato;
|
||||||
|
c) durata superiore a quattro ore e percentuale degli utenti colpiti superiore al cinque
|
||||||
|
per cento del totale degli utenti nazionali del servizio interessato;
|
||||||
|
5 di 6
|
||||||
|
|
||||||
|
Agenzia per la Cybersicurezza Nazionale
|
||||||
|
d) durata superiore a sei ore e percentuale degli utenti colpiti superiore al due per cento
|
||||||
|
del totale degli utenti nazionali del servizio interessato;
|
||||||
|
e) durata superiore ad otto ore e percentuale degli utenti colpiti superiore all’uno per
|
||||||
|
cento del totale degli utenti nazionali del servizio interessato.
|
||||||
|
4.
|
||||||
|
|
||||||
|
Il termine per gli adempimenti di cui al presente articolo decorre dalla data di entrata in
|
||||||
|
vigore della presente determinazione.
|
||||||
|
Articolo 8
|
||||||
|
(Disposizioni finanziarie)
|
||||||
|
|
||||||
|
1. Dalla presente determinazione non derivano nuovi o maggiori oneri a carico della finanza
|
||||||
|
pubblica, anche ai sensi dell’articolo 12, comma 6, del decreto NIS.
|
||||||
|
Articolo 9
|
||||||
|
(Pubblicità)
|
||||||
|
1. La presente determinazione è pubblicata sui siti web istituzionali dell’Agenzia per la
|
||||||
|
cybersicurezza nazionale e delle Autorità di settore NIS. Ne sarà data, altresì,
|
||||||
|
comunicazione tramite pubblicazione nella Gazzetta Ufficiale della Repubblica italiana.
|
||||||
|
Articolo 10
|
||||||
|
(Entrata in vigore e disposizioni transitorie)
|
||||||
|
1. Per quanto non previsto dalla presente determinazione, si applicano le disposizioni del
|
||||||
|
decreto NIS.
|
||||||
|
2. La presente determinazione entra in vigore a decorrere dal 30 aprile 2025.
|
||||||
|
3. L’articolo 2, commi 2 e 3, e l’articolo 3 entrano in vigore il giorno successivo
|
||||||
|
all’esperimento della procedura di informazione ai sensi della Direttiva (UE) n. 2015/1535
|
||||||
|
del Parlamento europeo e del Consiglio del 9 settembre 2015.
|
||||||
|
Roma, data del protocollo
|
||||||
|
IL DIRETTORE GENERALE
|
||||||
|
Bruno Frattasi
|
||||||
|
|
||||||
|
Firmato digitalmente da: Bruno
|
||||||
|
Frattasi
|
||||||
|
Data: 14/04/2025 10:52:39
|
||||||
|
|
||||||
|
6 di 6
|
||||||
|
|
||||||
BIN
docs/nis2/Determina333017_sett2025.pdf
Normal file
BIN
docs/nis2/Determina333017_sett2025.pdf
Normal file
Binary file not shown.
678
docs/nis2/Determina333017_sett2025.pdf.txt
Normal file
678
docs/nis2/Determina333017_sett2025.pdf.txt
Normal file
@ -0,0 +1,678 @@
|
|||||||
|
Agenzia per la Cybersicurezza Nazionale
|
||||||
|
Determinazione del Direttore generale dell’Agenzia per la
|
||||||
|
cybersicurezza nazionale
|
||||||
|
di cui all’articolo 7, comma 6, del decreto legislativo 4 settembre 2024, n. 138, adottata
|
||||||
|
secondo le modalità di cui all’articolo 40, comma 5, recante termini, modalità e procedimenti
|
||||||
|
di utilizzo e accesso alla piattaforma digitale nonché ulteriori informazioni che i soggetti
|
||||||
|
devono fornire all’Autorità nazionale competente NIS e termini, modalità e procedimento di
|
||||||
|
designazione dei rappresentanti NIS sul territorio nazionale.
|
||||||
|
IL DIRETTORE GENERALE
|
||||||
|
VISTO il decreto legislativo 12 gennaio 2019, n. 14, recante “Codice della crisi d'impresa e
|
||||||
|
dell'insolvenza in attuazione della legge 19 ottobre 2017, n. 155”;
|
||||||
|
VISTO il decreto-legge 14 giugno 2021, n. 82, convertito, con modificazioni, dalla legge 4 agosto
|
||||||
|
2021, n. 109, recante “Disposizioni urgenti in materia di cybersicurezza, definizione
|
||||||
|
dell’architettura nazionale di cybersicurezza e istituzione dell’Agenzia per la cybersicurezza
|
||||||
|
nazionale”;
|
||||||
|
VISTO il decreto legislativo 4 settembre 2024, n. 138, recante “Recepimento della direttiva (UE)
|
||||||
|
2022/2555, relativa a misure per un livello comune elevato di cibersicurezza nell’Unione, recante
|
||||||
|
modifica del regolamento (UE) n. 910/2014 e della direttiva (UE) 2018/1972 e che abroga la
|
||||||
|
direttiva (UE) 2016/1148” e, in particolare, l’articolo 7 e l’articolo 40, comma 5, lettera b);
|
||||||
|
VISTO il Regolamento (CEE) n. 2137/85 del Consiglio del 25 luglio 1985 relativo all'istituzione di
|
||||||
|
un gruppo europeo di interesse economico (GEIE);
|
||||||
|
VISTO il decreto legislativo 23 luglio 1991, n. 240, recante “Norme per l’applicazione del
|
||||||
|
regolamento n. 85/2137/CEE relativo all’istituzione di un Gruppo europeo di interesse economico GEIE, ai sensi dell’art. 17 della legge 29 dicembre 1990, n. 428”;
|
||||||
|
VISTA la raccomandazione 2003/361/CE della Commissione, del 6 maggio 2003, relativa alla
|
||||||
|
definizione delle microimprese, piccole e medie imprese;
|
||||||
|
VISTA la legge 28 giugno 2024, n. 90, recante “Disposizioni in materia di rafforzamento della
|
||||||
|
cybersicurezza nazionale e di reati informatici”;
|
||||||
|
VISTO il decreto del Presidente della Repubblica 28 dicembre 2000, n. 445, recante “Testo unico
|
||||||
|
delle disposizioni legislative e regolamentari in materia di documentazione amministrativa”, e, in
|
||||||
|
particolare, l’articolo 76;
|
||||||
|
CONSIDERATO che, ai sensi del richiamato articolo 7, comma 1, del decreto legislativo 4
|
||||||
|
settembre 2024, n. 138, i soggetti di cui all'articolo 3 del medesimo decreto si registrano o
|
||||||
|
|
||||||
|
1 di 16
|
||||||
|
|
||||||
|
Agenzia per la Cybersicurezza Nazionale
|
||||||
|
aggiornano la propria registrazione sulla piattaforma digitale resa disponibile dall'Autorità
|
||||||
|
nazionale competente NIS;
|
||||||
|
CONSIDERATO, altresì, che, ai sensi dell’articolo 7, comma 6, e dell’articolo 40, comma 5,
|
||||||
|
lettera b), del decreto legislativo 4 settembre 2024, n. 138, con determinazione dell’Agenzia per la
|
||||||
|
cybersicurezza nazionale, sentito il Tavolo per l’attuazione della disciplina NIS, sono stabiliti i
|
||||||
|
termini, le modalità nonché i procedimenti di utilizzo e accesso alla piattaforma digitale di cui
|
||||||
|
all’articolo 7 e le eventuali ulteriori informazioni che i soggetti devono fornire ai sensi dello stesso
|
||||||
|
articolo, nonché i termini, le modalità e i procedimenti di designazione dei rappresentanti di cui
|
||||||
|
all’articolo 5, comma 3, del medesimo decreto legislativo;
|
||||||
|
RICHIAMATA la propria determinazione n. 333017 del 22 settembre 2025 che ha aggiornato la
|
||||||
|
precedente determinazione n.38565 del 26 novembre 2024 integrandovi le modalità di designazione
|
||||||
|
del referente CSIRT e di aggiornamento annuale delle informazioni, tramite il servizio dedicato
|
||||||
|
NIS/Aggiornamento annuale disponibile sul Portale ACN;
|
||||||
|
RITENUTO di aggiornare e sostituire la predetta determinazione in vista della registrazione 2026
|
||||||
|
dei soggetti NIS sul portale ACN tramite il servizio dedicato NIS/Dichiarazione;
|
||||||
|
SENTITO il Tavolo per l’attuazione della disciplina NIS di cui all’articolo 12 del decreto
|
||||||
|
legislativo 4 settembre 2024, n. 138, nella riunione del 18 dicembre 2025;
|
||||||
|
ADOTTA LA PRESENTE DETERMINAZIONE
|
||||||
|
Capo I
|
||||||
|
Disposizioni di carattere generale
|
||||||
|
Articolo 1
|
||||||
|
(Definizioni)
|
||||||
|
1. Ai fini della presente determinazione si intende per:
|
||||||
|
a) “decreto NIS”, il decreto legislativo 4 settembre 2024, n. 138;
|
||||||
|
b) “Agenzia per la cybersicurezza nazionale”, l’Agenzia per la cybersicurezza nazionale
|
||||||
|
di cui all’articolo 5, comma 1, del decreto-legge 14 giugno 2021, n. 82;
|
||||||
|
c) “Autorità nazionale competente NIS”, l’Autorità nazionale competente di cui
|
||||||
|
all’articolo 10, comma 1, del decreto NIS;
|
||||||
|
d) “Autorità di settore NIS”, le Amministrazioni di cui all’articolo 11, commi 1 e 2, del
|
||||||
|
decreto NIS;
|
||||||
|
e) “organi di amministrazione e direttivi”, gli organi di amministrazione e direttivi di cui
|
||||||
|
all’articolo 23 del decreto NIS, ivi incluso, laddove presente, il consiglio di
|
||||||
|
amministrazione dei soggetti NIS;
|
||||||
|
f) “Portale ACN”, il Portale dei servizi tramite il quale sono accessibili i servizi che
|
||||||
|
l’Agenzia per la cybersicurezza nazionale mette a disposizione dei suoi interlocutori e
|
||||||
|
dei soggetti, pubblici e privati, che rientrano nell’ambito di applicazione della disciplina
|
||||||
|
cyber o con i quali l’Agenzia deve interagire ai sensi della stessa;
|
||||||
|
2 di 16
|
||||||
|
|
||||||
|
Agenzia per la Cybersicurezza Nazionale
|
||||||
|
g) “SPID”, il Sistema pubblico dell’identità digitale, istituito ai sensi dell'art. 64 del CAD,
|
||||||
|
modificato dall’art. 17-ter del decreto-legge 21 giugno 2013, n. 69, convertito con
|
||||||
|
modificazioni, dalla legge 9 agosto 2013, n. 98, ai sensi del Decreto del Presidente del
|
||||||
|
Consiglio dei Ministri 24 ottobre 2014;
|
||||||
|
h) “CIE”, Carta di Identità Elettronica, è il documento d’identità personale garantita dallo
|
||||||
|
Stato e rilasciata dal Ministero dell’Interno che permette l’accertamento dell’identità del
|
||||||
|
possessore e l’accesso ai servizi online delle Pubbliche Amministrazioni;
|
||||||
|
i) “Servizi NIS”, i servizi, accessibili tramite il Portale ACN, necessari per supportare
|
||||||
|
l’espletamento degli adempimenti previsti dal decreto NIS e le interlocuzioni tra
|
||||||
|
l’Autorità nazionale compente NIS e i soggetti;
|
||||||
|
j) “Servizio NIS/Dichiarazione”, il Servizio NIS reso disponibile dall’Autorità nazionale
|
||||||
|
competente NIS ai soggetti ai fini della registrazione di cui all’articolo 7, comma 1, del
|
||||||
|
decreto NIS;
|
||||||
|
k) “Servizio NIS/Aggiornamento annuale informazioni”, il Servizio NIS reso disponibile
|
||||||
|
dall’Autorità nazionale competente NIS ai soggetti NIS per l’aggiornamento annuale,
|
||||||
|
delle informazioni di cui all’articolo 7, commi 4 e 5, del decreto NIS;
|
||||||
|
l) “Servizio NIS/Aggiornamento continuo informazioni”, il Servizio NIS reso disponibile
|
||||||
|
dall’Autorità nazionale competente NIS ai soggetti NIS per l’aggiornamento continuo,
|
||||||
|
delle informazioni trasmesse ai sensi dell’articolo 7, comma 7, del decreto NIS;
|
||||||
|
m) “sito web”, il sito web istituzionale dell’Agenzia per la cybersicurezza nazionale
|
||||||
|
(acn.gov.it);
|
||||||
|
n) “piattaforma digitale”, la piattaforma digitale di cui all’articolo 7, comma 1, del decreto
|
||||||
|
NIS, accessibile tramite il Portale ACN per l’erogazione dei Servizi NIS;
|
||||||
|
o) “soggetto”, un soggetto, di cui all’articolo 2, comma 1, lettera hhh), del decreto NIS, di
|
||||||
|
natura giuridica pubblica o privata per conto della quale un utente accede al Portale
|
||||||
|
ACN e, in particolare, ai Servizi NIS;
|
||||||
|
p) “soggetto NIS”, un soggetto che rientra nell’ambito di applicazione del decreto NIS;
|
||||||
|
q) “punto di contatto”, la persona fisica designata dal soggetto NIS ai sensi dell’articolo 7,
|
||||||
|
comma 1, lettera c), del decreto NIS;
|
||||||
|
r) “sostituto punto di contatto”, la persona fisica designata dal soggetto NIS ai sensi
|
||||||
|
dell’articolo 7, comma 4, lettera d), del decreto NIS;
|
||||||
|
s) “segreteria”, la persona fisica che svolge funzioni di supporto al punto di contatto e al
|
||||||
|
sostituto punto di contatto per promuovere l’efficace interlocuzione con l’Autorità
|
||||||
|
nazionale competente NIS;
|
||||||
|
t) “operatore”, la persona fisica che svolge funzioni di supporto al punto di contatto e al
|
||||||
|
sostituto punto di contatto operando sui servizi NIS;
|
||||||
|
u) “utente”, i componenti degli organi di amministrazione e direttivi, il punto di contatto,
|
||||||
|
il sostituto punto di contatto, la segreteria, il referente CSIRT, il sostituto referente
|
||||||
|
CSIRT e gli operatori che accedono al Portale ACN e, in particolare, accedono ai servizi
|
||||||
|
di competenza;
|
||||||
|
v) “referente CSIRT e sostituti”, le persone fisiche designate dal Punto di contatto per
|
||||||
|
interloquire con lo CSIRT Italia, di cui all’articolo 2, comma 1, lettera i) del decreto
|
||||||
|
NIS, ed effettuare le notifiche di cui agli articoli 25 e 26 del medesimo decreto;
|
||||||
|
w) “rappresentante NIS”, il rappresentante di cui all’articolo 5, comma 3, del decreto NIS;
|
||||||
|
3 di 16
|
||||||
|
|
||||||
|
Agenzia per la Cybersicurezza Nazionale
|
||||||
|
x) “censimento”, il processo di autenticazione, tracciamento e verifica di un utente
|
||||||
|
finalizzato alla sua associazione a un soggetto per accedere al Portale ACN e, in
|
||||||
|
particolare, ai Servizi NIS;
|
||||||
|
y) “associazione”, il processo di tracciamento, verifica e convalida dell’associazione
|
||||||
|
dell’utenza con un soggetto che consente all’utente stesso di accedere al Portale ACN
|
||||||
|
e, in particolare, ai Servizi NIS;
|
||||||
|
z) “registrazione”, il processo di cui all’articolo 7, comma 1, del decreto NIS;
|
||||||
|
aa) “dichiarazione”, la dichiarazione resa dal punto di contatto ai fini della registrazione;
|
||||||
|
bb) “elenco dei soggetti NIS”, l’elenco dei soggetti essenziali e dei soggetti importanti di
|
||||||
|
cui all’articolo 7, comma 3, del decreto NIS;
|
||||||
|
cc) “impresa collegata”, un soggetto che soddisfa i criteri di cui all’articolo 3, paragrafi 2 e
|
||||||
|
3, dell’allegato alla raccomandazione 2003/361/CE, o che fa parte di un gruppo di
|
||||||
|
imprese;
|
||||||
|
dd) “impresa autonoma”, una impresa non identificabile come impresa collegata;
|
||||||
|
ee) “gruppo di imprese”, ai sensi dell’articolo 2, comma 1, lettera h), del decreto legislativo
|
||||||
|
12 gennaio 2019, n. 14, l'insieme delle società, delle imprese e degli enti, esclusi lo
|
||||||
|
Stato e gli enti territoriali, che esercitano o sono sottoposti, ai sensi degli articoli
|
||||||
|
2497 e 2545-septies del codice civile, alla direzione e coordinamento di una società, di
|
||||||
|
un ente o di una persona fisica; a tal fine si presume, salvo prova contraria, che l'attività
|
||||||
|
di direzione e coordinamento delle società del gruppo sia esercitata dalla società o ente
|
||||||
|
tenuto al consolidamento dei loro bilanci oppure dalla società o ente che le controlla,
|
||||||
|
direttamente o indirettamente, anche nei casi di controllo congiunto;
|
||||||
|
ff) “gruppo europeo di interesse economico (GEIE)”, un gruppo di imprese costituito sulla
|
||||||
|
base delle condizioni, modalità ed effetti disciplinati dal Regolamento (CEE) n.
|
||||||
|
2137/85.
|
||||||
|
gg) “aggiornamento annuale delle informazioni”, il processo tramite il quale i soggetti NIS
|
||||||
|
forniscono e, ogni anno, aggiornano le informazioni di cui all’articolo 7, commi 4 e 5,
|
||||||
|
del decreto NIS;
|
||||||
|
hh) “aggiornamento continuo delle informazioni”, il processo tramite il quale, ai sensi
|
||||||
|
dell’articolo 7, comma 7, del decreto NIS, i soggetti NIS comunicano qualsiasi modifica
|
||||||
|
delle informazioni trasmesse ai sensi dei commi 4 e 5 del medesimo articolo
|
||||||
|
tempestivamente e, in ogni caso, entro quattordici giorni dalla data della modifica;
|
||||||
|
ii) “spazio di indirizzamento IP pubblico in uso o nella disponibilità del soggetto NIS”, gli
|
||||||
|
indirizzi IP pubblici e statici che un soggetto NIS utilizza o ha nella propria disponibilità
|
||||||
|
in forza di contratti o accordi con fornitori di servizi Internet (ISP), Registri Internet
|
||||||
|
Regionali o altre organizzazioni deputate alla fornitura di indirizzi IP sulla base delle
|
||||||
|
normative e degli accordi nazionali, europei e internazionali vigenti;
|
||||||
|
jj) “nomi di dominio in uso o nella disponibilità del soggetto NIS”, i nomi di dominio che
|
||||||
|
un soggetto NIS utilizza o ha nella propria disponibilità in forza di contratti o accordi
|
||||||
|
con fornitori di servizi di registrazione di nomi di dominio o altre organizzazioni
|
||||||
|
deputate loro fornitura di nomi di dominio sulla base delle normative e degli accordi
|
||||||
|
nazionali, europei e internazionali vigenti;
|
||||||
|
kk) “accordi di condivisione”, gli accordi di condivisione delle informazioni sulla sicurezza
|
||||||
|
informatica, di cui all’articolo 17, comma 2, del decreto NIS.
|
||||||
|
4 di 16
|
||||||
|
|
||||||
|
Agenzia per la Cybersicurezza Nazionale
|
||||||
|
Articolo 2
|
||||||
|
(Oggetto, ambito di applicazione e finalità)
|
||||||
|
1. La presente determinazione stabilisce termini, modalità e procedimenti di utilizzo e accesso
|
||||||
|
al Portale ACN e, in particolare, ai Servizi NIS nonché le ulteriori informazioni che i
|
||||||
|
soggetti NIS devono fornire all’Autorità nazionale competente NIS ai fini dello svolgimento
|
||||||
|
delle funzioni attribuite dal decreto NIS, i termini, le modalità e i procedimenti di
|
||||||
|
designazione dei rappresentanti NIS nell’Unione.
|
||||||
|
2. Ai fini del comma 1, la presente determinazione definisce:
|
||||||
|
a) le modalità di designazione del punto di contatto e del sostituto punto di contatto:
|
||||||
|
b) il processo per il censimento degli utenti per accedere al Portale ACN;
|
||||||
|
c) il procedimento per l’associazione degli utenti al soggetto per conto del quale accedono
|
||||||
|
ai Servizi NIS;
|
||||||
|
d) il procedimento per la registrazione, tramite il “Servizio NIS/Dichiarazione”;
|
||||||
|
e) il processo per la conferma annuale delle informazioni, tramite il “Servizio
|
||||||
|
NIS/Aggiornamento annuale informazioni”;
|
||||||
|
f) il processo per l’aggiornamento continuo delle informazioni, tramite il “Servizio
|
||||||
|
NIS/Aggiornamento continuo informazioni”.
|
||||||
|
3. Ai sensi dell’articolo 23, comma 1, lettera b), del decreto NIS, gli organi di amministrazione
|
||||||
|
e direttivi dei soggetti NIS sovrintendono alla registrazione, comunicazione o
|
||||||
|
aggiornamento delle informazioni di cui all’articolo 7 del medesimo decreto e sono
|
||||||
|
responsabili delle eventuali violazioni.
|
||||||
|
4. La mancata registrazione, comunicazione o aggiornamento delle informazioni di cui
|
||||||
|
all’articolo 7 del decreto NIS, con le modalità sopra indicate, è punita ai sensi dell’articolo
|
||||||
|
38 del medesimo decreto.
|
||||||
|
Articolo 3
|
||||||
|
(Termini di uso del Portale ACN e dei Servizi NIS)
|
||||||
|
1. I soggetti comunicano con l’Autorità nazionale competente NIS, anche ai fini del
|
||||||
|
censimento, dell’associazione e della registrazione, esclusivamente tramite i Servizi NIS o
|
||||||
|
tramite la sezione dedicata nell’area NIS del sito web, salvo in caso di diversa espressa
|
||||||
|
specifica indicazione dell’Autorità nazionale competente o per cause di forza maggiore,
|
||||||
|
fermo restando quanto previsto dal decreto NIS.
|
||||||
|
2. Le istruttorie dell’Autorità nazionale competente NIS e delle Autorità di settore NIS ai fini
|
||||||
|
della presente determinazione sono svolte prioritariamente sulla base delle informazioni
|
||||||
|
trasmesse dai soggetti tramite i Servizi NIS.
|
||||||
|
3. Gli utenti aggiornano le informazioni trasmesse tramite il Portale ACN o tramite i Servizi
|
||||||
|
NIS tempestivamente, secondo eventuale specifica indicazione dell’Autorità nazionale
|
||||||
|
competente NIS, nel rispetto dei termini indicati dal decreto NIS.
|
||||||
|
4. Gli utenti sono tenuti a verificare la correttezza delle informazioni visualizzate o ricevute
|
||||||
|
tramite il Portale ACN e i Servizi NIS, e in caso di incongruenze effettuano la segnalazione
|
||||||
|
di cui al comma 6.
|
||||||
|
|
||||||
|
5 di 16
|
||||||
|
|
||||||
|
Agenzia per la Cybersicurezza Nazionale
|
||||||
|
5. Resta ferma la responsabilità penale, ai sensi dell’articolo 76 del decreto del Presidente della
|
||||||
|
Repubblica del 28 dicembre 2000, n. 445, in caso di rilascio di dichiarazioni mendaci,
|
||||||
|
formazione di atti falsi o, comunque, contenenti dati non più rispondenti a verità.
|
||||||
|
6. Gli utenti segnalano, tramite gli appositi canali di comunicazione del Portale ACN o tramite
|
||||||
|
la sezione dedicata nell’area NIS del sito web, malfunzionamenti o comportamenti inattesi
|
||||||
|
del Portale ACN stesso e dei Servizi NIS.
|
||||||
|
7. Le informazioni visualizzate o ricevute tramite il Portale ACN e i Servizi NIS sono
|
||||||
|
condivise nel rispetto della politica di condivisione delle informazioni. Salvo diversa
|
||||||
|
specifica indicazione, le informazioni visualizzate o ricevute tramite il Portale ACN e i
|
||||||
|
Servizi NIS sono a divulgazione limitata e sono ristrette all’originatore e ai destinatari
|
||||||
|
dell’informazione, nonché alle loro organizzazioni, alle loro terze parti e ai propri clienti. I
|
||||||
|
destinatari non possono condividere le informazioni ricevute al di fuori della propria
|
||||||
|
organizzazione, delle loro terze parti e dei propri clienti. La condivisione delle informazioni
|
||||||
|
ricevute nella propria organizzazione con le terze parti e con i clienti è limitata ai dati
|
||||||
|
strettamente necessari per lo svolgimento delle attività (principio del need-to-know).
|
||||||
|
Articolo 4
|
||||||
|
(Punto di contatto)
|
||||||
|
1. Il punto di contatto è una persona fisica designata dal soggetto NIS con il compito di curare
|
||||||
|
l'attuazione delle disposizioni del decreto NIS per conto del soggetto stesso. In particolare,
|
||||||
|
il punto di contatto accede al Portale ACN e ai Servizi NIS, effettua, per conto del soggetto,
|
||||||
|
la registrazione di cui all’articolo 7 del decreto NIS, e interloquisce, per conto del soggetto
|
||||||
|
NIS, con l’Autorità nazionale competente NIS.
|
||||||
|
2. Le funzioni di punto di contatto possono essere svolte dal rappresentante legale del soggetto
|
||||||
|
NIS, da uno dei procuratori generali del soggetto NIS, censiti sul registro delle imprese di
|
||||||
|
cui all’articolo 8 della legge 29 dicembre 1993, n. 580, o da un dipendente del soggetto NIS
|
||||||
|
delegato dal rappresentante legale del soggetto medesimo. Laddove il punto di contatto,
|
||||||
|
nell’espletamento delle proprie funzioni, si avvalga di personale esterno, restano comunque
|
||||||
|
ferme le disposizioni di cui al comma 1.
|
||||||
|
3. Qualora il soggetto sia parte di un gruppo di imprese, le funzioni di punto di contatto
|
||||||
|
possono essere svolte da un dipendente di un’altra impresa del gruppo che rientra
|
||||||
|
nell’ambito di applicazione del decreto NIS, delegato dal rappresentante legale del soggetto
|
||||||
|
stesso.
|
||||||
|
4. Qualora il soggetto NIS sia una pubblica amministrazione, le funzioni di punto di contatto
|
||||||
|
possono essere svolte da personale che presta servizio o dipendente di un’altra pubblica
|
||||||
|
amministrazione che rientra nell’ambito di applicazione del decreto NIS, previa
|
||||||
|
autorizzazione di quest'ultima ai sensi dell'articolo 53 del decreto legislativo 30 marzo 2001,
|
||||||
|
n. 165, delegato dal rappresentante legale del soggetto stesso.
|
||||||
|
5. Il punto di contatto riferisce direttamente al vertice gerarchico del soggetto NIS nonché agli
|
||||||
|
organi di amministrazione e direttivi del soggetto medesimo ai fini di quanto previsto dal
|
||||||
|
decreto NIS.
|
||||||
|
|
||||||
|
6 di 16
|
||||||
|
|
||||||
|
Agenzia per la Cybersicurezza Nazionale
|
||||||
|
6. Resta ferma, in ogni caso, la responsabilità degli organi di amministrazione e direttivi del
|
||||||
|
soggetto NIS ai sensi dell’articolo 23 del decreto NIS e delle persone fisiche ai sensi
|
||||||
|
dell’articolo 38 del medesimo decreto.
|
||||||
|
7. Nel caso di avvicendamento del punto di contatto, gli organi di amministrazione e direttivi
|
||||||
|
provvedono senza ingiustificato ritardo alla designazione del nuovo punto di contatto e
|
||||||
|
assicurano il suo censimento sul Portale ACN.
|
||||||
|
8. La designazione del punto di contatto da parte dei soggetti di cui all’articolo 1, comma 1,
|
||||||
|
della legge 28 giugno 2024, n. 90, che rientrano nell’ambito di applicazione del decreto NIS,
|
||||||
|
può soddisfare l’obbligo di nomina e comunicazione del referente per la cybersicurezza di
|
||||||
|
cui all’articolo 8, comma 2, della medesima legge.
|
||||||
|
Articolo 5
|
||||||
|
(Sostituto punto di contatto)
|
||||||
|
1. Il sostituto punto di contatto è una persona fisica, distinta dal punto di contatto, designato
|
||||||
|
con le medesime modalità di quest’ultimo ai sensi dell’articolo 4, a cui si applicano le
|
||||||
|
previsioni del citato articolo.
|
||||||
|
2. Il sostituto punto di contatto supporta il punto di contatto nell’esercizio delle proprie
|
||||||
|
funzioni, può interloquire direttamente con l’Autorità nazionale competente NIS e può
|
||||||
|
effettuare sulla piattaforma digitale le medesime azioni del punto di contatto, ad eccezione
|
||||||
|
della registrazione di cui all’articolo 7 del decreto NIS.
|
||||||
|
3. Il sostituto punto di contatto è designato entro il 31 maggio dell’anno in cui il soggetto NIS
|
||||||
|
ha ricevuto comunicazione di inserimento nell’elenco dei soggetti NIS.
|
||||||
|
4. L’obbligo di designazione del sostituto punto di contatto non si applica ai soggetti NIS che
|
||||||
|
versino nell’impossibilità materiale di effettuare tale adempimento, in quanto il punto di
|
||||||
|
contatto è l’unica persona fisica operante nell’organizzazione.
|
||||||
|
Articolo 6
|
||||||
|
(Rappresentante nell’Unione)
|
||||||
|
1. Per designare il proprio rappresentante NIS in Italia, i soggetti NIS di cui all’articolo 5,
|
||||||
|
comma 1, lettera b), del decreto NIS, trasmettono e aggiornano, dal primo settembre al trenta
|
||||||
|
novembre di ogni anno, al domicilio digitale dell’Agenzia per la cybersicurezza nazionale
|
||||||
|
la documentazione indicata nella sezione dedicata del sito web. Con le medesime modalità,
|
||||||
|
tali soggetti comunicano il domicilio digitale per le conseguenti interlocuzioni con
|
||||||
|
l’Autorità nazionale competente NIS.
|
||||||
|
2. L’Autorità nazionale competente NIS comunica al domicilio digitale del soggetto
|
||||||
|
l’autorizzazione, o il diniego, a procedere al censimento e alla registrazione entro trenta
|
||||||
|
giorni dalla ricezione della trasmissione di cui al comma 1.
|
||||||
|
3. Ove si renda necessario richiedere al soggetto integrazioni o informazioni, i termini di cui
|
||||||
|
al comma 2 sono sospesi e ricominciano a decorrere dalla data di ricevimento delle
|
||||||
|
integrazioni e delle informazioni che sono rese entro il termine di dieci giorni dalla richiesta.
|
||||||
|
Il tardivo riscontro alle richieste di cui al presente comma può essere motivo di diniego di
|
||||||
|
censimento e registrazione.
|
||||||
|
7 di 16
|
||||||
|
|
||||||
|
Agenzia per la Cybersicurezza Nazionale
|
||||||
|
4. Fermo restando quanto previsto dall’articolo 4, comma 2, i soggetti di cui al comma 1 del
|
||||||
|
presente articolo possono delegare le funzioni di punto di contatto:
|
||||||
|
a) al rappresentante NIS stesso, qualora sia una persona fisica;
|
||||||
|
b) al rappresentante legale, a uno dei procuratori generali o a un dipendente del
|
||||||
|
rappresentante NIS stesso, qualora quest’ultimo sia una persona giuridica.
|
||||||
|
Articolo 7
|
||||||
|
(Referente CSIRT e sostituti)
|
||||||
|
1. Il referente CSIRT è una persona fisica designata dal Punto di Contatto, a partire dal 20
|
||||||
|
novembre ed entro il 31 dicembre 2025, tramite la dedicata procedura telematica resa
|
||||||
|
disponibile dal Portale ACN.
|
||||||
|
2. Il referente CSIRT ha il compito di interloquire con lo CSIRT Italia, di cui all’articolo 2,
|
||||||
|
comma 1, lettera i) del decreto NIS, ed effettuare le notifiche di cui agli articoli 25 e 26 del
|
||||||
|
medesimo decreto per conto del soggetto NIS.
|
||||||
|
3. Al fine di assicurare il tempestivo svolgimento dei compiti del referente CSIRT, con
|
||||||
|
particolare riferimento alla notifica degli incidenti significativi di cui all’articolo 25 del
|
||||||
|
decreto NIS e relativi seguiti, con le medesime modalità di cui al comma 1, possono essere
|
||||||
|
designati uno o più sostituti referente CSIRT.
|
||||||
|
4. I sostituti referente CSIRT, ove designati, supportano il referente CSIRT nell’esercizio delle
|
||||||
|
funzioni di cui al comma 2 e possono svolgerle per suo conto.
|
||||||
|
5. Il referente CSIRT e i suoi sostituti, ove designati, possiedono almeno competenze di base
|
||||||
|
in materia di sicurezza informatica e di gestione di incidenti informatici, nonché una
|
||||||
|
conoscenza approfondita dei sistemi informativi e di rete del soggetto per conto del quale
|
||||||
|
operano.
|
||||||
|
|
||||||
|
Capo II
|
||||||
|
Censimento e associazione delle utenze
|
||||||
|
Articolo 8
|
||||||
|
(Censimento degli utenti)
|
||||||
|
1. Gli utenti si autenticano sul Portale ACN tramite CIE o SPID personale.
|
||||||
|
2. Gli utenti completano la propria anagrafica fornendo le informazioni seguenti, se non già
|
||||||
|
condivise tramite CIE o SPID:
|
||||||
|
a) nome e cognome;
|
||||||
|
b) codice fiscale;
|
||||||
|
c) luogo e data di nascita;
|
||||||
|
d) cittadinanza;
|
||||||
|
e) Paese di residenza e, ove richiesto, di domicilio;
|
||||||
|
f) indirizzo della sede prevalente di servizio, aziendale o professionale;
|
||||||
|
g) indirizzo di posta elettronica ordinaria, preferibilmente individuale, nonché di servizio,
|
||||||
|
aziendale o professionale;
|
||||||
|
8 di 16
|
||||||
|
|
||||||
|
Agenzia per la Cybersicurezza Nazionale
|
||||||
|
h) ove disponibile, un indirizzo di posta elettronica certificata, preferibilmente individuale,
|
||||||
|
nonché di servizio, aziendale o professionale;
|
||||||
|
i) numero di telefono, preferibilmente individuale, nonché di servizio, aziendale o
|
||||||
|
professionale;
|
||||||
|
j) ove disponibile, un numero alternativo di telefono, preferibilmente individuale di
|
||||||
|
servizio, aziendale o professionale;
|
||||||
|
k) denominazione e codice fiscale dell’organizzazione di appartenenza prevalente.
|
||||||
|
3. Qualora, ai sensi della normativa vigente, un utente non possa disporre di credenziali SPID
|
||||||
|
o di CIE, può autenticarsi con credenziali personali. La procedura per la richiesta delle
|
||||||
|
credenziali personali è pubblicata nella sezione dedicata del sito web. Tali utenti forniscono
|
||||||
|
un codice di identificazione nazionale in luogo del codice fiscale di cui al comma 2, lettera
|
||||||
|
c).
|
||||||
|
Articolo 9
|
||||||
|
(Associazione dell’utenza del punto di contatto e del sostituto al soggetto NIS)
|
||||||
|
1. Il punto di contatto, censito sul Portale ACN, effettua l’associazione della sua utenza con il
|
||||||
|
soggetto che lo ha designato attraverso la digitazione del suo codice fiscale o del codice
|
||||||
|
dell’indice dei domicili digitali delle pubbliche amministrazioni e dei gestori di pubblici
|
||||||
|
servizi (IPA).
|
||||||
|
2. L’utente:
|
||||||
|
a) verifica la denominazione nonché l’indirizzo, il domicilio digitale e i recapiti della sede
|
||||||
|
legale del soggetto visualizzati dal Portale ACN;
|
||||||
|
b) indica se è:
|
||||||
|
1) rappresentante legale del soggetto;
|
||||||
|
2) procuratore generale del soggetto;
|
||||||
|
3) delegato dal rappresentante legale del soggetto;
|
||||||
|
c) indica il codice fiscale dell’organizzazione di cui è dipendente qualora diverso dal
|
||||||
|
soggetto al quale si sta associando;
|
||||||
|
d) indica il ruolo svolto presso il soggetto.
|
||||||
|
3. Nel caso di cui al comma 2, lettera b), numero 3, l’utente inserisce sul Portale ACN la delega
|
||||||
|
rilasciata a suo nome dal soggetto NIS, dichiarando che la stessa lo autorizza ad accedere al
|
||||||
|
Portale ACN stesso e ai Servizi NIS per conto del medesimo soggetto.
|
||||||
|
4. L’associazione dell’utenza del punto di contatto è sottoposta alla convalida del soggetto
|
||||||
|
NIS, secondo la procedura telematica indicata nella richiesta inviata al domicilio digitale di
|
||||||
|
quest’ultimo.
|
||||||
|
5. Al termine del processo di censimento e associazione, il soggetto riceve al suo domicilio
|
||||||
|
digitale la comunicazione di conclusione del processo stesso.
|
||||||
|
6. La convalida dell’associazione dell’utenza del punto di contatto ad un soggetto NIS
|
||||||
|
determina la dissociazione, se presente, dell’utenza del punto di contatto precedentemente
|
||||||
|
associata.
|
||||||
|
7. Il sostituto punto di contatto effettua, su invito del punto di contatto, l’associazione con le
|
||||||
|
medesime modalità del punto di contatto di cui al presente articolo.
|
||||||
|
|
||||||
|
9 di 16
|
||||||
|
|
||||||
|
Agenzia per la Cybersicurezza Nazionale
|
||||||
|
Articolo 10
|
||||||
|
(Associazione delle utenze al soggetto NIS)
|
||||||
|
1. Al punto di contatto è data facoltà di invitare ulteriori utenti con il ruolo di operatore e, al
|
||||||
|
più, un utente con il ruolo di segreteria.
|
||||||
|
2. Gli utenti censiti sul Portale ACN che non sono stati designati e associati quali punti di
|
||||||
|
contatto o sostituti punti di contatto:
|
||||||
|
a) sono associati al soggetto NIS, per conto del quale operano, su indicazione e invito
|
||||||
|
del punto di contatto;
|
||||||
|
b) non possono effettuare azioni sul Portale ACN che determinano la trasmissione di
|
||||||
|
comunicazioni, inerenti il perfezionamento degli adempimenti di cu al decreto NIS,
|
||||||
|
al domicilio digitale del soggetto NIS o all’Autorità nazionale competente NIS.
|
||||||
|
3. Tutti gli utenti possono:
|
||||||
|
a) annullare la propria associazione con il soggetto NIS;
|
||||||
|
b) disabilitare la propria utenza.
|
||||||
|
4. Il punto di contatto, il sostituto punto di contatto, e la segreteria possono ridurre il proprio
|
||||||
|
ruolo ad operatore.
|
||||||
|
|
||||||
|
Capo III
|
||||||
|
Registrazione dei soggetti NIS e elaborazione dell’elenco dei soggetti NIS
|
||||||
|
Articolo 11
|
||||||
|
(Registrazione)
|
||||||
|
1. Dal 1° gennaio al 28 febbraio di ogni anno, gli utenti compilano, tramite il “Servizio NIS/
|
||||||
|
Dichiarazione”, la dichiarazione per il soggetto per cui operano ai fini della sua
|
||||||
|
registrazione, assicurandosi che le informazioni fornite siano corrette e aggiornate.
|
||||||
|
2. In particolare, l’utente:
|
||||||
|
a) qualora il soggetto non sia un’impresa autonoma, indica se il soggetto è parte di un
|
||||||
|
gruppo di imprese e, in tal caso, indica se il soggetto è la capo gruppo ovvero indica il
|
||||||
|
codice fiscale della capo gruppo;
|
||||||
|
b) qualora il soggetto non sia un’impresa autonoma, elenca i soggetti NIS di cui è a
|
||||||
|
conoscenza che sono imprese collegate nei confronti delle quali soddisfi almeno uno
|
||||||
|
dei criteri di cui all’articolo 3, comma 10, del decreto NIS, indicando il codice fiscale
|
||||||
|
di tali imprese e quale dei criteri è soddisfatto;
|
||||||
|
c) qualora il soggetto non sia un’impresa autonoma, elenca le imprese collegate che
|
||||||
|
soddisfano nei suoi confronti almeno uno dei criteri di cui all’articolo 3, comma 10, del
|
||||||
|
decreto NIS, indicando il codice fiscale di tali imprese e quale dei criteri è soddisfatto,
|
||||||
|
ai fini della loro identificazione come soggetti NIS ai sensi del medesimo comma;
|
||||||
|
d) elenca i codici ATECO che descrivono l’attività del soggetto;
|
||||||
|
e) indica le normative settoriali dell’Unione europea citate negli allegati I e II del decreto
|
||||||
|
NIS per definire le tipologie di soggetto che rientrano nell’ambito di applicazione del
|
||||||
|
decreto NIS;
|
||||||
|
10 di 16
|
||||||
|
|
||||||
|
Agenzia per la Cybersicurezza Nazionale
|
||||||
|
f) indica i valori del fatturato e del bilancio nonché del numero di dipendenti al fine di
|
||||||
|
determinare l’appartenenza del soggetto NIS alla categoria delle medie o grandi imprese
|
||||||
|
ai sensi della raccomandazione 2003/361/CE. Le pubbliche amministrazioni possono
|
||||||
|
non indicare i valori del fatturato e del bilancio;
|
||||||
|
g) elenca le tipologie di soggetto di cui agli allegati I, II, III e IV del decreto NIS a cui il
|
||||||
|
soggetto è riconducibile.
|
||||||
|
3. Fermo restando l’obbligo di registrazione per i soggetti di cui all’articolo 3, comma 10, del
|
||||||
|
decreto NIS, l’Autorità nazionale competente NIS informa le imprese di cui al comma 2,
|
||||||
|
lettera c), del presente articolo che nei loro confronti si sono verificati i presupposti di cui
|
||||||
|
al citato articolo del decreto NIS.
|
||||||
|
4. Qualora il soggetto non sia una impresa autonoma, il calcolo del fatturato e del bilancio
|
||||||
|
nonché del numero di dipendenti di cui al comma 2, lettera f), del presente articolo è
|
||||||
|
effettuato ai sensi dell’articolo 6, paragrafo 2, dell’allegato alla raccomandazione
|
||||||
|
2003/361/CE.
|
||||||
|
5. Qualora in fase di compilazione della dichiarazione siano rilevate incongruenze, queste sono
|
||||||
|
segnalate all’utente che deve procedere a:
|
||||||
|
a) modificare la dichiarazione correggendo le informazioni errate o incomplete;
|
||||||
|
b) fornire ulteriori elementi informativi per giustificare l’incongruenza rilevata.
|
||||||
|
6. Al termine della compilazione della dichiarazione, all’utente è rimessa la conferma della
|
||||||
|
valutazione preliminare fornita automaticamente dalla piattaforma, sulla base dei criteri di
|
||||||
|
cui agli articoli 3 e 6 del decreto NIS, fondata sulla base delle informazioni fornite ai sensi
|
||||||
|
del presente articolo.
|
||||||
|
7. Gli utenti designati quali punti di contatto confermano, ai sensi del decreto del Presidente
|
||||||
|
della Repubblica del 28 dicembre 2000, n. 445, le informazioni fornite e le trasmettono
|
||||||
|
telematicamente tramite il “Servizio NIS/Dichiarazione” all’Autorità nazionale competente
|
||||||
|
NIS. Copia di tali informazioni, per ricevuta, è inviata al domicilio digitale del soggetto con
|
||||||
|
l’avvertenza che tale dichiarazione potrà essere sottoposta alle verifiche di coerenza di cui
|
||||||
|
all’articolo 14.
|
||||||
|
8. Decorsi dieci giorni solari dalla sottomissione della dichiarazione questa si intende
|
||||||
|
definitivamente acquisita e non ulteriormente modificabile dall’utente.
|
||||||
|
9. Le dichiarazioni sottomesse o modificate oltre i termini di cui al comma 1 sono considerate
|
||||||
|
tardive, salvo che il ritardo sia determinato da documentate criticità tecnico-operative non
|
||||||
|
imputabili all’utente.
|
||||||
|
10. Ai soggetti già inseriti nell’elenco dei soggetti NIS, all’avvio della registrazione per l’anno
|
||||||
|
2026, viene presentata una bozza di dichiarazione precompilata sulla base delle
|
||||||
|
informazioni trasmesse nel corso dell’anno solare precedente tramite i Servizi NIS.
|
||||||
|
Articolo 12
|
||||||
|
(Clausola di salvaguardia)
|
||||||
|
1. Nel caso in cui l’utente ritenga che il calcolo effettuato ai sensi dell’articolo 11, comma 4,
|
||||||
|
non sia proporzionato tenuto conto dei criteri di cui al decreto del Presidente del Consiglio
|
||||||
|
dei ministri di cui all’articolo 40, comma 1, lettera a), del decreto NIS, nel corso della
|
||||||
|
11 di 16
|
||||||
|
|
||||||
|
Agenzia per la Cybersicurezza Nazionale
|
||||||
|
registrazione può chiedere l’applicazione della clausola di salvaguardia di cui all’articolo 3,
|
||||||
|
comma 12, del decreto NIS.
|
||||||
|
2. Ai fini della richiesta di cui al comma 1, tramite il “Servizio NIS/Dichiarazione”, l’utente
|
||||||
|
fornisce gli elementi di valutazione corrispondenti ai criteri di cui al decreto del Presidente
|
||||||
|
del Consiglio dei ministri di cui all’articolo 40, comma 1, lettera a), del decreto NIS
|
||||||
|
all’Autorità nazionale competente NIS, che li condivide con le Autorità di settore interessate
|
||||||
|
ai fini delle valutazioni di cui all’articolo 11, comma 4, lettera c), del medesimo decreto.
|
||||||
|
3. Al soggetto NIS è fornito riscontro con la comunicazione dell’Autorità nazionale
|
||||||
|
competente NIS ai sensi dell’articolo 7, comma 3, del decreto NIS.
|
||||||
|
|
||||||
|
Articolo 13
|
||||||
|
(Individuazione da parte dell’Autorità nazionale competente NIS)
|
||||||
|
1. I soggetti che ricevono una notifica di individuazione da parte dell’Autorità nazionale
|
||||||
|
competente NIS, su proposta delle Autorità di settore, ai sensi dell’articolo 3, comma 13,
|
||||||
|
del decreto NIS, procedono al censimento e alla registrazione alla stregua delle disposizioni
|
||||||
|
del presente capo.
|
||||||
|
2. In fase di registrazione, tali soggetti prendono visione e confermano gli elementi presenti
|
||||||
|
nella notifica di cui al comma 1.
|
||||||
|
Articolo 14
|
||||||
|
(Verifiche di coerenza)
|
||||||
|
1. Le verifiche di coerenza delle informazioni contenute nelle dichiarazioni sono svolte, a
|
||||||
|
campione, dall’Autorità nazionale competente NIS d’intesa con le Autorità di settore e non
|
||||||
|
sollevano il soggetto NIS dall’obbligo del rispetto dei termini d’uso di cui all’articolo 3
|
||||||
|
della presente determinazione e, in particolare, dalla responsabilità per le dichiarazioni
|
||||||
|
mendaci di cui al comma 5 del medesimo articolo.
|
||||||
|
2. Nei casi di cui al comma 1, l’Autorità nazionale competente NIS fornisce riscontro al
|
||||||
|
soggetto entro trenta giorni dalla presentazione della dichiarazione tramite il “Servizio NIS/
|
||||||
|
Dichiarazione”. Il predetto termine può essere prorogato dall’Autorità nazionale competente
|
||||||
|
NIS, per una sola volta e fino ad un massimo di ulteriori venti giorni, qualora sia necessario
|
||||||
|
svolgere approfondimenti complessi riguardanti la coerenza delle informazioni contenute
|
||||||
|
nella dichiarazione.
|
||||||
|
3. Ove si renda necessario richiedere al soggetto integrazioni, informazioni aggiuntive o
|
||||||
|
modifiche della dichiarazione, i termini di cui al comma 2 sono sospesi e ricominciano a
|
||||||
|
decorrere dalla data di ricevimento delle integrazioni e delle informazioni che sono rese
|
||||||
|
entro il termine di dieci giorni dalla richiesta. Il tardivo riscontro alle richieste di cui al
|
||||||
|
presente comma può essere motivo di rigetto della dichiarazione.
|
||||||
|
4. Al termine delle verifiche di coerenza delle informazioni contenute nelle dichiarazioni,
|
||||||
|
l’Autorità nazionale competente comunica, tramite i Servizi NIS al domicilio digitale del
|
||||||
|
soggetto NIS:
|
||||||
|
a) l’esito positivo della verifica;
|
||||||
|
12 di 16
|
||||||
|
|
||||||
|
Agenzia per la Cybersicurezza Nazionale
|
||||||
|
b) l’esito negativo della verifica.
|
||||||
|
5. La comunicazione di cui al comma 4, lettera b), non solleva il soggetto NIS dall’obbligo di
|
||||||
|
registrazione di cui all’articolo 7, comma 1, del decreto NIS.
|
||||||
|
Articolo 15
|
||||||
|
(Elaborazione dell’elenco dei soggetti NIS e comunicazioni)
|
||||||
|
1. L’elenco dei soggetti NIS di cui all’articolo 7, comma 2, del decreto NIS è elaborato
|
||||||
|
dall’Autorità nazionale competente NIS sulla base delle informazioni trasmesse dai soggetti
|
||||||
|
NIS ai sensi del capo III della presente determinazione e delle verifiche svolte dalle Autorità
|
||||||
|
di settore ai sensi dell’articolo 11, comma 4, lettera a), del medesimo decreto che, ove
|
||||||
|
necessario, possono proseguire anche successivamente all’elaborazione dell’elenco dei
|
||||||
|
soggetti NIS.
|
||||||
|
2. Ai sensi del comma 1, il processo di registrazione di cui alla presente determinazione
|
||||||
|
costituisce la fase endoprocedimentale del procedimento di costituzione dell’elenco dei
|
||||||
|
soggetti NIS.
|
||||||
|
3. Ai sensi dell’articolo 7, comma 3, del decreto NIS, l’Autorità nazionale competente NIS
|
||||||
|
comunica ai soggetti registrati l'inserimento, o meno, nell'elenco dei soggetti NIS. Ai
|
||||||
|
soggetti inseriti nell’elenco dei soggetti NIS e ai loro punti di contatto viene, altresì,
|
||||||
|
comunicato un codice identificativo univoco, per il soggetto NIS, al fine di facilitare le
|
||||||
|
interlocuzioni con l’Autorità nazionale competente NIS.
|
||||||
|
|
||||||
|
Capo IV
|
||||||
|
Aggiornamento delle informazioni
|
||||||
|
Articolo 16
|
||||||
|
(Processo per l’aggiornamento annuale delle informazioni)
|
||||||
|
1. Dal 15 aprile al 31 maggio di ogni anno, gli utenti aggiornano, tramite il “Servizio NIS/
|
||||||
|
Aggiornamento annuale informazioni”, le informazioni per conto del soggetto per cui
|
||||||
|
operano, assicurandone la correttezza.
|
||||||
|
2. Per tutti i soggetti NIS:
|
||||||
|
a) il punto di contatto si assicura che i propri dati anagrafici e di contatto siano corretti e
|
||||||
|
aggiornati. Ove prevista dall’articolo 4, il punto di contatto si assicura che la delega
|
||||||
|
conferitagli dal rappresentante legale del soggetto sia corretta, aggiornata e conforme a
|
||||||
|
quanto previsto dall’articolo medesimo;
|
||||||
|
b) il sostituto punto di contatto si assicura che i propri dati anagrafici e di contatto siano
|
||||||
|
corretti e aggiornati. Ove prevista delega il sostituto punto di contatto si assicura che la
|
||||||
|
delega conferitagli dal rappresentante legale del soggetto sia corretta, aggiornata e
|
||||||
|
conforme a quanto previsto dall’articolo medesimo;
|
||||||
|
c) la segreteria, ove presente, si assicura che i propri dati anagrafici e di contatto siano
|
||||||
|
corretti e aggiornati.
|
||||||
|
3. Per tutti i soggetti NIS, gli utenti verificano la correttezza e l’aggiornamento:
|
||||||
|
13 di 16
|
||||||
|
|
||||||
|
Agenzia per la Cybersicurezza Nazionale
|
||||||
|
a) dei dati anagrafici e di contatto del soggetto NIS. Tali informazioni includono almeno
|
||||||
|
il codice fiscale, la denominazione, l’indirizzo della sede legale, l’indicazione del
|
||||||
|
rappresentante legale, l’elenco dei procuratori generali, il numero di telefono, il
|
||||||
|
domicilio digitale e un indirizzo di posta elettronica ordinaria funzionale;
|
||||||
|
b) dell’elenco dei componenti degli organi di amministrazione e direttivi, quali persone
|
||||||
|
fisiche responsabili ai sensi dell’articolo 38, comma 5, del decreto NIS;
|
||||||
|
c) ove applicabile, dell’elenco dei servizi che rientrano nell’ambito di applicazione della
|
||||||
|
direttiva 2022/2555 che il soggetto NIS offre nell’UE e indicando in quali Stati membri;
|
||||||
|
d) dello spazio di indirizzamento IP pubblico e dei nomi di dominio in uso o nella
|
||||||
|
disponibilità del soggetto NIS, eventualmente distinto a livello di articolazioni di primo
|
||||||
|
livello;
|
||||||
|
e) dell’elenco degli accordi di condivisione delle informazioni
|
||||||
|
f) dei dati identificativi del referente CSIRT e degli eventuali sostituti.
|
||||||
|
4. Per i soggetti NIS di cui all’articolo 7, comma 5, del decreto NIS gli utenti verificano la
|
||||||
|
correttezza e l’aggiornamento dell’elenco delle sedi del soggetto NIS nell’Unione,
|
||||||
|
indicandone l’indirizzo.
|
||||||
|
5. Per i soggetti NIS di cui all’articolo 5, comma 1, lettera b), del decreto NIS, che hanno
|
||||||
|
designato il proprio rappresentante NIS in Italia ai sensi dell’articolo 6 della presente
|
||||||
|
determinazione, gli utenti verificano che dati anagrafici e di contatto del rappresentante NIS
|
||||||
|
siano corretti e aggiornati.
|
||||||
|
6. Qualora ritenuto opportuno, è data la facoltà di descrivere la struttura organizzativa
|
||||||
|
dell’organizzazione, indicandone la suddivisione in articolazioni di primo livello. Tale
|
||||||
|
descrizione della struttura organizzativa potrà essere impiegata per l’eventuale conferimento
|
||||||
|
di informazioni di dettaglio relative alle articolazioni di primo livello.
|
||||||
|
7. Gli utenti designati quali punti di contatto confermano, ai sensi del decreto del Presidente
|
||||||
|
della Repubblica del 28 dicembre 2000, n. 445, le informazioni fornite e le trasmettono
|
||||||
|
telematicamente tramite il “Servizio NIS/Aggiornamento annuale informazioni”
|
||||||
|
all’Autorità nazionale competente NIS. Copia di tali informazioni, per ricevuta, è inviata al
|
||||||
|
domicilio digitale del soggetto.
|
||||||
|
8. La modifica, confermata da punto di contatto, dell’indicazione del rappresentante legale o
|
||||||
|
dell’elenco dei procuratori generali del soggetto NIS è sottoposta alla convalida del soggetto
|
||||||
|
medesimo, secondo la procedura telematica indicata nella richiesta inviata al domicilio
|
||||||
|
digitale di quest’ultimo.
|
||||||
|
9. Le modifiche dei dati anagrafici e di contatto del soggetto NIS sono trasmesse, per ricevuta,
|
||||||
|
al domicilio digitale di quest’ultimo.
|
||||||
|
10. Le modifiche dei dati anagrafici e di contatto degli utenti sono trasmesse, per ricevuta,
|
||||||
|
all’indirizzo di posta elettronica certificata indicata dall’utente stesso o, in subordine,
|
||||||
|
all’indirizzo di posta elettronica ordinaria indicata dall’utente stesso.
|
||||||
|
11. In fase di prima applicazione, fermo restando quanto previsto dall’articolo 35, comma 3,
|
||||||
|
lettera c), e dall’articolo 42, comma 1, lettera c), del decreto NIS, in caso di registrazione
|
||||||
|
tardiva, il termine per completare l’aggiornamento annuale è comunicato di volta in volta
|
||||||
|
dall’Autorità nazionale competente NIS.
|
||||||
|
|
||||||
|
14 di 16
|
||||||
|
|
||||||
|
Agenzia per la Cybersicurezza Nazionale
|
||||||
|
12. Il comma 3, lettera b), del presente articolo e l’articolo 17 non si applicano ai soggetti che
|
||||||
|
rientrano nell’ambito di applicazione del decreto NIS e del Regolamento UE 2022/2554
|
||||||
|
(DORA).
|
||||||
|
Articolo 17
|
||||||
|
(Elencazione degli organi di amministrazione e direttivi)
|
||||||
|
1. Ai fini dell’articolo 16, comma 3, lettera b), tramite il “Servizio NIS/Aggiornamento
|
||||||
|
annuale informazioni”, gli utenti elencano i codici fiscali delle persone fisiche che
|
||||||
|
compongono gli organi di amministrazione e direttivi, indicandone l’indirizzo di posta
|
||||||
|
elettronica certificata.
|
||||||
|
2. Le informazioni di cui al comma 1 sono confermate dal punto di contatto.
|
||||||
|
3. Ai fini dell’articolo 7, comma 4, lettera c), del decreto NIS, le persone fisiche appartenenti
|
||||||
|
agli organi di amministrazione e direttivi del soggetto NIS accettano tale indicazione
|
||||||
|
accedendo al Portale ACN, secondo la procedura telematica indicata nella richiesta inviata
|
||||||
|
a loro indirizzo di posta elettronica certificata di cui al comma 1.
|
||||||
|
Articolo 18
|
||||||
|
(Processo per l’aggiornamento continuo delle informazioni)
|
||||||
|
1. A seguito del perfezionamento dell’aggiornamento annuale, laddove siano sopravvenute
|
||||||
|
modifiche alle informazioni trasmesse ai sensi dell’articolo 16, tramite il “Servizio NIS/
|
||||||
|
Aggiornamento continuo informazioni” gli utenti forniscono le informazioni aggiornate per
|
||||||
|
conto del soggetto per cui operano, assicurandone la correttezza.
|
||||||
|
2. L’aggiornamento continuo delle informazioni è possibile fino al 14 aprile di ogni anno
|
||||||
|
successivo alla ricezione della comunicazione di cui all’articolo 7, comma 3, lettera a), del
|
||||||
|
decreto NIS.
|
||||||
|
3. Gli utenti designati quali punti di contatto confermano, ai sensi del decreto del Presidente
|
||||||
|
della Repubblica del 28 dicembre 2000, n. 445, le informazioni fornite e le trasmettono
|
||||||
|
telematicamente tramite il “Servizio NIS/Aggiornamento continuo informazioni”
|
||||||
|
all’Autorità nazionale competente NIS. Copia di tali informazioni, per ricevuta, è inviata al
|
||||||
|
domicilio digitale del soggetto.
|
||||||
|
4. La modifica, confermata da punto di contatto, dell’indicazione del rappresentante legale o
|
||||||
|
dell’elenco dei procuratori generali del soggetto NIS è sottoposta alla convalida del soggetto
|
||||||
|
medesimo, secondo la procedura telematica indicata nella richiesta inviata al domicilio
|
||||||
|
digitale di quest’ultimo.
|
||||||
|
5. Le modifiche dei dati anagrafici e di contatto del soggetto NIS sono trasmesse, per ricevuta,
|
||||||
|
al domicilio digitale di quest’ultimo.
|
||||||
|
6. Le modifiche dei dati anagrafici e di contatto degli utenti sono trasmesse, per ricevuta,
|
||||||
|
all’indirizzo di posta elettronica certificata indicata dall’utente stesso o, in subordine,
|
||||||
|
all’indirizzo di posta elettronica ordinaria indicata dall’utente stesso.
|
||||||
|
|
||||||
|
15 di 16
|
||||||
|
|
||||||
|
Agenzia per la Cybersicurezza Nazionale
|
||||||
|
Capo V
|
||||||
|
Disposizioni finali
|
||||||
|
Articolo 19
|
||||||
|
(Disposizioni finanziarie)
|
||||||
|
1. Agli oneri derivanti dalla presente determinazione, a carico dell’Autorità nazionale
|
||||||
|
competente NIS e delle Autorità di settore, si provvede, rispettivamente, con le risorse di
|
||||||
|
cui agli articoli 10 e 11 del decreto NIS.
|
||||||
|
|
||||||
|
Articolo 20
|
||||||
|
(Pubblicità)
|
||||||
|
1. La presente determinazione è pubblicata sul sito web e sui siti web istituzionali delle
|
||||||
|
Autorità di settore NIS e ne sarà data, altresì, comunicazione tramite pubblicazione nella
|
||||||
|
Gazzetta Ufficiale della Repubblica italiana.
|
||||||
|
Articolo 21
|
||||||
|
(Applicazione)
|
||||||
|
1. La presente determinazione aggiorna e sostituisce la determinazione ACN n. 333017 del 22
|
||||||
|
settembre 2025.
|
||||||
|
2. Per quanto non previsto dalla presente determinazione, si applicano le disposizioni del
|
||||||
|
decreto NIS.
|
||||||
|
3. La presente determinazione si applica a decorrere dal 31 dicembre 2025.
|
||||||
|
Roma, data del protocollo
|
||||||
|
IL DIRETTORE GENERALE
|
||||||
|
Bruno Frattasi
|
||||||
|
Bruno
|
||||||
|
Frattasi
|
||||||
|
18.12.2025
|
||||||
|
18:12:36
|
||||||
|
GMT+01:00
|
||||||
|
|
||||||
|
16 di 16
|
||||||
|
|
||||||
BIN
docs/nis2/Dir2022_2555_UE_NIS2_ITA.pdf
Normal file
BIN
docs/nis2/Dir2022_2555_UE_NIS2_ITA.pdf
Normal file
Binary file not shown.
4772
docs/nis2/Dir2022_2555_UE_NIS2_ITA.pdf.txt
Normal file
4772
docs/nis2/Dir2022_2555_UE_NIS2_ITA.pdf.txt
Normal file
File diff suppressed because it is too large
Load Diff
BIN
docs/nis2/Dir2022_2557_UE_ITA.pdf
Normal file
BIN
docs/nis2/Dir2022_2557_UE_ITA.pdf
Normal file
Binary file not shown.
2266
docs/nis2/Dir2022_2557_UE_ITA.pdf.txt
Normal file
2266
docs/nis2/Dir2022_2557_UE_ITA.pdf.txt
Normal file
File diff suppressed because it is too large
Load Diff
88
docs/nis2/INTEGRAZIONE_COMPLETATA.md
Normal file
88
docs/nis2/INTEGRAZIONE_COMPLETATA.md
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
# Integrazione analisi `docs/nis2/` → NIS2 Agile
|
||||||
|
|
||||||
|
> Data: 2026-05-29 (CEST) · Versione: v1.7.0 · Stato: **✅ DEPLOYATO ED ESEGUITO IN PRODUZIONE (Hetzner)**
|
||||||
|
|
||||||
|
## ✅ Eseguito in produzione (2026-05-29 ~17:06 CEST)
|
||||||
|
- **Codice**: live su `/var/www/nis2-agile` (stesso filesystem del container dev via bind mount → nessuno scp necessario). 5 nuovi endpoint verificati live (HTTP 401 auth, routing OK).
|
||||||
|
- **Migrazioni DB 020/021/022**: applicate e verificate (colonne assets/incidents + tabella `incident_pir` create).
|
||||||
|
- **Ingest KB**: **287 chunk** normativi indicizzati in Qdrant `nis2_kb` scope SYSTEM (171 NIS2 + 77 CER + 25 Det.333017 + 9 Det.164179 + 5 Ambiti). Retrieval verificato (query "preallarme CSIRT" → Direttiva NIS2; "settori alta criticità" → Ambiti Allegati I/II).
|
||||||
|
- **Backup**: `/root/backup_pre_v170_20260529_165447.sql`.
|
||||||
|
|
||||||
|
### ⚠️ Azione consigliata residua (richiede conferma — recreate container)
|
||||||
|
**Qdrant IP drift**: il container `nis2-qdrant` non ha IP statico in `docker-compose.yml` ed è driftato da `172.21.0.5` → `172.21.0.3`. Fallback in `VectorService.php` aggiornato a `.3` (live). Per evitare ricorrenze: in `docker/docker-compose.yml` assegnare `ipv4_address` statico al servizio `qdrant` e allineare `QDRANT_URL`, poi `docker compose up -d --force-recreate qdrant app`. NB: nota anche che `kb_uploaded_documents` non esiste su questo DB (migrazioni KB 012-014 non applicate qui) → il tracking MySQL dei doc KB è saltato (best-effort), ma la ricerca RAG legge da Qdrant e funziona.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Integrazione del materiale di analisi (mockup HTML + testi normativi PDF) nel prodotto NIS2 Agile.
|
||||||
|
Tutto il codice è scritto e lint-clean (`php -l` / `node --check`). **Le migrazioni DB e l'ingest KB
|
||||||
|
NON sono ancora stati eseguiti** (questo container dev non raggiunge il DB/Qdrant di produzione).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Cosa è stato implementato
|
||||||
|
|
||||||
|
### Fase 1 — Asset Relevance Scoring NIS2 (GV.OC-04)
|
||||||
|
Metodologia di scoring 0-100 su 6 criteri pesati, soglia rilevanza ≥40, classi critico/alto/medio/basso/trascurabile.
|
||||||
|
- `docs/sql/020_asset_relevance.sql` — colonne `relevance_score`, `relevance_criteria` (JSON), `relevance_class`, `is_nis2_relevant`, `relevance_assessed_at/by` + indice
|
||||||
|
- `application/services/AssetScoringService.php` — logica pura + griglia ufficiale in costante
|
||||||
|
- `application/controllers/AssetController.php` — `GET scoringGrid`, `POST {id}/score`, `GET relevantSystems`, filtro `nis2_relevant`
|
||||||
|
- `public/assets.html` — colonna "Rilevanza NIS2" + modale di valutazione a 6 criteri con anteprima punteggio
|
||||||
|
- `public/js/api.js` — `getScoringGrid`, `scoreAsset`, `listRelevantSystems`, `deleteAsset`
|
||||||
|
- Verifica: esempio ERP del mockup = **91/100 → critico** ✓
|
||||||
|
|
||||||
|
### Fase 2 — Tassonomia incidenti (Determina ACN 164179/2025)
|
||||||
|
- `docs/sql/021_incident_nis2_taxonomy.sql` — colonne `nis2_incident_type` ENUM(IS-1..IS-4), `entity_obligation` ENUM(essential/important)
|
||||||
|
- `application/controllers/IncidentController.php` — `create()` deriva il regime (Allegato 3 essenziali / Allegato 4 importanti) e blocca IS-4 per gli importanti
|
||||||
|
- `application/services/AIService.php` — `classifyIncident()` cita le fonti e restituisce `nis2_incident_type` + `notification_basis`
|
||||||
|
|
||||||
|
### Fase 3 — Post-Incident Review + metriche TTD/TTC/TTR
|
||||||
|
- `docs/sql/022_incident_metrics_pir.sql` — timestamp di fase (`triaged_at`, `contained_at`, `eradicated_at`, `recovered_at`) + tabella `incident_pir` (5-Whys, metriche, costo, lesson learned)
|
||||||
|
- `IncidentController.php` — `GET {id}/metrics`, `GET {id}/pir`, `POST {id}/pir`; `update()` timbra i timestamp di fase al cambio stato
|
||||||
|
- `public/js/api.js` — `getIncidentMetrics`, `getIncidentPir`, `saveIncidentPir`, `aiClassifyIncident`
|
||||||
|
|
||||||
|
### Fase 4 — Layer mapping NIST CSF 2.0 (reference, non invasivo)
|
||||||
|
- `application/controllers/AuditController.php` — `GET nistCsfMapping`: 43 controlli NIST CSF 2.0 → NIS2 Art.21/23 → modulo. **Nessuna migrazione**, nessuna modifica all'assessment esistente.
|
||||||
|
|
||||||
|
### Fonti normative certe (richiesta esplicita: AI + help citano fonti certe)
|
||||||
|
- `application/config/nis2_sources.php` — **registry canonico citabile** (Dir. 2022/2555, Dir. 2022/2557, D.Lgs. 138/2024, Determina ACN 164179/2025, Determina ACN 333017/2025, Ambiti NIS2)
|
||||||
|
- `application/services/AIService.php` — `authoritativeSourcesBlock()` iniettato nei system prompt (default, RAG, classifyIncident): impone di citare le fonti e vieta riferimenti inventati
|
||||||
|
- `public/js/help.js` — riferimenti normativi italiani aggiunti a incidenti e asset
|
||||||
|
- `scripts/ingest-nis2-sources.php` — indicizza i 5 PDF normativi nella KB (Qdrant `nis2_kb`, scope SYSTEM) per il grounding RAG
|
||||||
|
|
||||||
|
### Report
|
||||||
|
- `ReportService::generateRelevantSystemsRegister()` + `GET /api/audit/relevantSystemsRegister` — registro formale "Sistemi Rilevanti NIS2" (GV.OC-04) HTML stampabile con citazioni.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Deploy su Hetzner (da eseguire, in ordine — CHIEDERE CONFERMA UTENTE)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 0) Backup pre-migrazione
|
||||||
|
ssh -i docs/credentials/hetzner_key root@135.181.149.254
|
||||||
|
mysqldump nis2_agile_db assets incidents > /root/backup_pre_v170_$(date +%F).sql
|
||||||
|
|
||||||
|
# 1) Deploy codice (bind mount: PHP live; verificare path reale di produzione)
|
||||||
|
cd /var/www/nis2-agile && git pull origin main # dopo push su Gitea
|
||||||
|
|
||||||
|
# 2) Migrazioni DB (additive, idempotenti). NB: usare host MySQL, non docker exec nis2-db
|
||||||
|
mysql -h localhost nis2_agile_db -e "source /var/www/nis2-agile/docs/sql/020_asset_relevance.sql"
|
||||||
|
mysql -h localhost nis2_agile_db -e "source /var/www/nis2-agile/docs/sql/021_incident_nis2_taxonomy.sql"
|
||||||
|
mysql -h localhost nis2_agile_db -e "source /var/www/nis2-agile/docs/sql/022_incident_metrics_pir.sql"
|
||||||
|
|
||||||
|
# 3) Ingest fonti normative nella KB (richiede Qdrant + Voyage attivi)
|
||||||
|
docker exec -i nis2-app php /var/www/nis2-agile/scripts/ingest-nis2-sources.php --dry-run # verifica
|
||||||
|
docker exec -i nis2-app php /var/www/nis2-agile/scripts/ingest-nis2-sources.php # esegui
|
||||||
|
|
||||||
|
# 4) Smoke test
|
||||||
|
curl -s https://nis2.agile.software/api/assets/scoringGrid -H "Authorization: Bearer <jwt>" | head
|
||||||
|
```
|
||||||
|
|
||||||
|
### Rollback
|
||||||
|
Ogni `.sql` contiene la sezione ROLLBACK in coda. Per la KB: cancellare i chunk scope=SYSTEM/source=normativa o ripristinare la collection.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Note
|
||||||
|
- **Phase 4** è volutamente reference-only (nessuna tabella/migrazione) per non toccare l'assessment Art.21 consolidato.
|
||||||
|
- I PDF normativi restano in `docs/nis2/*.pdf` come libreria sorgente referenziata da `nis2_sources.php`.
|
||||||
|
- I file `*copy.html` e `incidente_r00/` dei mockup non sono stati usati (duplicati/superati).
|
||||||
2015
docs/nis2/assets.html
Normal file
2015
docs/nis2/assets.html
Normal file
File diff suppressed because it is too large
Load Diff
1481
docs/nis2/dashboard.html
Normal file
1481
docs/nis2/dashboard.html
Normal file
File diff suppressed because it is too large
Load Diff
450
docs/nis2/doc-network-physical.html
Normal file
450
docs/nis2/doc-network-physical.html
Normal file
@ -0,0 +1,450 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="it">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Diagramma Topologia Rete - NIS2</title>
|
||||||
|
<style>
|
||||||
|
:root {
|
||||||
|
--bg-primary: #ffffff;
|
||||||
|
--text-primary: #1a1a1a;
|
||||||
|
--text-secondary: #666666;
|
||||||
|
--border-color: #cccccc;
|
||||||
|
--accent-primary: #0066cc;
|
||||||
|
--zone-dmz: #fff3cd;
|
||||||
|
--zone-internal: #d1ecf1;
|
||||||
|
--zone-secure: #d4edda;
|
||||||
|
--zone-external: #f8d7da;
|
||||||
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
color: var(--text-primary);
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.document-container {
|
||||||
|
max-width: 297mm;
|
||||||
|
margin: 0 auto;
|
||||||
|
background-color: var(--bg-primary);
|
||||||
|
padding: 30px;
|
||||||
|
box-shadow: 0 0 20px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
text-align: center;
|
||||||
|
border-bottom: 3px solid var(--text-primary);
|
||||||
|
padding-bottom: 20px;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: var(--accent-primary);
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.doc-title {
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: bold;
|
||||||
|
margin: 15px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.doc-subtitle {
|
||||||
|
font-size: 12px;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.classification {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #d32f2f;
|
||||||
|
background-color: #ffebee;
|
||||||
|
padding: 10px;
|
||||||
|
border: 2px solid #d32f2f;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.diagram-container {
|
||||||
|
width: 100%;
|
||||||
|
background-color: #fafafa;
|
||||||
|
border: 2px solid var(--border-color);
|
||||||
|
padding: 30px;
|
||||||
|
margin: 20px 0;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.zone {
|
||||||
|
border: 2px dashed #333;
|
||||||
|
padding: 20px;
|
||||||
|
margin: 15px 0;
|
||||||
|
border-radius: 8px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.zone-label {
|
||||||
|
position: absolute;
|
||||||
|
top: -12px;
|
||||||
|
left: 20px;
|
||||||
|
background-color: var(--bg-primary);
|
||||||
|
padding: 0 10px;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.zone-external {
|
||||||
|
background-color: var(--zone-external);
|
||||||
|
border-color: #721c24;
|
||||||
|
}
|
||||||
|
|
||||||
|
.zone-dmz {
|
||||||
|
background-color: var(--zone-dmz);
|
||||||
|
border-color: #856404;
|
||||||
|
}
|
||||||
|
|
||||||
|
.zone-internal {
|
||||||
|
background-color: var(--zone-internal);
|
||||||
|
border-color: #004085;
|
||||||
|
}
|
||||||
|
|
||||||
|
.zone-secure {
|
||||||
|
background-color: var(--zone-secure);
|
||||||
|
border-color: #155724;
|
||||||
|
}
|
||||||
|
|
||||||
|
.device {
|
||||||
|
background-color: white;
|
||||||
|
border: 2px solid #333;
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 15px;
|
||||||
|
margin: 10px;
|
||||||
|
display: inline-block;
|
||||||
|
min-width: 150px;
|
||||||
|
text-align: center;
|
||||||
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.device-icon {
|
||||||
|
font-size: 32px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.device-name {
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 12px;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.device-ip {
|
||||||
|
font-size: 10px;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.device-code {
|
||||||
|
font-size: 9px;
|
||||||
|
color: var(--accent-primary);
|
||||||
|
font-family: monospace;
|
||||||
|
}
|
||||||
|
|
||||||
|
.connection {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 24px;
|
||||||
|
color: #333;
|
||||||
|
margin: 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legend {
|
||||||
|
margin-top: 30px;
|
||||||
|
padding: 20px;
|
||||||
|
background-color: #f9f9f9;
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legend-title {
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 14px;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
color: var(--accent-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.legend-item {
|
||||||
|
display: inline-block;
|
||||||
|
margin: 5px 15px 5px 0;
|
||||||
|
font-size: 11px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legend-color {
|
||||||
|
display: inline-block;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
border: 1px solid #333;
|
||||||
|
margin-right: 8px;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-box {
|
||||||
|
background-color: #e7f3ff;
|
||||||
|
border-left: 4px solid var(--accent-primary);
|
||||||
|
padding: 15px;
|
||||||
|
margin: 20px 0;
|
||||||
|
font-size: 11px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-box-title {
|
||||||
|
font-weight: bold;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-print {
|
||||||
|
position: fixed;
|
||||||
|
top: 20px;
|
||||||
|
right: 20px;
|
||||||
|
z-index: 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-print {
|
||||||
|
padding: 12px 24px;
|
||||||
|
background-color: var(--accent-primary);
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 14px;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-print:hover {
|
||||||
|
background-color: #0052a3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid-container {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
|
||||||
|
gap: 15px;
|
||||||
|
justify-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media print {
|
||||||
|
body {
|
||||||
|
background-color: white;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
.document-container {
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
.no-print {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="no-print">
|
||||||
|
<button class="btn-print" onclick="window.print()">🖨️ Stampa PDF</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="document-container">
|
||||||
|
<div class="classification">
|
||||||
|
⚠️ DOCUMENTO RISERVATO - SOLO PERSONALE AUTORIZZATO ⚠️
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="header">
|
||||||
|
<div class="logo">ACME CORPORATION S.p.A.</div>
|
||||||
|
<div class="doc-title">Diagramma Topologia Rete Fisica</div>
|
||||||
|
<div class="doc-subtitle">Versione 3.2 | Data: 15 Febbraio 2024 | Approvato da: CISO</div>
|
||||||
|
<div class="doc-subtitle">Documento ID.AM-03 - Requisito NIS2 (Solo Soggetti Essenziali)</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="info-box">
|
||||||
|
<div class="info-box-title">📋 Informazioni Documento</div>
|
||||||
|
<strong>Codice:</strong> NET-TOPO-PHY-v3.2 |
|
||||||
|
<strong>Ultima Modifica:</strong> 15/02/2024 |
|
||||||
|
<strong>Prossima Revisione:</strong> 15/05/2024 |
|
||||||
|
<strong>Classificazione:</strong> RISERVATO
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="diagram-container">
|
||||||
|
<!-- ZONA INTERNET -->
|
||||||
|
<div class="zone zone-external">
|
||||||
|
<div class="zone-label">🌐 INTERNET / ZONA ESTERNA</div>
|
||||||
|
<div style="text-align: center;">
|
||||||
|
<div class="device">
|
||||||
|
<div class="device-icon">🌍</div>
|
||||||
|
<div class="device-name">Internet</div>
|
||||||
|
<div class="device-ip">Pubblico</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="connection">⬇️ Connessione Fibra 1Gbps</div>
|
||||||
|
|
||||||
|
<!-- ZONA DMZ -->
|
||||||
|
<div class="zone zone-dmz">
|
||||||
|
<div class="zone-label">🛡️ DMZ (DeMilitarized Zone)</div>
|
||||||
|
|
||||||
|
<div class="grid-container">
|
||||||
|
<div class="device">
|
||||||
|
<div class="device-icon">🔥</div>
|
||||||
|
<div class="device-name">Firewall Perimetrale</div>
|
||||||
|
<div class="device-ip">10.10.0.1</div>
|
||||||
|
<div class="device-code">HW-NET-015</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="device">
|
||||||
|
<div class="device-icon">🌐</div>
|
||||||
|
<div class="device-name">Web Server Pubblico</div>
|
||||||
|
<div class="device-ip">10.10.2.45</div>
|
||||||
|
<div class="device-code">HW-SRV-023</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="device">
|
||||||
|
<div class="device-icon">📧</div>
|
||||||
|
<div class="device-name">Mail Gateway</div>
|
||||||
|
<div class="device-ip">10.10.2.50</div>
|
||||||
|
<div class="device-code">HW-SRV-028</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="device">
|
||||||
|
<div class="device-icon">🔐</div>
|
||||||
|
<div class="device-name">VPN Gateway</div>
|
||||||
|
<div class="device-ip">10.10.2.60</div>
|
||||||
|
<div class="device-code">HW-NET-018</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="connection">⬇️ VLAN Segmentation</div>
|
||||||
|
|
||||||
|
<!-- ZONA INTERNA -->
|
||||||
|
<div class="zone zone-internal">
|
||||||
|
<div class="zone-label">🏢 RETE INTERNA</div>
|
||||||
|
|
||||||
|
<div class="grid-container">
|
||||||
|
<div class="device">
|
||||||
|
<div class="device-icon">🔀</div>
|
||||||
|
<div class="device-name">Core Switch</div>
|
||||||
|
<div class="device-ip">10.10.1.1</div>
|
||||||
|
<div class="device-code">HW-NET-022</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="device">
|
||||||
|
<div class="device-icon">💻</div>
|
||||||
|
<div class="device-name">Workstation (x150)</div>
|
||||||
|
<div class="device-ip">10.20.x.x</div>
|
||||||
|
<div class="device-code">VLAN 20</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="device">
|
||||||
|
<div class="device-icon">🖨️</div>
|
||||||
|
<div class="device-name">Stampanti</div>
|
||||||
|
<div class="device-ip">10.30.x.x</div>
|
||||||
|
<div class="device-code">VLAN 30</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="device">
|
||||||
|
<div class="device-icon">📱</div>
|
||||||
|
<div class="device-name">WiFi Guest</div>
|
||||||
|
<div class="device-ip">10.40.x.x</div>
|
||||||
|
<div class="device-code">VLAN 40</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="connection">⬇️ Firewall Interno</div>
|
||||||
|
|
||||||
|
<!-- ZONA SICURA -->
|
||||||
|
<div class="zone zone-secure">
|
||||||
|
<div class="zone-label">🔒 DATACENTER / ZONA SICURA</div>
|
||||||
|
|
||||||
|
<div class="grid-container">
|
||||||
|
<div class="device">
|
||||||
|
<div class="device-icon">🖥️</div>
|
||||||
|
<div class="device-name">ERP Server</div>
|
||||||
|
<div class="device-ip">10.10.1.10</div>
|
||||||
|
<div class="device-code">HW-SRV-001</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="device">
|
||||||
|
<div class="device-icon">💾</div>
|
||||||
|
<div class="device-name">Database Server</div>
|
||||||
|
<div class="device-ip">10.10.1.20</div>
|
||||||
|
<div class="device-code">HW-SRV-012</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="device">
|
||||||
|
<div class="device-icon">📊</div>
|
||||||
|
<div class="device-name">SIEM Splunk</div>
|
||||||
|
<div class="device-ip">10.10.1.30</div>
|
||||||
|
<div class="device-code">HW-SRV-045</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="device">
|
||||||
|
<div class="device-icon">💿</div>
|
||||||
|
<div class="device-name">Backup Server</div>
|
||||||
|
<div class="device-ip">10.10.1.40</div>
|
||||||
|
<div class="device-code">HW-SRV-050</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="device">
|
||||||
|
<div class="device-icon">☁️</div>
|
||||||
|
<div class="device-name">VMware Cluster</div>
|
||||||
|
<div class="device-ip">10.10.1.50-55</div>
|
||||||
|
<div class="device-code">HW-SRV-060</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="device">
|
||||||
|
<div class="device-icon">🔐</div>
|
||||||
|
<div class="device-name">Active Directory</div>
|
||||||
|
<div class="device-ip">10.10.1.60</div>
|
||||||
|
<div class="device-code">HW-SRV-065</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="legend">
|
||||||
|
<div class="legend-title">📖 LEGENDA</div>
|
||||||
|
<div class="legend-item">
|
||||||
|
<span class="legend-color" style="background-color: var(--zone-external);"></span>
|
||||||
|
Zona Esterna (Internet)
|
||||||
|
</div>
|
||||||
|
<div class="legend-item">
|
||||||
|
<span class="legend-color" style="background-color: var(--zone-dmz);"></span>
|
||||||
|
DMZ (Servizi Esposti)
|
||||||
|
</div>
|
||||||
|
<div class="legend-item">
|
||||||
|
<span class="legend-color" style="background-color: var(--zone-internal);"></span>
|
||||||
|
Rete Interna (Utenti)
|
||||||
|
</div>
|
||||||
|
<div class="legend-item">
|
||||||
|
<span class="legend-color" style="background-color: var(--zone-secure);"></span>
|
||||||
|
Datacenter (Sistemi Critici)
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="info-box">
|
||||||
|
<div class="info-box-title">🔐 Note di Sicurezza</div>
|
||||||
|
• Tutti i flussi tra zone sono controllati da firewall con regole whitelist<br>
|
||||||
|
• Monitoraggio 24/7 tramite SIEM centralizzato (Splunk)<br>
|
||||||
|
• Segmentazione VLAN per separazione logica dei servizi<br>
|
||||||
|
• Backup giornaliero con replica off-site<br>
|
||||||
|
• Accesso datacenter con autenticazione biometrica e logging<br>
|
||||||
|
• Aggiornamento obbligatorio entro 5 giorni da modifiche infrastrutturali
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="margin-top: 40px; padding-top: 20px; border-top: 2px solid var(--border-color); text-align: center; font-size: 10px; color: var(--text-secondary);">
|
||||||
|
Documento NET-TOPO-PHY-v3.2 - RISERVATO - Pagina 1 di 1
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
482
docs/nis2/doc-relevant-systems.html
Normal file
482
docs/nis2/doc-relevant-systems.html
Normal file
@ -0,0 +1,482 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="it">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Documento Formale - Sistemi Rilevanti NIS2</title>
|
||||||
|
<style>
|
||||||
|
:root {
|
||||||
|
--bg-primary: #ffffff;
|
||||||
|
--text-primary: #1a1a1a;
|
||||||
|
--text-secondary: #666666;
|
||||||
|
--border-color: #cccccc;
|
||||||
|
--accent-primary: #0066cc;
|
||||||
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: 'Times New Roman', Times, serif;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
color: var(--text-primary);
|
||||||
|
line-height: 1.6;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.document-container {
|
||||||
|
max-width: 210mm;
|
||||||
|
margin: 0 auto;
|
||||||
|
background-color: var(--bg-primary);
|
||||||
|
padding: 40mm 25mm;
|
||||||
|
box-shadow: 0 0 20px rgba(0, 0, 0, 0.1);
|
||||||
|
min-height: 297mm;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
text-align: center;
|
||||||
|
border-bottom: 3px solid var(--text-primary);
|
||||||
|
padding-bottom: 20px;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: var(--accent-primary);
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.doc-title {
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: bold;
|
||||||
|
margin: 20px 0 10px 0;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.doc-subtitle {
|
||||||
|
font-size: 14px;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.doc-info {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
gap: 10px;
|
||||||
|
margin: 30px 0;
|
||||||
|
padding: 15px;
|
||||||
|
background-color: #f9f9f9;
|
||||||
|
border-left: 4px solid var(--accent-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.doc-info-item {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.doc-info-label {
|
||||||
|
font-weight: bold;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.section {
|
||||||
|
margin: 30px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: var(--accent-primary);
|
||||||
|
border-bottom: 2px solid var(--border-color);
|
||||||
|
padding-bottom: 5px;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-content {
|
||||||
|
font-size: 12px;
|
||||||
|
text-align: justify;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
margin: 20px 0;
|
||||||
|
font-size: 11px;
|
||||||
|
}
|
||||||
|
|
||||||
|
th {
|
||||||
|
background-color: #e8e8e8;
|
||||||
|
padding: 10px 8px;
|
||||||
|
text-align: left;
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
td {
|
||||||
|
padding: 8px;
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
tr:nth-child(even) {
|
||||||
|
background-color: #f9f9f9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.critical {
|
||||||
|
color: #d32f2f;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.high {
|
||||||
|
color: #f57c00;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.medium {
|
||||||
|
color: #388e3c;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
margin-top: 50px;
|
||||||
|
padding-top: 20px;
|
||||||
|
border-top: 2px solid var(--border-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.signature-block {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
gap: 40px;
|
||||||
|
margin-top: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.signature {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.signature-line {
|
||||||
|
border-top: 1px solid var(--text-primary);
|
||||||
|
margin-top: 60px;
|
||||||
|
padding-top: 10px;
|
||||||
|
font-size: 11px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.signature-role {
|
||||||
|
font-size: 10px;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-number {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 10px;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
margin-top: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.classification {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #d32f2f;
|
||||||
|
background-color: #ffebee;
|
||||||
|
padding: 10px;
|
||||||
|
border: 2px solid #d32f2f;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media print {
|
||||||
|
body {
|
||||||
|
background-color: white;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
.document-container {
|
||||||
|
box-shadow: none;
|
||||||
|
padding: 20mm 15mm;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-print {
|
||||||
|
position: fixed;
|
||||||
|
top: 20px;
|
||||||
|
right: 20px;
|
||||||
|
z-index: 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-print {
|
||||||
|
padding: 12px 24px;
|
||||||
|
background-color: var(--accent-primary);
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 14px;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-print:hover {
|
||||||
|
background-color: #0052a3;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="no-print">
|
||||||
|
<button class="btn-print" onclick="window.print()">🖨️ Stampa PDF</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="document-container">
|
||||||
|
<div class="classification">
|
||||||
|
⚠️ DOCUMENTO RISERVATO - DISTRIBUZIONE LIMITATA ⚠️
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="header">
|
||||||
|
<div class="logo">ACME CORPORATION S.p.A.</div>
|
||||||
|
<div class="doc-title">Elenco Sistemi Rilevanti NIS2</div>
|
||||||
|
<div class="doc-subtitle">Documento Formale ai sensi della Direttiva (UE) 2022/2555</div>
|
||||||
|
<div class="doc-subtitle">Requisito GV.OC-04</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="doc-info">
|
||||||
|
<div class="doc-info-item">
|
||||||
|
<span class="doc-info-label">Codice Documento:</span> NIS2-GV-OC-04-v2.3
|
||||||
|
</div>
|
||||||
|
<div class="doc-info-item">
|
||||||
|
<span class="doc-info-label">Data Emissione:</span> 15 Febbraio 2024
|
||||||
|
</div>
|
||||||
|
<div class="doc-info-item">
|
||||||
|
<span class="doc-info-label">Versione:</span> 2.3
|
||||||
|
</div>
|
||||||
|
<div class="doc-info-item">
|
||||||
|
<span class="doc-info-label">Prossima Revisione:</span> 15 Agosto 2024
|
||||||
|
</div>
|
||||||
|
<div class="doc-info-item">
|
||||||
|
<span class="doc-info-label">Redatto da:</span> CISO - Marco Bianchi
|
||||||
|
</div>
|
||||||
|
<div class="doc-info-item">
|
||||||
|
<span class="doc-info-label">Approvato da:</span> CdA - Delibera 05/2024
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="section">
|
||||||
|
<div class="section-title">1. PREMESSA</div>
|
||||||
|
<div class="section-content">
|
||||||
|
Il presente documento costituisce l'elenco formale dei sistemi classificati come rilevanti ai fini della conformità alla Direttiva NIS2 (UE) 2022/2555 e al relativo decreto di recepimento nazionale. La classificazione è stata effettuata secondo la metodologia di scoring approvata dal Consiglio di Amministrazione in data 10 Gennaio 2024, basata su sei criteri di valutazione con punteggio massimo di 100 punti.
|
||||||
|
</div>
|
||||||
|
<div class="section-content">
|
||||||
|
<strong>Soglia di Rilevanza:</strong> Sono considerati rilevanti tutti i sistemi con punteggio ≥ 40 punti.<br>
|
||||||
|
<strong>Sistemi Critici:</strong> Sistemi con punteggio ≥ 80 punti richiedono misure di sicurezza massime e monitoraggio continuo 24/7.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="section">
|
||||||
|
<div class="section-title">2. RIEPILOGO STATISTICO</div>
|
||||||
|
<div class="section-content">
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th>Categoria</th>
|
||||||
|
<th>Range Punteggio</th>
|
||||||
|
<th>Numero Sistemi</th>
|
||||||
|
<th>Percentuale</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><span class="critical">CRITICO</span></td>
|
||||||
|
<td>80-100</td>
|
||||||
|
<td>12</td>
|
||||||
|
<td>31.6%</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><span class="high">ALTO</span></td>
|
||||||
|
<td>60-79</td>
|
||||||
|
<td>15</td>
|
||||||
|
<td>39.5%</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><span class="medium">MEDIO</span></td>
|
||||||
|
<td>40-59</td>
|
||||||
|
<td>11</td>
|
||||||
|
<td>28.9%</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>TOTALE RILEVANTI</strong></td>
|
||||||
|
<td>≥40</td>
|
||||||
|
<td><strong>38</strong></td>
|
||||||
|
<td><strong>100%</strong></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="section">
|
||||||
|
<div class="section-title">3. ELENCO SISTEMI CRITICI (≥80 PUNTI)</div>
|
||||||
|
<div class="section-content">
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th>Codice</th>
|
||||||
|
<th>Nome Sistema</th>
|
||||||
|
<th>Tipo</th>
|
||||||
|
<th>Punteggio</th>
|
||||||
|
<th>RTO/RPO</th>
|
||||||
|
<th>Monitoraggio</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>SW-ERP-001</td>
|
||||||
|
<td>SAP ERP</td>
|
||||||
|
<td>Software</td>
|
||||||
|
<td class="critical">95</td>
|
||||||
|
<td>4h / 1h</td>
|
||||||
|
<td>24/7</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>SVC-001</td>
|
||||||
|
<td>Piattaforma ERP Cloud</td>
|
||||||
|
<td>Servizio</td>
|
||||||
|
<td class="critical">94</td>
|
||||||
|
<td>4h / 1h</td>
|
||||||
|
<td>24/7</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>SW-SEC-008</td>
|
||||||
|
<td>Splunk SIEM</td>
|
||||||
|
<td>Software</td>
|
||||||
|
<td class="critical">92</td>
|
||||||
|
<td>4h / 4h</td>
|
||||||
|
<td>24/7</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>HW-SRV-001</td>
|
||||||
|
<td>ERP-PROD-01</td>
|
||||||
|
<td>Hardware</td>
|
||||||
|
<td class="critical">91</td>
|
||||||
|
<td>4h / 1h</td>
|
||||||
|
<td>24/7</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>SW-DB-003</td>
|
||||||
|
<td>Oracle Database</td>
|
||||||
|
<td>Software</td>
|
||||||
|
<td class="critical">89</td>
|
||||||
|
<td>4h / 1h</td>
|
||||||
|
<td>24/7</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>HW-NET-015</td>
|
||||||
|
<td>FW-PERIMETRALE-01</td>
|
||||||
|
<td>Hardware</td>
|
||||||
|
<td class="critical">88</td>
|
||||||
|
<td>1h / N/A</td>
|
||||||
|
<td>24/7</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>SVC-002</td>
|
||||||
|
<td>Hosting Applicazioni</td>
|
||||||
|
<td>Servizio</td>
|
||||||
|
<td class="critical">88</td>
|
||||||
|
<td>8h / 4h</td>
|
||||||
|
<td>24/7</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>CLD-IAAS-001</td>
|
||||||
|
<td>VM Production AWS</td>
|
||||||
|
<td>Cloud</td>
|
||||||
|
<td class="critical">87</td>
|
||||||
|
<td>4h / 1h</td>
|
||||||
|
<td>24/7</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>CLD-PAAS-003</td>
|
||||||
|
<td>Azure SQL Database</td>
|
||||||
|
<td>Cloud</td>
|
||||||
|
<td class="critical">85</td>
|
||||||
|
<td>4h / 1h</td>
|
||||||
|
<td>24/7</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>HW-NET-022</td>
|
||||||
|
<td>Core Switch Datacenter</td>
|
||||||
|
<td>Hardware</td>
|
||||||
|
<td class="critical">84</td>
|
||||||
|
<td>2h / N/A</td>
|
||||||
|
<td>24/7</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>SW-BACKUP-001</td>
|
||||||
|
<td>Veeam Backup System</td>
|
||||||
|
<td>Software</td>
|
||||||
|
<td class="critical">82</td>
|
||||||
|
<td>24h / 24h</td>
|
||||||
|
<td>24/7</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>HW-SRV-012</td>
|
||||||
|
<td>DB-PROD-01</td>
|
||||||
|
<td>Hardware</td>
|
||||||
|
<td class="critical">80</td>
|
||||||
|
<td>4h / 1h</td>
|
||||||
|
<td>24/7</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="section">
|
||||||
|
<div class="section-title">4. MISURE DI SICUREZZA OBBLIGATORIE</div>
|
||||||
|
<div class="section-content">
|
||||||
|
Per tutti i sistemi rilevanti sono implementate le seguenti misure minime di sicurezza:
|
||||||
|
<ul style="margin-left: 20px; margin-top: 10px;">
|
||||||
|
<li>Backup giornaliero con retention minima 30 giorni</li>
|
||||||
|
<li>Patch management con SLA massimo 30 giorni per vulnerabilità critiche</li>
|
||||||
|
<li>Logging centralizzato su SIEM con retention 12 mesi</li>
|
||||||
|
<li>Controllo accessi con autenticazione multi-fattore (MFA)</li>
|
||||||
|
<li>Monitoraggio continuo con alerting automatico</li>
|
||||||
|
<li>Business Continuity Plan e Disaster Recovery Plan documentati e testati</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="section-content">
|
||||||
|
<strong>Sistemi Critici (≥80):</strong> Oltre alle misure sopra elencate, richiedono ridondanza hardware/software, monitoraggio 24/7 con reperibilità H24, test DR semestrali e revisione trimestrale delle configurazioni di sicurezza.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="section">
|
||||||
|
<div class="section-title">5. REVISIONE E AGGIORNAMENTO</div>
|
||||||
|
<div class="section-content">
|
||||||
|
Il presente documento è soggetto a revisione semestrale obbligatoria. Revisioni straordinarie sono richieste in caso di:
|
||||||
|
<ul style="margin-left: 20px; margin-top: 10px;">
|
||||||
|
<li>Introduzione di nuovi sistemi con punteggio ≥40</li>
|
||||||
|
<li>Modifiche sostanziali ai sistemi esistenti che ne alterano il punteggio</li>
|
||||||
|
<li>Incidenti di sicurezza significativi</li>
|
||||||
|
<li>Cambiamenti normativi rilevanti</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="footer">
|
||||||
|
<div class="section-title">APPROVAZIONE</div>
|
||||||
|
<div class="section-content">
|
||||||
|
Il presente documento è stato approvato dal Consiglio di Amministrazione in data 15 Febbraio 2024 con Delibera n. 05/2024 e costituisce documento ufficiale ai fini della conformità NIS2.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="signature-block">
|
||||||
|
<div class="signature">
|
||||||
|
<div class="signature-line">
|
||||||
|
<strong>Marco Bianchi</strong><br>
|
||||||
|
<span class="signature-role">Chief Information Security Officer (CISO)</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="signature">
|
||||||
|
<div class="signature-line">
|
||||||
|
<strong>Giovanni Rossi</strong><br>
|
||||||
|
<span class="signature-role">Amministratore Delegato</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="page-number">
|
||||||
|
Pagina 1 di 1 - Documento NIS2-GV-OC-04-v2.3 - RISERVATO
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
1402
docs/nis2/incidente_r01/incident-dashboard.html
Normal file
1402
docs/nis2/incidente_r01/incident-dashboard.html
Normal file
File diff suppressed because it is too large
Load Diff
1805
docs/nis2/incidente_r01/incident-detail.html
Normal file
1805
docs/nis2/incidente_r01/incident-detail.html
Normal file
File diff suppressed because it is too large
Load Diff
353
docs/nis2/incidente_r01/incident-gate.html
Normal file
353
docs/nis2/incidente_r01/incident-gate.html
Normal file
@ -0,0 +1,353 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="it">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Accesso Sistema Gestione Incidenti - NIS2</title>
|
||||||
|
<style>
|
||||||
|
:root {
|
||||||
|
--bg-primary: #0d1117;
|
||||||
|
--bg-secondary: #161b22;
|
||||||
|
--bg-tertiary: #1c2128;
|
||||||
|
--border-color: #30363d;
|
||||||
|
--text-primary: #c9d1d9;
|
||||||
|
--text-secondary: #8b949e;
|
||||||
|
--accent-primary: #58a6ff;
|
||||||
|
--accent-secondary: #1f6feb;
|
||||||
|
--success: #3fb950;
|
||||||
|
--warning: #d29922;
|
||||||
|
--danger: #f85149;
|
||||||
|
--essential-bg: #fef3c7;
|
||||||
|
--essential-text: #92400e;
|
||||||
|
--essential-border: #f59e0b;
|
||||||
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Noto Sans', Helvetica, Arial, sans-serif;
|
||||||
|
background-color: var(--bg-primary);
|
||||||
|
color: var(--text-primary);
|
||||||
|
line-height: 1.6;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
min-height: 100vh;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gate-container {
|
||||||
|
max-width: 900px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gate-header {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 48px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gate-header h1 {
|
||||||
|
font-size: 32px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: var(--text-primary);
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gate-header p {
|
||||||
|
font-size: 16px;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.warning-box {
|
||||||
|
background-color: rgba(210, 153, 34, 0.1);
|
||||||
|
border: 2px solid var(--warning);
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 24px;
|
||||||
|
margin-bottom: 48px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.warning-box-title {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--warning);
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.warning-icon {
|
||||||
|
font-size: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.warning-box-content {
|
||||||
|
font-size: 14px;
|
||||||
|
color: var(--text-primary);
|
||||||
|
line-height: 1.8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selection-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
|
||||||
|
gap: 24px;
|
||||||
|
margin-bottom: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selection-card {
|
||||||
|
background-color: var(--bg-secondary);
|
||||||
|
border: 2px solid var(--border-color);
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 32px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selection-card::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
height: 4px;
|
||||||
|
background: linear-gradient(90deg, var(--accent-primary), var(--accent-secondary));
|
||||||
|
transform: scaleX(0);
|
||||||
|
transition: transform 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selection-card:hover {
|
||||||
|
border-color: var(--accent-primary);
|
||||||
|
transform: translateY(-4px);
|
||||||
|
box-shadow: 0 8px 24px rgba(88, 166, 255, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.selection-card:hover::before {
|
||||||
|
transform: scaleX(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.selection-card.essential {
|
||||||
|
border-color: var(--essential-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
.selection-card.essential:hover {
|
||||||
|
border-color: var(--essential-border);
|
||||||
|
box-shadow: 0 8px 24px rgba(245, 158, 11, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.selection-card.essential::before {
|
||||||
|
background: linear-gradient(90deg, var(--essential-border), var(--warning));
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-badge {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 6px 12px;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: 700;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.5px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge-important {
|
||||||
|
background-color: rgba(88, 166, 255, 0.2);
|
||||||
|
color: var(--accent-primary);
|
||||||
|
border: 1px solid var(--accent-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge-essential {
|
||||||
|
background-color: var(--essential-bg);
|
||||||
|
color: var(--essential-text);
|
||||||
|
border: 1px solid var(--essential-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-title {
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text-primary);
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-description {
|
||||||
|
font-size: 14px;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
line-height: 1.6;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-features {
|
||||||
|
list-style: none;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-features li {
|
||||||
|
font-size: 13px;
|
||||||
|
color: var(--text-primary);
|
||||||
|
padding: 8px 0;
|
||||||
|
padding-left: 24px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-features li::before {
|
||||||
|
content: '✓';
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
color: var(--success);
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-button {
|
||||||
|
width: 100%;
|
||||||
|
padding: 14px 24px;
|
||||||
|
background-color: var(--bg-tertiary);
|
||||||
|
border: 2px solid var(--accent-primary);
|
||||||
|
border-radius: 6px;
|
||||||
|
color: var(--accent-primary);
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 600;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-button:hover {
|
||||||
|
background-color: var(--accent-primary);
|
||||||
|
color: var(--bg-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.selection-card.essential .card-button {
|
||||||
|
border-color: var(--essential-border);
|
||||||
|
color: var(--essential-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
.selection-card.essential .card-button:hover {
|
||||||
|
background-color: var(--essential-border);
|
||||||
|
color: var(--bg-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-note {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 13px;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
padding: 24px;
|
||||||
|
background-color: var(--bg-secondary);
|
||||||
|
border-radius: 6px;
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-note strong {
|
||||||
|
color: var(--text-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.selection-grid {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gate-header h1 {
|
||||||
|
font-size: 24px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="gate-container">
|
||||||
|
<div class="gate-header">
|
||||||
|
<h1>Sistema Gestione Incidenti NIS2</h1>
|
||||||
|
<p>Seleziona la tipologia del tuo soggetto per accedere alle funzionalità appropriate</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="warning-box">
|
||||||
|
<div class="warning-box-title">
|
||||||
|
<span class="warning-icon">⚠️</span>
|
||||||
|
Accesso Obbligatorio
|
||||||
|
</div>
|
||||||
|
<div class="warning-box-content">
|
||||||
|
<strong>La conformità alla gestione incidenti è obbligatoria per TUTTI i soggetti NIS2</strong> (essenziali e importanti). La differenza sta nei tipi di incidenti da segnalare e nelle tempistiche, come definito negli Allegati 3 (soggetti essenziali) e 4 (soggetti importanti) della Determina 164179/2025.
|
||||||
|
<br><br>
|
||||||
|
Seleziona la categoria corretta per visualizzare solo i requisiti applicabili alla tua organizzazione.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="selection-grid">
|
||||||
|
<div class="selection-card" onclick="selectType('important')">
|
||||||
|
<span class="card-badge badge-important">Soggetto Importante</span>
|
||||||
|
<h2 class="card-title">Soggetto Importante</h2>
|
||||||
|
<p class="card-description">
|
||||||
|
Organizzazioni che rientrano nella categoria "importanti" secondo il D.Lgs. 138/2024, con obblighi di notifica per incidenti significativi secondo Allegato 4.
|
||||||
|
</p>
|
||||||
|
<ul class="card-features">
|
||||||
|
<li>Notifica incidenti IS-1, IS-2, IS-3</li>
|
||||||
|
<li>Preallarme entro 24 ore</li>
|
||||||
|
<li>Notifica completa entro 72 ore</li>
|
||||||
|
<li>Relazione finale entro 1 mese</li>
|
||||||
|
<li>Gestione incidenti ricorrenti (IS-4) non obbligatoria</li>
|
||||||
|
</ul>
|
||||||
|
<button class="card-button">Accedi come Soggetto Importante</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="selection-card essential" onclick="selectType('essential')">
|
||||||
|
<span class="card-badge badge-essential">Soggetto Essenziale</span>
|
||||||
|
<h2 class="card-title">Soggetto Essenziale</h2>
|
||||||
|
<p class="card-description">
|
||||||
|
Organizzazioni che rientrano nella categoria "essenziali" secondo il D.Lgs. 138/2024, con obblighi estesi di notifica per incidenti significativi secondo Allegato 3.
|
||||||
|
</p>
|
||||||
|
<ul class="card-features">
|
||||||
|
<li>Notifica incidenti IS-1, IS-2, IS-3, IS-4</li>
|
||||||
|
<li>Preallarme entro 24 ore</li>
|
||||||
|
<li>Notifica completa entro 72 ore</li>
|
||||||
|
<li>Relazione finale entro 1 mese</li>
|
||||||
|
<li>Gestione incidenti ricorrenti (IS-4) obbligatoria</li>
|
||||||
|
<li>Monitoraggio 24/7 richiesto</li>
|
||||||
|
</ul>
|
||||||
|
<button class="card-button">Accedi come Soggetto Essenziale</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="footer-note">
|
||||||
|
<strong>Riferimenti normativi:</strong> D.Lgs. 138/2024 (Direttiva NIS2), Determina ACN 164179/2025 (Allegati 3 e 4)<br>
|
||||||
|
<strong>Requisiti NIS2 coperti:</strong> RS.MA-01 (Gestione Incidenti), RS.CO-02 (Notifiche), RC.RP-01 (Ripristino), RC.CO-03 (Comunicazioni)
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function selectType(type) {
|
||||||
|
// Salva la selezione in sessionStorage
|
||||||
|
sessionStorage.setItem('nis2_subject_type', type);
|
||||||
|
|
||||||
|
// Reindirizza alla dashboard
|
||||||
|
window.location.href = 'incident-dashboard.html';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verifica se c'è già una selezione
|
||||||
|
window.addEventListener('DOMContentLoaded', function() {
|
||||||
|
const savedType = sessionStorage.getItem('nis2_subject_type');
|
||||||
|
if (savedType) {
|
||||||
|
// Mostra un messaggio che sta caricando
|
||||||
|
const container = document.querySelector('.gate-container');
|
||||||
|
container.innerHTML = `
|
||||||
|
<div style="text-align: center; padding: 60px 20px;">
|
||||||
|
<h2 style="font-size: 24px; margin-bottom: 16px;">Accesso già configurato</h2>
|
||||||
|
<p style="color: var(--text-secondary); margin-bottom: 24px;">
|
||||||
|
Sei configurato come: <strong style="color: var(--text-primary);">${savedType === 'essential' ? 'Soggetto Essenziale' : 'Soggetto Importante'}</strong>
|
||||||
|
</p>
|
||||||
|
<button onclick="window.location.href='incident-dashboard.html'"
|
||||||
|
style="padding: 12px 24px; background-color: var(--accent-primary); border: none; border-radius: 6px; color: white; font-weight: 600; cursor: pointer; margin-right: 12px;">
|
||||||
|
Vai alla Dashboard
|
||||||
|
</button>
|
||||||
|
<button onclick="sessionStorage.removeItem('nis2_subject_type'); location.reload();"
|
||||||
|
style="padding: 12px 24px; background-color: var(--bg-tertiary); border: 1px solid var(--border-color); border-radius: 6px; color: var(--text-primary); font-weight: 600; cursor: pointer;">
|
||||||
|
Cambia Selezione
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
956
docs/nis2/incidente_r01/incident-new.html
Normal file
956
docs/nis2/incidente_r01/incident-new.html
Normal file
@ -0,0 +1,956 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="it">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Nuovo Incidente - NIS2 Management System</title>
|
||||||
|
<style>
|
||||||
|
:root {
|
||||||
|
--bg-primary: #0d1117;
|
||||||
|
--bg-secondary: #161b22;
|
||||||
|
--bg-tertiary: #1c2128;
|
||||||
|
--border-color: #30363d;
|
||||||
|
--text-primary: #c9d1d9;
|
||||||
|
--text-secondary: #8b949e;
|
||||||
|
--accent-primary: #58a6ff;
|
||||||
|
--accent-secondary: #1f6feb;
|
||||||
|
--success: #3fb950;
|
||||||
|
--warning: #d29922;
|
||||||
|
--danger: #f85149;
|
||||||
|
--essential-bg: #fef3c7;
|
||||||
|
--essential-text: #92400e;
|
||||||
|
--essential-border: #f59e0b;
|
||||||
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Noto Sans', Helvetica, Arial, sans-serif;
|
||||||
|
background-color: var(--bg-primary);
|
||||||
|
color: var(--text-primary);
|
||||||
|
line-height: 1.6;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 1200px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
background-color: var(--bg-secondary);
|
||||||
|
border-bottom: 1px solid var(--border-color);
|
||||||
|
padding: 24px 0;
|
||||||
|
margin-bottom: 32px;
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
z-index: 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-content {
|
||||||
|
max-width: 1200px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0 20px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header h1 {
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.breadcrumb {
|
||||||
|
font-size: 13px;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
margin-top: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.breadcrumb a {
|
||||||
|
color: var(--accent-primary);
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
padding: 8px 16px;
|
||||||
|
background-color: var(--bg-tertiary);
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
border-radius: 6px;
|
||||||
|
color: var(--text-primary);
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 500;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn:hover {
|
||||||
|
border-color: var(--accent-primary);
|
||||||
|
color: var(--accent-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-section {
|
||||||
|
background-color: var(--bg-secondary);
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 24px;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-section-title {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text-primary);
|
||||||
|
margin-bottom: 20px;
|
||||||
|
padding-bottom: 12px;
|
||||||
|
border-bottom: 1px solid var(--border-color);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.help-icon {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 22px;
|
||||||
|
height: 22px;
|
||||||
|
background-color: rgba(167, 139, 250, 0.2);
|
||||||
|
border: 2px solid #a78bfa;
|
||||||
|
border-radius: 50%;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #a78bfa;
|
||||||
|
cursor: help;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.help-icon:hover {
|
||||||
|
background-color: rgba(167, 139, 250, 0.3);
|
||||||
|
transform: scale(1.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tooltip {
|
||||||
|
visibility: hidden;
|
||||||
|
position: absolute;
|
||||||
|
z-index: 1000;
|
||||||
|
background-color: var(--bg-tertiary);
|
||||||
|
color: var(--text-primary);
|
||||||
|
padding: 12px;
|
||||||
|
border-radius: 6px;
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
|
||||||
|
width: 320px;
|
||||||
|
top: 28px;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 1.5;
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.2s;
|
||||||
|
white-space: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tooltip::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: -6px;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
border-left: 6px solid transparent;
|
||||||
|
border-right: 6px solid transparent;
|
||||||
|
border-bottom: 6px solid var(--border-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tooltip-title {
|
||||||
|
color: var(--accent-primary);
|
||||||
|
font-weight: 600;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
font-size: 11px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.help-icon:hover .tooltip {
|
||||||
|
visibility: visible;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||||||
|
gap: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group.full-width {
|
||||||
|
grid-column: 1 / -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-label {
|
||||||
|
display: block;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text-primary);
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-label .required {
|
||||||
|
color: var(--danger);
|
||||||
|
margin-left: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-input, .form-select, .form-textarea {
|
||||||
|
width: 100%;
|
||||||
|
padding: 10px 12px;
|
||||||
|
background-color: var(--bg-tertiary);
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
border-radius: 6px;
|
||||||
|
color: var(--text-primary);
|
||||||
|
font-size: 14px;
|
||||||
|
font-family: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-input:focus, .form-select:focus, .form-textarea:focus {
|
||||||
|
outline: none;
|
||||||
|
border-color: var(--accent-primary);
|
||||||
|
box-shadow: 0 0 0 3px rgba(88, 166, 255, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-textarea {
|
||||||
|
resize: vertical;
|
||||||
|
min-height: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-help {
|
||||||
|
font-size: 12px;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
margin-top: 6px;
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.severity-selector {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.severity-option {
|
||||||
|
padding: 16px;
|
||||||
|
background-color: var(--bg-tertiary);
|
||||||
|
border: 2px solid var(--border-color);
|
||||||
|
border-radius: 6px;
|
||||||
|
cursor: pointer;
|
||||||
|
text-align: center;
|
||||||
|
transition: all 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.severity-option:hover {
|
||||||
|
border-color: var(--accent-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.severity-option.selected {
|
||||||
|
border-color: var(--accent-primary);
|
||||||
|
background-color: rgba(88, 166, 255, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.severity-option.sev-1 {
|
||||||
|
border-color: var(--danger);
|
||||||
|
}
|
||||||
|
|
||||||
|
.severity-option.sev-1.selected {
|
||||||
|
background-color: rgba(248, 81, 73, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.severity-option.sev-2 {
|
||||||
|
border-color: var(--warning);
|
||||||
|
}
|
||||||
|
|
||||||
|
.severity-option.sev-2.selected {
|
||||||
|
background-color: rgba(210, 153, 34, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.severity-label {
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 14px;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.severity-desc {
|
||||||
|
font-size: 11px;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert-box {
|
||||||
|
background-color: rgba(88, 166, 255, 0.1);
|
||||||
|
border: 1px solid var(--accent-primary);
|
||||||
|
border-left: 4px solid var(--accent-primary);
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 16px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert-box.warning {
|
||||||
|
background-color: rgba(210, 153, 34, 0.1);
|
||||||
|
border-color: var(--warning);
|
||||||
|
border-left-color: var(--warning);
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert-box.danger {
|
||||||
|
background-color: rgba(248, 81, 73, 0.1);
|
||||||
|
border-color: var(--danger);
|
||||||
|
border-left-color: var(--danger);
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert-title {
|
||||||
|
font-weight: 600;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert-content {
|
||||||
|
font-size: 13px;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 12px;
|
||||||
|
justify-content: flex-end;
|
||||||
|
padding-top: 24px;
|
||||||
|
border-top: 1px solid var(--border-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary {
|
||||||
|
background-color: var(--accent-primary);
|
||||||
|
border-color: var(--accent-primary);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary:hover {
|
||||||
|
background-color: var(--accent-secondary);
|
||||||
|
border-color: var(--accent-secondary);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-danger {
|
||||||
|
background-color: var(--danger);
|
||||||
|
border-color: var(--danger);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-danger:hover {
|
||||||
|
background-color: #dc2626;
|
||||||
|
border-color: #dc2626;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checklist {
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checklist li {
|
||||||
|
padding: 10px;
|
||||||
|
background-color: var(--bg-tertiary);
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
border-radius: 4px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checklist input[type="checkbox"] {
|
||||||
|
width: 18px;
|
||||||
|
height: 18px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.essential-badge {
|
||||||
|
display: inline-block;
|
||||||
|
background-color: var(--essential-bg);
|
||||||
|
color: var(--essential-text);
|
||||||
|
padding: 4px 8px;
|
||||||
|
border-radius: 3px;
|
||||||
|
font-size: 10px;
|
||||||
|
font-weight: 700;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.5px;
|
||||||
|
border: 1px solid var(--essential-border);
|
||||||
|
margin-left: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.form-grid {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.severity-selector {
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="header">
|
||||||
|
<div class="header-content">
|
||||||
|
<div>
|
||||||
|
<h1>🚨 Segnalazione Nuovo Incidente</h1>
|
||||||
|
<div class="breadcrumb">
|
||||||
|
<a href="dashboard.html">Dashboard NIS2</a> /
|
||||||
|
<a href="incident-dashboard.html">Gestione Incidenti</a> /
|
||||||
|
Nuovo Incidente
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<a href="incident-dashboard.html" class="btn">← Annulla</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<div class="alert-box danger">
|
||||||
|
<div class="alert-title">⚠️ Procedura di Emergenza</div>
|
||||||
|
<div class="alert-content">
|
||||||
|
Per incidenti <strong>SEV-1 (Critici)</strong>: attivare immediatamente il Crisis Team e il CISO.
|
||||||
|
La notifica al CSIRT Italia (preallarme) deve essere effettuata entro <strong>24 ore</strong> dalla conoscenza dell'incidente significativo.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<form id="incidentForm">
|
||||||
|
<!-- Sezione 1: Rilevazione -->
|
||||||
|
<div class="form-section">
|
||||||
|
<div class="form-section-title">
|
||||||
|
Fase 1: Rilevazione e Segnalazione
|
||||||
|
<span class="help-icon">?
|
||||||
|
<div class="tooltip">
|
||||||
|
<div class="tooltip-title">HELP DELLA SEZIONE</div>
|
||||||
|
Registrazione iniziale dell'incidente. Compilare entro 15 minuti dalla rilevazione per incidenti critici. Tutte le informazioni possono essere aggiornate durante la gestione.
|
||||||
|
</div>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-grid">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label">
|
||||||
|
Data/Ora Rilevazione <span class="required">*</span>
|
||||||
|
</label>
|
||||||
|
<input type="datetime-local" class="form-input" id="detectionTime" required>
|
||||||
|
<div class="form-help">Momento in cui l'incidente è stato rilevato</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label">
|
||||||
|
Fonte di Rilevazione <span class="required">*</span>
|
||||||
|
</label>
|
||||||
|
<select class="form-select" id="detectionSource" required>
|
||||||
|
<option value="">Seleziona...</option>
|
||||||
|
<option value="siem">Alert SIEM/SOC</option>
|
||||||
|
<option value="edr">Alert EDR/Antimalware</option>
|
||||||
|
<option value="user">Segnalazione Utente</option>
|
||||||
|
<option value="supplier">Notifica Fornitore/Partner</option>
|
||||||
|
<option value="csirt">Notifica CSIRT Italia</option>
|
||||||
|
<option value="threat-intel">Threat Intelligence</option>
|
||||||
|
<option value="external">Segnalazione Esterna</option>
|
||||||
|
<option value="monitoring">Monitoraggio Infrastruttura</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label">
|
||||||
|
Analista Assegnato <span class="required">*</span>
|
||||||
|
</label>
|
||||||
|
<select class="form-select" id="analyst" required>
|
||||||
|
<option value="">Seleziona...</option>
|
||||||
|
<option value="ciso">CISO</option>
|
||||||
|
<option value="soc-lead">SOC Lead</option>
|
||||||
|
<option value="analyst1">Analista Sicurezza 1</option>
|
||||||
|
<option value="analyst2">Analista Sicurezza 2</option>
|
||||||
|
<option value="sysadmin">System Administrator</option>
|
||||||
|
<option value="netadmin">Network Administrator</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group full-width">
|
||||||
|
<label class="form-label">
|
||||||
|
Descrizione Preliminare <span class="required">*</span>
|
||||||
|
</label>
|
||||||
|
<textarea class="form-textarea" id="description" required placeholder="Descrizione dettagliata dell'incidente rilevato..."></textarea>
|
||||||
|
<div class="form-help">Fornire tutti i dettagli disponibili: cosa è stato rilevato, su quali sistemi, sintomi osservati</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group full-width">
|
||||||
|
<label class="form-label">
|
||||||
|
Sistemi Potenzialmente Impattati
|
||||||
|
</label>
|
||||||
|
<input type="text" class="form-input" id="affectedSystems" placeholder="es. HW-SRV-001, SW-ERP-001, CLD-IAAS-001">
|
||||||
|
<div class="form-help">Codici asset da inventario (Org.01). Separare con virgola se multipli</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Sezione 2: Triage e Classificazione -->
|
||||||
|
<div class="form-section">
|
||||||
|
<div class="form-section-title">
|
||||||
|
Fase 2: Triage e Classificazione
|
||||||
|
<span class="help-icon">?
|
||||||
|
<div class="tooltip">
|
||||||
|
<div class="tooltip-title">HELP DELLA SEZIONE</div>
|
||||||
|
Determinazione della severità e classificazione secondo NIS2. Completare entro 1 ora per SEV-1/SEV-2. La classificazione determina gli obblighi di notifica al CSIRT.
|
||||||
|
</div>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group full-width">
|
||||||
|
<label class="form-label">
|
||||||
|
Severità Incidente <span class="required">*</span>
|
||||||
|
</label>
|
||||||
|
<div class="severity-selector">
|
||||||
|
<div class="severity-option sev-1" onclick="selectSeverity('sev-1')">
|
||||||
|
<div class="severity-label" style="color: var(--danger);">SEV-1</div>
|
||||||
|
<div class="severity-desc">CRITICO</div>
|
||||||
|
</div>
|
||||||
|
<div class="severity-option sev-2" onclick="selectSeverity('sev-2')">
|
||||||
|
<div class="severity-label" style="color: var(--warning);">SEV-2</div>
|
||||||
|
<div class="severity-desc">ALTO</div>
|
||||||
|
</div>
|
||||||
|
<div class="severity-option" onclick="selectSeverity('sev-3')">
|
||||||
|
<div class="severity-label" style="color: var(--accent-primary);">SEV-3</div>
|
||||||
|
<div class="severity-desc">MEDIO</div>
|
||||||
|
</div>
|
||||||
|
<div class="severity-option" onclick="selectSeverity('sev-4')">
|
||||||
|
<div class="severity-label" style="color: var(--text-secondary);">SEV-4</div>
|
||||||
|
<div class="severity-desc">BASSO</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<input type="hidden" id="severity" required>
|
||||||
|
<div class="form-help" id="severityHelp" style="margin-top: 12px;"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="alert-box warning" id="sev1Alert" style="display: none;">
|
||||||
|
<div class="alert-title">🚨 Incidente SEV-1 - Azioni Immediate Richieste</div>
|
||||||
|
<div class="alert-content">
|
||||||
|
<ul style="margin-left: 20px; margin-top: 8px;">
|
||||||
|
<li>Attivare immediatamente Crisis Team</li>
|
||||||
|
<li>Notificare CISO e Direzione</li>
|
||||||
|
<li>Contenimento entro 30 minuti</li>
|
||||||
|
<li>Preallarme CSIRT entro 24h (se significativo)</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-grid">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label">
|
||||||
|
Classificazione NIS2 <span class="required">*</span>
|
||||||
|
</label>
|
||||||
|
<select class="form-select" id="classification" required onchange="updateClassificationHelp()">
|
||||||
|
<option value="">Seleziona...</option>
|
||||||
|
<option value="is-1">IS-1 - Impatto su servizi rilevanti</option>
|
||||||
|
<option value="is-2">IS-2 - Impatto su integrità/riservatezza dati</option>
|
||||||
|
<option value="is-3">IS-3 - Impatto su altri soggetti/supply chain</option>
|
||||||
|
<option value="is-4" id="is4ClassOption">IS-4 - Incidente ricorrente (SOLO ESSENZIALI)</option>
|
||||||
|
<option value="not-significant">Non Significativo</option>
|
||||||
|
</select>
|
||||||
|
<div class="form-help" id="classificationHelp"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label">
|
||||||
|
Impatto
|
||||||
|
</label>
|
||||||
|
<select class="form-select" id="impact" multiple size="4">
|
||||||
|
<option value="availability">Disponibilità</option>
|
||||||
|
<option value="integrity">Integrità</option>
|
||||||
|
<option value="confidentiality">Riservatezza</option>
|
||||||
|
<option value="authenticity">Autenticità</option>
|
||||||
|
</select>
|
||||||
|
<div class="form-help">Tenere premuto Ctrl/Cmd per selezione multipla</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label">
|
||||||
|
Categoria MITRE ATT&CK
|
||||||
|
</label>
|
||||||
|
<select class="form-select" id="mitreCategory">
|
||||||
|
<option value="">Non determinata</option>
|
||||||
|
<option value="initial-access">Initial Access</option>
|
||||||
|
<option value="execution">Execution</option>
|
||||||
|
<option value="persistence">Persistence</option>
|
||||||
|
<option value="privilege-escalation">Privilege Escalation</option>
|
||||||
|
<option value="defense-evasion">Defense Evasion</option>
|
||||||
|
<option value="credential-access">Credential Access</option>
|
||||||
|
<option value="discovery">Discovery</option>
|
||||||
|
<option value="lateral-movement">Lateral Movement</option>
|
||||||
|
<option value="collection">Collection</option>
|
||||||
|
<option value="exfiltration">Exfiltration</option>
|
||||||
|
<option value="impact">Impact</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label">
|
||||||
|
Vettore di Attacco
|
||||||
|
</label>
|
||||||
|
<select class="form-select" id="attackVector">
|
||||||
|
<option value="">Non determinato</option>
|
||||||
|
<option value="phishing">Phishing/Spear Phishing</option>
|
||||||
|
<option value="malware">Malware</option>
|
||||||
|
<option value="ransomware">Ransomware</option>
|
||||||
|
<option value="vulnerability">Exploit Vulnerabilità</option>
|
||||||
|
<option value="brute-force">Brute Force</option>
|
||||||
|
<option value="credential-stuffing">Credential Stuffing</option>
|
||||||
|
<option value="supply-chain">Supply Chain Attack</option>
|
||||||
|
<option value="ddos">DDoS</option>
|
||||||
|
<option value="insider">Insider Threat</option>
|
||||||
|
<option value="physical">Accesso Fisico</option>
|
||||||
|
<option value="social-engineering">Social Engineering</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="alert-box" id="csirtAlert" style="display: none;">
|
||||||
|
<div class="alert-title">📡 Notifica CSIRT Obbligatoria</div>
|
||||||
|
<div class="alert-content">
|
||||||
|
Questo incidente rientra nella classificazione di incidente significativo secondo NIS2.
|
||||||
|
È obbligatorio inviare il <strong>preallarme al CSIRT Italia entro 24 ore</strong> dalla conoscenza dell'incidente.
|
||||||
|
<br><br>
|
||||||
|
Dopo la creazione dell'incidente, procedere alla sezione "Notifiche CSIRT" per gestire le comunicazioni obbligatorie.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Sezione 3: Dati Impattati -->
|
||||||
|
<div class="form-section">
|
||||||
|
<div class="form-section-title">
|
||||||
|
Dati e Servizi Impattati
|
||||||
|
<span class="help-icon">?
|
||||||
|
<div class="tooltip">
|
||||||
|
<div class="tooltip-title">HELP DELLA SEZIONE</div>
|
||||||
|
Identificazione dei dati e servizi coinvolti nell'incidente. Fondamentale per valutare obblighi GDPR e impatto operativo.
|
||||||
|
</div>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-grid">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label">
|
||||||
|
Dati Personali Coinvolti?
|
||||||
|
</label>
|
||||||
|
<select class="form-select" id="personalData" onchange="toggleGDPR()">
|
||||||
|
<option value="no">No</option>
|
||||||
|
<option value="yes">Sì</option>
|
||||||
|
<option value="unknown">Da verificare</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group" id="gdprGroup" style="display: none;">
|
||||||
|
<label class="form-label">
|
||||||
|
Notifica Garante Privacy
|
||||||
|
</label>
|
||||||
|
<select class="form-select" id="gdprNotification">
|
||||||
|
<option value="not-required">Non richiesta</option>
|
||||||
|
<option value="required">Richiesta (entro 72h)</option>
|
||||||
|
<option value="sent">Già inviata</option>
|
||||||
|
</select>
|
||||||
|
<div class="form-help">Art. 33 GDPR - coordinare con DPO</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group full-width">
|
||||||
|
<label class="form-label">
|
||||||
|
Servizi Rilevanti NIS2 Impattati
|
||||||
|
</label>
|
||||||
|
<input type="text" class="form-input" id="affectedServices" placeholder="Codici servizi da catalogo (ID.AM-04)">
|
||||||
|
<div class="form-help">Elencare i servizi rilevanti NIS2 che hanno subito interruzione o degrado</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label">
|
||||||
|
Numero Utenti Impattati (stima)
|
||||||
|
</label>
|
||||||
|
<input type="number" class="form-input" id="usersImpacted" min="0">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label">
|
||||||
|
Impatto Economico Stimato (€)
|
||||||
|
</label>
|
||||||
|
<input type="number" class="form-input" id="financialImpact" min="0" step="100">
|
||||||
|
<div class="form-help">Stima preliminare (diretto + indiretto)</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Sezione 4: Azioni Immediate -->
|
||||||
|
<div class="form-section">
|
||||||
|
<div class="form-section-title">
|
||||||
|
Azioni Immediate di Contenimento
|
||||||
|
<span class="help-icon">?
|
||||||
|
<div class="tooltip">
|
||||||
|
<div class="tooltip-title">HELP DELLA SEZIONE</div>
|
||||||
|
Checklist delle azioni di contenimento immediato. Per SEV-1: contenimento entro 30 minuti. Documentare ogni azione con timestamp.
|
||||||
|
</div>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ul class="checklist">
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="action1">
|
||||||
|
<label for="action1">Sistema compromesso isolato dalla rete</label>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="action2">
|
||||||
|
<label for="action2">Account compromessi bloccati</label>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="action3">
|
||||||
|
<label for="action3">IP/domini malevoli bloccati su firewall</label>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="action4">
|
||||||
|
<label for="action4">Evidenze preservate (snapshot, log, memoria)</label>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="action5">
|
||||||
|
<label for="action5">Monitoraggio intensivo attivato su sistemi correlati</label>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="action6">
|
||||||
|
<label for="action6">Crisis Team / IRT notificato</label>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="action7">
|
||||||
|
<label for="action7">Direzione informata (per SEV-1/SEV-2)</label>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div class="form-group" style="margin-top: 20px;">
|
||||||
|
<label class="form-label">
|
||||||
|
Note Azioni di Contenimento
|
||||||
|
</label>
|
||||||
|
<textarea class="form-textarea" id="containmentNotes" placeholder="Descrivere in dettaglio le azioni di contenimento effettuate con timestamp..."></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Sezione 5: Collegamento Risk -->
|
||||||
|
<div class="form-section">
|
||||||
|
<div class="form-section-title">
|
||||||
|
Collegamento Risk Assessment
|
||||||
|
<span class="help-icon">?
|
||||||
|
<div class="tooltip">
|
||||||
|
<div class="tooltip-title">HELP DELLA SEZIONE</div>
|
||||||
|
Collegare l'incidente a rischi già identificati nel risk assessment (Org.05). Se l'incidente evidenzia un nuovo rischio, verrà creato automaticamente.
|
||||||
|
</div>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label">
|
||||||
|
Collegamento N°RISK
|
||||||
|
</label>
|
||||||
|
<input type="text" class="form-input" id="riskId" placeholder="es. RISK-2024-015">
|
||||||
|
<div class="form-help">Codice rischio da Org.05 - Risk Assessment. Lasciare vuoto se nuovo rischio</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label">
|
||||||
|
Root Cause Preliminare
|
||||||
|
</label>
|
||||||
|
<select class="form-select" id="rootCause">
|
||||||
|
<option value="">Da determinare</option>
|
||||||
|
<option value="vulnerability">Vulnerabilità non patchata</option>
|
||||||
|
<option value="misconfiguration">Errore di configurazione</option>
|
||||||
|
<option value="weak-credentials">Credenziali deboli/compromesse</option>
|
||||||
|
<option value="missing-controls">Controlli di sicurezza mancanti</option>
|
||||||
|
<option value="human-error">Errore umano</option>
|
||||||
|
<option value="third-party">Compromissione terza parte</option>
|
||||||
|
<option value="zero-day">Zero-day exploit</option>
|
||||||
|
<option value="insider">Insider threat</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Form Actions -->
|
||||||
|
<div class="form-section">
|
||||||
|
<div class="form-actions">
|
||||||
|
<a href="incident-dashboard.html" class="btn">Annulla</a>
|
||||||
|
<button type="button" class="btn" onclick="saveDraft()">Salva Bozza</button>
|
||||||
|
<button type="submit" class="btn btn-danger">🚨 Crea Incidente e Attiva Gestione</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// Verifica tipo soggetto
|
||||||
|
function checkSubjectType() {
|
||||||
|
const subjectType = sessionStorage.getItem('nis2_subject_type');
|
||||||
|
|
||||||
|
if (!subjectType) {
|
||||||
|
window.location.href = 'incident-gate.html';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Nascondi IS-4 per soggetti importanti
|
||||||
|
if (subjectType === 'important') {
|
||||||
|
const is4Option = document.getElementById('is4ClassOption');
|
||||||
|
if (is4Option) is4Option.style.display = 'none';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Imposta data/ora corrente
|
||||||
|
function setCurrentDateTime() {
|
||||||
|
const now = new Date();
|
||||||
|
const year = now.getFullYear();
|
||||||
|
const month = String(now.getMonth() + 1).padStart(2, '0');
|
||||||
|
const day = String(now.getDate()).padStart(2, '0');
|
||||||
|
const hours = String(now.getHours()).padStart(2, '0');
|
||||||
|
const minutes = String(now.getMinutes()).padStart(2, '0');
|
||||||
|
|
||||||
|
document.getElementById('detectionTime').value = `${year}-${month}-${day}T${hours}:${minutes}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Selezione severità
|
||||||
|
function selectSeverity(severity) {
|
||||||
|
// Rimuovi selezione precedente
|
||||||
|
document.querySelectorAll('.severity-option').forEach(opt => {
|
||||||
|
opt.classList.remove('selected');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Seleziona nuovo
|
||||||
|
event.target.closest('.severity-option').classList.add('selected');
|
||||||
|
document.getElementById('severity').value = severity;
|
||||||
|
|
||||||
|
// Mostra help specifico
|
||||||
|
const helpTexts = {
|
||||||
|
'sev-1': '🚨 <strong>CRITICO:</strong> Interruzione totale servizio critico, ransomware attivo, esfiltrazione massiva dati, compromissione infrastruttura core. <strong>Attivazione immediata Crisis Team.</strong>',
|
||||||
|
'sev-2': '⚠️ <strong>ALTO:</strong> Interruzione parziale servizio rilevante, compromissione account privilegiato, malware attivo non contenuto, accesso non autorizzato a dati riservati.',
|
||||||
|
'sev-3': 'ℹ️ <strong>MEDIO:</strong> Degrado prestazioni servizio rilevante, malware contenuto automaticamente, tentativo intrusione bloccato ma significativo.',
|
||||||
|
'sev-4': '📝 <strong>BASSO:</strong> Anomalia senza impatto operativo, tentativo attacco bloccato (routine), violazione policy minore.'
|
||||||
|
};
|
||||||
|
|
||||||
|
document.getElementById('severityHelp').innerHTML = helpTexts[severity];
|
||||||
|
|
||||||
|
// Mostra alert per SEV-1
|
||||||
|
const sev1Alert = document.getElementById('sev1Alert');
|
||||||
|
if (severity === 'sev-1') {
|
||||||
|
sev1Alert.style.display = 'block';
|
||||||
|
} else {
|
||||||
|
sev1Alert.style.display = 'none';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Aggiorna help classificazione
|
||||||
|
function updateClassificationHelp() {
|
||||||
|
const classification = document.getElementById('classification').value;
|
||||||
|
const helpTexts = {
|
||||||
|
'is-1': 'Interruzione operativa o degrado significativo di un servizio rilevante NIS2. <strong>Notifica CSIRT obbligatoria.</strong>',
|
||||||
|
'is-2': 'Accesso non autorizzato, modifica, esfiltrazione o violazione riservatezza dati. <strong>Notifica CSIRT obbligatoria.</strong> Verificare anche obbligo GDPR.',
|
||||||
|
'is-3': 'Incidente che si propaga a soggetti terzi o impatta la catena di fornitura. <strong>Notifica CSIRT obbligatoria.</strong>',
|
||||||
|
'is-4': 'Serie di incidenti correlati con impatto cumulativo significativo. <strong>Notifica CSIRT obbligatoria SOLO per soggetti ESSENZIALI.</strong>',
|
||||||
|
'not-significant': 'Incidente gestito internamente, senza obbligo di notifica CSIRT. Documentare comunque nel registro incidenti.'
|
||||||
|
};
|
||||||
|
|
||||||
|
const helpElement = document.getElementById('classificationHelp');
|
||||||
|
helpElement.innerHTML = helpTexts[classification] || '';
|
||||||
|
|
||||||
|
// Mostra/nascondi alert CSIRT
|
||||||
|
const csirtAlert = document.getElementById('csirtAlert');
|
||||||
|
if (['is-1', 'is-2', 'is-3', 'is-4'].includes(classification)) {
|
||||||
|
csirtAlert.style.display = 'block';
|
||||||
|
} else {
|
||||||
|
csirtAlert.style.display = 'none';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Toggle GDPR
|
||||||
|
function toggleGDPR() {
|
||||||
|
const personalData = document.getElementById('personalData').value;
|
||||||
|
const gdprGroup = document.getElementById('gdprGroup');
|
||||||
|
|
||||||
|
if (personalData === 'yes') {
|
||||||
|
gdprGroup.style.display = 'block';
|
||||||
|
} else {
|
||||||
|
gdprGroup.style.display = 'none';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Salva bozza
|
||||||
|
function saveDraft() {
|
||||||
|
alert('Bozza salvata con successo. Puoi continuare la compilazione in seguito.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Submit form
|
||||||
|
document.getElementById('incidentForm').addEventListener('submit', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
// Validazione
|
||||||
|
const severity = document.getElementById('severity').value;
|
||||||
|
if (!severity) {
|
||||||
|
alert('Seleziona la severità dell\'incidente');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Genera codice incidente
|
||||||
|
const year = new Date().getFullYear();
|
||||||
|
const progressive = Math.floor(Math.random() * 900) + 100; // Simulato
|
||||||
|
const incidentCode = `INC-${year}-${progressive}`;
|
||||||
|
|
||||||
|
// Simula creazione incidente
|
||||||
|
const tooltip = document.createElement('div');
|
||||||
|
tooltip.style.cssText = `
|
||||||
|
position: fixed;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
background: var(--bg-secondary);
|
||||||
|
border: 2px solid var(--success);
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 32px;
|
||||||
|
box-shadow: 0 8px 24px rgba(0,0,0,0.5);
|
||||||
|
z-index: 10000;
|
||||||
|
max-width: 500px;
|
||||||
|
text-align: center;
|
||||||
|
`;
|
||||||
|
tooltip.innerHTML = `
|
||||||
|
<div style="font-size: 48px; margin-bottom: 16px;">✅</div>
|
||||||
|
<h2 style="color: var(--success); margin-bottom: 16px;">Incidente Creato con Successo</h2>
|
||||||
|
<p style="color: var(--text-secondary); margin-bottom: 8px;">Codice incidente:</p>
|
||||||
|
<p style="font-size: 24px; font-weight: 700; color: var(--text-primary); margin-bottom: 24px; font-family: monospace;">${incidentCode}</p>
|
||||||
|
<div style="background: var(--bg-tertiary); padding: 16px; border-radius: 6px; margin-bottom: 24px; text-align: left;">
|
||||||
|
<p style="font-size: 13px; color: var(--text-secondary); margin-bottom: 12px;"><strong>Prossime azioni:</strong></p>
|
||||||
|
<ul style="font-size: 13px; color: var(--text-secondary); margin-left: 20px;">
|
||||||
|
<li>Incident Response Team notificato</li>
|
||||||
|
<li>Timeline di gestione avviata</li>
|
||||||
|
${severity === 'sev-1' ? '<li style="color: var(--danger); font-weight: 600;">Crisis Team attivato</li>' : ''}
|
||||||
|
${['is-1', 'is-2', 'is-3'].includes(document.getElementById('classification').value) ? '<li style="color: var(--warning); font-weight: 600;">Preallarme CSIRT da inviare entro 24h</li>' : ''}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<button onclick="window.location.href='incident-detail.html?id=${incidentCode}'"
|
||||||
|
style="padding: 12px 24px; background: var(--accent-primary); border: none; border-radius: 6px; color: white; font-weight: 600; cursor: pointer; margin-right: 12px;">
|
||||||
|
Vai all'Incidente
|
||||||
|
</button>
|
||||||
|
<button onclick="window.location.href='incident-dashboard.html'"
|
||||||
|
style="padding: 12px 24px; background: var(--bg-tertiary); border: 1px solid var(--border-color); border-radius: 6px; color: var(--text-primary); font-weight: 600; cursor: pointer;">
|
||||||
|
Torna alla Dashboard
|
||||||
|
</button>
|
||||||
|
`;
|
||||||
|
document.body.appendChild(tooltip);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Inizializza
|
||||||
|
window.addEventListener('DOMContentLoaded', function() {
|
||||||
|
checkSubjectType();
|
||||||
|
setCurrentDateTime();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
758
docs/nis2/incidente_r01/incident-notification.html
Normal file
758
docs/nis2/incidente_r01/incident-notification.html
Normal file
@ -0,0 +1,758 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="it">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Notifiche CSIRT - INC-2024-047</title>
|
||||||
|
<style>
|
||||||
|
:root {
|
||||||
|
--bg-primary: #0d1117;
|
||||||
|
--bg-secondary: #161b22;
|
||||||
|
--bg-tertiary: #1c2128;
|
||||||
|
--border-color: #30363d;
|
||||||
|
--text-primary: #c9d1d9;
|
||||||
|
--text-secondary: #8b949e;
|
||||||
|
--accent-primary: #58a6ff;
|
||||||
|
--accent-secondary: #1f6feb;
|
||||||
|
--success: #3fb950;
|
||||||
|
--warning: #d29922;
|
||||||
|
--danger: #f85149;
|
||||||
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Noto Sans', Helvetica, Arial, sans-serif;
|
||||||
|
background-color: var(--bg-primary);
|
||||||
|
color: var(--text-primary);
|
||||||
|
line-height: 1.6;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 1200px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
background-color: var(--bg-secondary);
|
||||||
|
border-bottom: 1px solid var(--border-color);
|
||||||
|
padding: 24px 0;
|
||||||
|
margin-bottom: 32px;
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
z-index: 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-content {
|
||||||
|
max-width: 1200px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0 20px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header h1 {
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.breadcrumb {
|
||||||
|
font-size: 13px;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
margin-top: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.breadcrumb a {
|
||||||
|
color: var(--accent-primary);
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
padding: 8px 16px;
|
||||||
|
background-color: var(--bg-tertiary);
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
border-radius: 6px;
|
||||||
|
color: var(--text-primary);
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 500;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn:hover {
|
||||||
|
border-color: var(--accent-primary);
|
||||||
|
color: var(--accent-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary {
|
||||||
|
background-color: var(--accent-primary);
|
||||||
|
border-color: var(--accent-primary);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary:hover {
|
||||||
|
background-color: var(--accent-secondary);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-danger {
|
||||||
|
background-color: var(--danger);
|
||||||
|
border-color: var(--danger);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-danger:hover {
|
||||||
|
background-color: #dc2626;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert-box {
|
||||||
|
background-color: rgba(210, 153, 34, 0.1);
|
||||||
|
border: 1px solid var(--warning);
|
||||||
|
border-left: 4px solid var(--warning);
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 20px;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert-box.danger {
|
||||||
|
background-color: rgba(248, 81, 73, 0.1);
|
||||||
|
border-color: var(--danger);
|
||||||
|
border-left-color: var(--danger);
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert-box.success {
|
||||||
|
background-color: rgba(63, 185, 80, 0.1);
|
||||||
|
border-color: var(--success);
|
||||||
|
border-left-color: var(--success);
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert-title {
|
||||||
|
font-weight: 600;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
font-size: 15px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert-content {
|
||||||
|
font-size: 13px;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section {
|
||||||
|
background-color: var(--bg-secondary);
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 24px;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
padding-bottom: 16px;
|
||||||
|
border-bottom: 1px solid var(--border-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-horizontal {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-bottom: 32px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-horizontal::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 20px;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
height: 2px;
|
||||||
|
background: var(--border-color);
|
||||||
|
z-index: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-step {
|
||||||
|
flex: 1;
|
||||||
|
text-align: center;
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-circle {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: var(--bg-tertiary);
|
||||||
|
border: 2px solid var(--border-color);
|
||||||
|
margin: 0 auto 12px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-step.completed .timeline-circle {
|
||||||
|
background: var(--success);
|
||||||
|
border-color: var(--success);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-step.active .timeline-circle {
|
||||||
|
background: var(--warning);
|
||||||
|
border-color: var(--warning);
|
||||||
|
color: white;
|
||||||
|
animation: pulse 2s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes pulse {
|
||||||
|
0%, 100% { box-shadow: 0 0 0 0 rgba(210, 153, 34, 0.7); }
|
||||||
|
50% { box-shadow: 0 0 0 10px rgba(210, 153, 34, 0); }
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-label {
|
||||||
|
font-size: 12px;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
font-weight: 600;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-deadline {
|
||||||
|
font-size: 11px;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-step.completed .timeline-label,
|
||||||
|
.timeline-step.active .timeline-label {
|
||||||
|
color: var(--text-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-section {
|
||||||
|
background-color: var(--bg-tertiary);
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 20px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-label {
|
||||||
|
display: block;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text-primary);
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-input, .form-select, .form-textarea {
|
||||||
|
width: 100%;
|
||||||
|
padding: 10px 12px;
|
||||||
|
background-color: var(--bg-primary);
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
border-radius: 6px;
|
||||||
|
color: var(--text-primary);
|
||||||
|
font-size: 14px;
|
||||||
|
font-family: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-input:focus, .form-select:focus, .form-textarea:focus {
|
||||||
|
outline: none;
|
||||||
|
border-color: var(--accent-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-textarea {
|
||||||
|
resize: vertical;
|
||||||
|
min-height: 120px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-help {
|
||||||
|
font-size: 12px;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
margin-top: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-box {
|
||||||
|
background-color: var(--bg-tertiary);
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 16px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-box-title {
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--accent-primary);
|
||||||
|
margin-bottom: 8px;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-box-content {
|
||||||
|
font-size: 13px;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.data-table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.data-table th {
|
||||||
|
background-color: var(--bg-primary);
|
||||||
|
color: var(--text-secondary);
|
||||||
|
font-weight: 600;
|
||||||
|
text-align: left;
|
||||||
|
padding: 10px 12px;
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
font-size: 11px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.data-table td {
|
||||||
|
padding: 10px 12px;
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
color: var(--text-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.timeline-horizontal {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-horizontal::before {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-step {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-circle {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="header">
|
||||||
|
<div class="header-content">
|
||||||
|
<div>
|
||||||
|
<h1>📡 Notifiche CSIRT Italia - INC-2024-047</h1>
|
||||||
|
<div class="breadcrumb">
|
||||||
|
<a href="dashboard.html">Dashboard NIS2</a> /
|
||||||
|
<a href="incident-dashboard.html">Gestione Incidenti</a> /
|
||||||
|
<a href="incident-detail.html?id=INC-2024-047">INC-2024-047</a> /
|
||||||
|
Notifiche CSIRT
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<a href="incident-detail.html?id=INC-2024-047" class="btn">← Torna all'Incidente</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<!-- Alert Scadenza -->
|
||||||
|
<div class="alert-box danger">
|
||||||
|
<div class="alert-title">
|
||||||
|
⏰ Scadenza Imminente - Preallarme CSIRT
|
||||||
|
</div>
|
||||||
|
<div class="alert-content">
|
||||||
|
Il <strong>preallarme</strong> deve essere inviato al CSIRT Italia entro <strong>24 ore</strong> dalla conoscenza dell'incidente significativo.<br>
|
||||||
|
<strong>Scadenza:</strong> 2024-03-07 08:15 (rimangono <span style="color: var(--danger); font-weight: 700;">18 ore</span>)<br>
|
||||||
|
<strong>Canale:</strong> Portale CSIRT Italia (https://www.csirt.gov.it) o PEC dedicata
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Timeline Notifiche -->
|
||||||
|
<div class="timeline-horizontal">
|
||||||
|
<div class="timeline-step active">
|
||||||
|
<div class="timeline-circle">1</div>
|
||||||
|
<div class="timeline-label">Preallarme</div>
|
||||||
|
<div class="timeline-deadline">Entro 24h</div>
|
||||||
|
</div>
|
||||||
|
<div class="timeline-step">
|
||||||
|
<div class="timeline-circle">2</div>
|
||||||
|
<div class="timeline-label">Notifica Completa</div>
|
||||||
|
<div class="timeline-deadline">Entro 72h</div>
|
||||||
|
</div>
|
||||||
|
<div class="timeline-step">
|
||||||
|
<div class="timeline-circle">3</div>
|
||||||
|
<div class="timeline-label">Relazioni Intermedie</div>
|
||||||
|
<div class="timeline-deadline">Su richiesta</div>
|
||||||
|
</div>
|
||||||
|
<div class="timeline-step">
|
||||||
|
<div class="timeline-circle">4</div>
|
||||||
|
<div class="timeline-label">Relazione Finale</div>
|
||||||
|
<div class="timeline-deadline">Entro 1 mese</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Sezione Preallarme -->
|
||||||
|
<div class="section">
|
||||||
|
<div class="section-header">
|
||||||
|
<div class="section-title">1. Preallarme (Entro 24 ore)</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="info-box">
|
||||||
|
<div class="info-box-title">📋 Contenuto Minimo Preallarme</div>
|
||||||
|
<div class="info-box-content">
|
||||||
|
<ul style="margin-left: 20px; margin-top: 8px;">
|
||||||
|
<li>Se l'incidente è presumibilmente causato da atti illegittimi o malevoli</li>
|
||||||
|
<li>Se può avere impatto transfrontaliero</li>
|
||||||
|
<li>Descrizione preliminare dell'incidente</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<form id="prealertForm">
|
||||||
|
<div class="form-section">
|
||||||
|
<h3 style="font-size: 16px; font-weight: 600; margin-bottom: 16px;">Dati Incidente</h3>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label">Codice Incidente</label>
|
||||||
|
<input type="text" class="form-input" value="INC-2024-047" readonly>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label">Data/Ora Rilevazione</label>
|
||||||
|
<input type="text" class="form-input" value="2024-03-06 08:15" readonly>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label">Classificazione NIS2</label>
|
||||||
|
<input type="text" class="form-input" value="IS-2 - Impatto su integrità/riservatezza dati" readonly>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-section">
|
||||||
|
<h3 style="font-size: 16px; font-weight: 600; margin-bottom: 16px;">Informazioni Preallarme</h3>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label">Atti Illegittimi o Malevoli?</label>
|
||||||
|
<select class="form-select" required>
|
||||||
|
<option value="yes" selected>Sì - Attacco ransomware</option>
|
||||||
|
<option value="no">No</option>
|
||||||
|
<option value="unknown">Da determinare</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label">Impatto Transfrontaliero?</label>
|
||||||
|
<select class="form-select" required>
|
||||||
|
<option value="no" selected>No</option>
|
||||||
|
<option value="yes">Sì</option>
|
||||||
|
<option value="possible">Possibile</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label">Descrizione Preliminare Incidente</label>
|
||||||
|
<textarea class="form-textarea" required>Tentativo di attacco ransomware (famiglia BlackCat/ALPHV) rilevato su server ERP di produzione. L'EDR ha bloccato l'esecuzione del malware in fase iniziale. Il vettore di attacco è stato identificato come email phishing con allegato malevolo, sfruttando credenziali utente precedentemente compromesse. Il sistema è stato immediatamente isolato. Nessuna crittografia dati avvenuta. Nessuna esfiltrazione rilevata. Incidente contenuto con successo.</textarea>
|
||||||
|
<div class="form-help">Fornire una descrizione sintetica ma completa dell'incidente</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label">Sistemi/Servizi Impattati</label>
|
||||||
|
<textarea class="form-textarea">- Server ERP-PROD-01 (HW-SRV-001)
|
||||||
|
- Applicazione SAP ERP (SW-ERP-001)
|
||||||
|
- Servizio gestionale aziendale (SRV-ERP-001)
|
||||||
|
- 45 utenti interni impattati da interruzione servizio</textarea>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label">Azioni di Contenimento Adottate</label>
|
||||||
|
<textarea class="form-textarea">- Isolamento immediato server dalla rete (08:22)
|
||||||
|
- Blocco account utente compromesso (09:30)
|
||||||
|
- Blocco IP C2 su firewall (09:45)
|
||||||
|
- Preservazione evidenze forensi (08:35)
|
||||||
|
- Attivazione Crisis Team e CISO (08:25)
|
||||||
|
- Contenimento confermato entro 2.2 ore dalla rilevazione</textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-section">
|
||||||
|
<h3 style="font-size: 16px; font-weight: 600; margin-bottom: 16px;">Dati Organizzazione</h3>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label">Nome Organizzazione</label>
|
||||||
|
<input type="text" class="form-input" value="[Nome Azienda]" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label">Settore NIS2</label>
|
||||||
|
<select class="form-select" required>
|
||||||
|
<option value="">Seleziona settore...</option>
|
||||||
|
<option value="energia">Energia</option>
|
||||||
|
<option value="trasporti">Trasporti</option>
|
||||||
|
<option value="bancario">Bancario</option>
|
||||||
|
<option value="sanitario">Sanitario</option>
|
||||||
|
<option value="digitale" selected>Infrastrutture Digitali</option>
|
||||||
|
<option value="acqua">Acqua Potabile</option>
|
||||||
|
<option value="altro">Altro</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label">Referente Tecnico</label>
|
||||||
|
<input type="text" class="form-input" value="CISO - P. Lombardi" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label">Email Contatto</label>
|
||||||
|
<input type="email" class="form-input" value="ciso@azienda.it" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label">Telefono Contatto</label>
|
||||||
|
<input type="tel" class="form-input" value="+39 02 1234567" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="display: flex; gap: 12px; justify-content: flex-end; padding-top: 24px; border-top: 1px solid var(--border-color);">
|
||||||
|
<button type="button" class="btn" onclick="savePrealertDraft()">Salva Bozza</button>
|
||||||
|
<button type="button" class="btn btn-primary" onclick="previewPrealert()">Anteprima</button>
|
||||||
|
<button type="submit" class="btn btn-danger">📡 Invia Preallarme CSIRT</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Sezione Notifica Completa -->
|
||||||
|
<div class="section">
|
||||||
|
<div class="section-header">
|
||||||
|
<div class="section-title">2. Notifica Completa (Entro 72 ore)</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="alert-box">
|
||||||
|
<div class="alert-title">⏸️ In Attesa Invio Preallarme</div>
|
||||||
|
<div class="alert-content">
|
||||||
|
La notifica completa può essere compilata dopo l'invio del preallarme.<br>
|
||||||
|
<strong>Scadenza:</strong> 2024-03-09 08:15 (72 ore dalla rilevazione)
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="info-box">
|
||||||
|
<div class="info-box-title">📋 Contenuto Notifica Completa</div>
|
||||||
|
<div class="info-box-content">
|
||||||
|
<ul style="margin-left: 20px; margin-top: 8px;">
|
||||||
|
<li>Aggiornamento informazioni del preallarme</li>
|
||||||
|
<li>Valutazione iniziale dell'incidente</li>
|
||||||
|
<li>Gravità e impatto dettagliato</li>
|
||||||
|
<li>Indicatori di compromissione (IoC) se disponibili</li>
|
||||||
|
<li>Misure di contenimento adottate</li>
|
||||||
|
<li>Stato corrente della gestione</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button class="btn" disabled style="opacity: 0.5;">Compila Notifica Completa (disponibile dopo preallarme)</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Sezione Relazione Finale -->
|
||||||
|
<div class="section">
|
||||||
|
<div class="section-header">
|
||||||
|
<div class="section-title">4. Relazione Finale (Entro 1 mese)</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="alert-box">
|
||||||
|
<div class="alert-title">⏸️ In Attesa Chiusura Incidente</div>
|
||||||
|
<div class="alert-content">
|
||||||
|
La relazione finale deve essere inviata entro 1 mese dalla notifica completa,
|
||||||
|
o entro 1 mese dalla gestione completa dell'incidente se ancora in corso.<br>
|
||||||
|
<strong>Scadenza stimata:</strong> 2024-04-09
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="info-box">
|
||||||
|
<div class="info-box-title">📋 Contenuto Relazione Finale</div>
|
||||||
|
<div class="info-box-content">
|
||||||
|
<ul style="margin-left: 20px; margin-top: 8px;">
|
||||||
|
<li>Descrizione dettagliata dell'incidente</li>
|
||||||
|
<li>Causa radice (root cause) identificata o probabile</li>
|
||||||
|
<li>Misure di mitigazione applicate</li>
|
||||||
|
<li>Impatto transfrontaliero (se applicabile)</li>
|
||||||
|
<li>Tipo di minaccia o causa radice</li>
|
||||||
|
<li>Misure correttive in corso e pianificate</li>
|
||||||
|
<li>Lesson learned e raccomandazioni</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button class="btn" disabled style="opacity: 0.5;">Compila Relazione Finale (disponibile dopo chiusura incidente)</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Storico Comunicazioni -->
|
||||||
|
<div class="section">
|
||||||
|
<div class="section-header">
|
||||||
|
<div class="section-title">Storico Comunicazioni CSIRT</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<table class="data-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Data/Ora</th>
|
||||||
|
<th>Tipo Comunicazione</th>
|
||||||
|
<th>Canale</th>
|
||||||
|
<th>Protocollo/Riferimento</th>
|
||||||
|
<th>Stato</th>
|
||||||
|
<th>Azioni</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td colspan="6" style="text-align: center; color: var(--text-secondary); padding: 24px;">
|
||||||
|
Nessuna comunicazione inviata ancora
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function savePrealertDraft() {
|
||||||
|
alert('Bozza preallarme salvata con successo. Puoi continuare la compilazione in seguito.');
|
||||||
|
}
|
||||||
|
|
||||||
|
function previewPrealert() {
|
||||||
|
const tooltip = document.createElement('div');
|
||||||
|
tooltip.style.cssText = `
|
||||||
|
position: fixed;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
background: var(--bg-secondary);
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 24px;
|
||||||
|
box-shadow: 0 8px 24px rgba(0,0,0,0.5);
|
||||||
|
z-index: 10000;
|
||||||
|
max-width: 700px;
|
||||||
|
width: 90%;
|
||||||
|
max-height: 80vh;
|
||||||
|
overflow-y: auto;
|
||||||
|
`;
|
||||||
|
tooltip.innerHTML = `
|
||||||
|
<h3 style="margin-bottom: 16px; color: var(--text-primary);">📄 Anteprima Preallarme CSIRT Italia</h3>
|
||||||
|
<div style="background: var(--bg-tertiary); padding: 20px; border-radius: 6px; margin-bottom: 16px; font-size: 13px; line-height: 1.8; font-family: monospace;">
|
||||||
|
<strong>PREALLARME INCIDENTE SIGNIFICATIVO NIS2</strong><br>
|
||||||
|
<strong>Protocollo:</strong> [Generato automaticamente]<br>
|
||||||
|
<strong>Data invio:</strong> ${new Date().toLocaleString('it-IT')}<br>
|
||||||
|
<br>
|
||||||
|
<strong>ORGANIZZAZIONE:</strong> [Nome Azienda]<br>
|
||||||
|
<strong>Settore:</strong> Infrastrutture Digitali<br>
|
||||||
|
<strong>Tipologia soggetto:</strong> ${sessionStorage.getItem('nis2_subject_type') === 'essential' ? 'Essenziale' : 'Importante'}<br>
|
||||||
|
<br>
|
||||||
|
<strong>CODICE INCIDENTE:</strong> INC-2024-047<br>
|
||||||
|
<strong>Data/Ora rilevazione:</strong> 2024-03-06 08:15<br>
|
||||||
|
<strong>Classificazione:</strong> IS-2 (Impatto integrità/riservatezza dati)<br>
|
||||||
|
<br>
|
||||||
|
<strong>NATURA INCIDENTE:</strong><br>
|
||||||
|
☑ Atti illegittimi o malevoli: SÌ (Attacco ransomware)<br>
|
||||||
|
☐ Impatto transfrontaliero: NO<br>
|
||||||
|
<br>
|
||||||
|
<strong>DESCRIZIONE PRELIMINARE:</strong><br>
|
||||||
|
Tentativo di attacco ransomware (famiglia BlackCat/ALPHV) rilevato su server ERP di produzione.
|
||||||
|
L'EDR ha bloccato l'esecuzione del malware in fase iniziale. Il vettore di attacco è stato identificato
|
||||||
|
come email phishing con allegato malevolo, sfruttando credenziali utente precedentemente compromesse.
|
||||||
|
Il sistema è stato immediatamente isolato. Nessuna crittografia dati avvenuta. Nessuna esfiltrazione rilevata.
|
||||||
|
Incidente contenuto con successo.<br>
|
||||||
|
<br>
|
||||||
|
<strong>SISTEMI IMPATTATI:</strong><br>
|
||||||
|
- Server ERP-PROD-01<br>
|
||||||
|
- Applicazione SAP ERP<br>
|
||||||
|
- 45 utenti interni<br>
|
||||||
|
<br>
|
||||||
|
<strong>AZIONI CONTENIMENTO:</strong><br>
|
||||||
|
- Isolamento server (2.2h)<br>
|
||||||
|
- Blocco account compromesso<br>
|
||||||
|
- Blocco IP C2<br>
|
||||||
|
- Evidenze preservate<br>
|
||||||
|
<br>
|
||||||
|
<strong>REFERENTE:</strong> CISO - P. Lombardi<br>
|
||||||
|
<strong>Contatto:</strong> ciso@azienda.it / +39 02 1234567<br>
|
||||||
|
<br>
|
||||||
|
<em>Notifica completa seguirà entro 72 ore.</em>
|
||||||
|
</div>
|
||||||
|
<div style="display: flex; gap: 12px;">
|
||||||
|
<button onclick="this.parentElement.parentElement.remove()" style="flex: 1; padding: 10px; background: var(--bg-tertiary); border: 1px solid var(--border-color); border-radius: 6px; color: var(--text-primary); font-weight: 600; cursor: pointer;">
|
||||||
|
Chiudi
|
||||||
|
</button>
|
||||||
|
<button onclick="this.parentElement.parentElement.remove(); document.getElementById('prealertForm').dispatchEvent(new Event('submit'));" style="flex: 1; padding: 10px; background: var(--danger); border: none; border-radius: 6px; color: white; font-weight: 600; cursor: pointer;">
|
||||||
|
Conferma e Invia
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
document.body.appendChild(tooltip);
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById('prealertForm').addEventListener('submit', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
const tooltip = document.createElement('div');
|
||||||
|
tooltip.style.cssText = `
|
||||||
|
position: fixed;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
background: var(--bg-secondary);
|
||||||
|
border: 2px solid var(--success);
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 32px;
|
||||||
|
box-shadow: 0 8px 24px rgba(0,0,0,0.5);
|
||||||
|
z-index: 10000;
|
||||||
|
max-width: 500px;
|
||||||
|
text-align: center;
|
||||||
|
`;
|
||||||
|
tooltip.innerHTML = `
|
||||||
|
<div style="font-size: 48px; margin-bottom: 16px;">✅</div>
|
||||||
|
<h2 style="color: var(--success); margin-bottom: 16px;">Preallarme Inviato con Successo</h2>
|
||||||
|
<p style="color: var(--text-secondary); margin-bottom: 8px;">Protocollo CSIRT:</p>
|
||||||
|
<p style="font-size: 20px; font-weight: 700; color: var(--text-primary); margin-bottom: 24px; font-family: monospace;">CSIRT-2024-03-06-${Math.floor(Math.random() * 10000)}</p>
|
||||||
|
<div style="background: var(--bg-tertiary); padding: 16px; border-radius: 6px; margin-bottom: 24px; text-align: left;">
|
||||||
|
<p style="font-size: 13px; color: var(--text-secondary); margin-bottom: 12px;"><strong>Dettagli invio:</strong></p>
|
||||||
|
<ul style="font-size: 13px; color: var(--text-secondary); margin-left: 20px;">
|
||||||
|
<li>Data/Ora invio: ${new Date().toLocaleString('it-IT')}</li>
|
||||||
|
<li>Canale: Portale CSIRT Italia</li>
|
||||||
|
<li>Ricevuta PEC: Confermata</li>
|
||||||
|
<li>Scadenza rispettata: ✅ SÌ (entro 24h)</li>
|
||||||
|
</ul>
|
||||||
|
<p style="font-size: 13px; color: var(--text-secondary); margin-top: 12px;">
|
||||||
|
<strong>Prossimo step:</strong> Notifica completa entro 2024-03-09 08:15 (72h)
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<button onclick="window.location.href='incident-detail.html?id=INC-2024-047'" style="padding: 12px 24px; background: var(--accent-primary); border: none; border-radius: 6px; color: white; font-weight: 600; cursor: pointer;">
|
||||||
|
Torna all'Incidente
|
||||||
|
</button>
|
||||||
|
`;
|
||||||
|
document.body.appendChild(tooltip);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
803
docs/nis2/incidente_r01/incident-pir.html
Normal file
803
docs/nis2/incidente_r01/incident-pir.html
Normal file
@ -0,0 +1,803 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="it">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Post-Incident Review - INC-2024-047</title>
|
||||||
|
<style>
|
||||||
|
:root {
|
||||||
|
--bg-primary: #0d1117;
|
||||||
|
--bg-secondary: #161b22;
|
||||||
|
--bg-tertiary: #1c2128;
|
||||||
|
--border-color: #30363d;
|
||||||
|
--text-primary: #c9d1d9;
|
||||||
|
--text-secondary: #8b949e;
|
||||||
|
--accent-primary: #58a6ff;
|
||||||
|
--success: #3fb950;
|
||||||
|
--warning: #d29922;
|
||||||
|
--danger: #f85149;
|
||||||
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Noto Sans', Helvetica, Arial, sans-serif;
|
||||||
|
background-color: var(--bg-primary);
|
||||||
|
color: var(--text-primary);
|
||||||
|
line-height: 1.6;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 1400px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
background-color: var(--bg-secondary);
|
||||||
|
border-bottom: 1px solid var(--border-color);
|
||||||
|
padding: 24px 0;
|
||||||
|
margin-bottom: 32px;
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
z-index: 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-content {
|
||||||
|
max-width: 1400px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0 20px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header h1 {
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.breadcrumb {
|
||||||
|
font-size: 13px;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
margin-top: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.breadcrumb a {
|
||||||
|
color: var(--accent-primary);
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
padding: 8px 16px;
|
||||||
|
background-color: var(--bg-tertiary);
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
border-radius: 6px;
|
||||||
|
color: var(--text-primary);
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 500;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn:hover {
|
||||||
|
border-color: var(--accent-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary {
|
||||||
|
background-color: var(--accent-primary);
|
||||||
|
border-color: var(--accent-primary);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary:hover {
|
||||||
|
background-color: #1f6feb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert-box {
|
||||||
|
background-color: rgba(88, 166, 255, 0.1);
|
||||||
|
border: 1px solid var(--accent-primary);
|
||||||
|
border-left: 4px solid var(--accent-primary);
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 20px;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert-title {
|
||||||
|
font-weight: 600;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert-content {
|
||||||
|
font-size: 13px;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section {
|
||||||
|
background-color: var(--bg-secondary);
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 24px;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text-primary);
|
||||||
|
margin-bottom: 20px;
|
||||||
|
padding-bottom: 12px;
|
||||||
|
border-bottom: 1px solid var(--border-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.metrics-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||||
|
gap: 16px;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.metric-card {
|
||||||
|
background-color: var(--bg-tertiary);
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 16px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.metric-label {
|
||||||
|
font-size: 11px;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.5px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.metric-value {
|
||||||
|
font-size: 28px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: var(--text-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.metric-value.success {
|
||||||
|
color: var(--success);
|
||||||
|
}
|
||||||
|
|
||||||
|
.metric-value.warning {
|
||||||
|
color: var(--warning);
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-label {
|
||||||
|
display: block;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text-primary);
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-textarea {
|
||||||
|
width: 100%;
|
||||||
|
padding: 12px;
|
||||||
|
background-color: var(--bg-tertiary);
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
border-radius: 6px;
|
||||||
|
color: var(--text-primary);
|
||||||
|
font-size: 14px;
|
||||||
|
font-family: inherit;
|
||||||
|
resize: vertical;
|
||||||
|
min-height: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-textarea:focus {
|
||||||
|
outline: none;
|
||||||
|
border-color: var(--accent-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.data-table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.data-table th {
|
||||||
|
background-color: var(--bg-tertiary);
|
||||||
|
color: var(--text-secondary);
|
||||||
|
font-weight: 600;
|
||||||
|
text-align: left;
|
||||||
|
padding: 10px 12px;
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
font-size: 11px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.data-table td {
|
||||||
|
padding: 10px 12px;
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
color: var(--text-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.priority-high {
|
||||||
|
color: var(--danger);
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.priority-medium {
|
||||||
|
color: var(--warning);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.priority-low {
|
||||||
|
color: var(--text-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-badge {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 4px 8px;
|
||||||
|
border-radius: 3px;
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: 600;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-planned {
|
||||||
|
background-color: rgba(88, 166, 255, 0.2);
|
||||||
|
color: var(--accent-primary);
|
||||||
|
border: 1px solid var(--accent-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-progress {
|
||||||
|
background-color: rgba(210, 153, 34, 0.2);
|
||||||
|
color: var(--warning);
|
||||||
|
border: 1px solid var(--warning);
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-completed {
|
||||||
|
background-color: rgba(63, 185, 80, 0.2);
|
||||||
|
color: var(--success);
|
||||||
|
border: 1px solid var(--success);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="header">
|
||||||
|
<div class="header-content">
|
||||||
|
<div>
|
||||||
|
<h1>📊 Post-Incident Review - INC-2024-047</h1>
|
||||||
|
<div class="breadcrumb">
|
||||||
|
<a href="dashboard.html">Dashboard NIS2</a> /
|
||||||
|
<a href="incident-dashboard.html">Gestione Incidenti</a> /
|
||||||
|
<a href="incident-detail.html?id=INC-2024-047">INC-2024-047</a> /
|
||||||
|
Post-Incident Review
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div style="display: flex; gap: 8px;">
|
||||||
|
<button class="btn" onclick="exportPIR()">📄 Esporta Report</button>
|
||||||
|
<a href="incident-detail.html?id=INC-2024-047" class="btn">← Torna all'Incidente</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<div class="alert-box">
|
||||||
|
<div class="alert-title">ℹ️ Post-Incident Review (RC.CO-03)</div>
|
||||||
|
<div class="alert-content">
|
||||||
|
Analisi completa dell'incidente per identificare lesson learned e azioni di miglioramento.
|
||||||
|
Da completare entro <strong>2 settimane dalla chiusura</strong> per incidenti SEV-1/SEV-2.
|
||||||
|
<br><br>
|
||||||
|
<strong>Partecipanti richiesti:</strong> Incident Response Team, CISO, Responsabili Divisione impattate, Direzione (per SEV-1)
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Metriche Incidente -->
|
||||||
|
<div class="section">
|
||||||
|
<div class="section-title">Metriche Incidente</div>
|
||||||
|
|
||||||
|
<div class="metrics-grid">
|
||||||
|
<div class="metric-card">
|
||||||
|
<div class="metric-label">TTD (Time to Detect)</div>
|
||||||
|
<div class="metric-value success">0.5h</div>
|
||||||
|
<div style="font-size: 11px; color: var(--text-secondary); margin-top: 4px;">Target: <2h ✅</div>
|
||||||
|
</div>
|
||||||
|
<div class="metric-card">
|
||||||
|
<div class="metric-label">TTC (Time to Contain)</div>
|
||||||
|
<div class="metric-value success">2.2h</div>
|
||||||
|
<div style="font-size: 11px; color: var(--text-secondary); margin-top: 4px;">Target SEV-1: <1h ⚠️</div>
|
||||||
|
</div>
|
||||||
|
<div class="metric-card">
|
||||||
|
<div class="metric-label">TTR (Time to Recover)</div>
|
||||||
|
<div class="metric-value success">30.25h</div>
|
||||||
|
<div style="font-size: 11px; color: var(--text-secondary); margin-top: 4px;">RTO: ≤48h ✅</div>
|
||||||
|
</div>
|
||||||
|
<div class="metric-card">
|
||||||
|
<div class="metric-label">Downtime Totale</div>
|
||||||
|
<div class="metric-value warning">30h 15m</div>
|
||||||
|
<div style="font-size: 11px; color: var(--text-secondary); margin-top: 4px;">45 utenti impattati</div>
|
||||||
|
</div>
|
||||||
|
<div class="metric-card">
|
||||||
|
<div class="metric-label">Costo Stimato</div>
|
||||||
|
<div class="metric-value">€12.5K</div>
|
||||||
|
<div style="font-size: 11px; color: var(--text-secondary); margin-top: 4px;">Diretto + indiretto</div>
|
||||||
|
</div>
|
||||||
|
<div class="metric-card">
|
||||||
|
<div class="metric-label">Conformità Notifiche</div>
|
||||||
|
<div class="metric-value success">100%</div>
|
||||||
|
<div style="font-size: 11px; color: var(--text-secondary); margin-top: 4px;">CSIRT entro 24h ✅</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Root Cause Analysis -->
|
||||||
|
<div class="section">
|
||||||
|
<div class="section-title">Root Cause Analysis (5 Whys)</div>
|
||||||
|
|
||||||
|
<div style="background: var(--bg-tertiary); padding: 20px; border-radius: 6px; margin-bottom: 20px;">
|
||||||
|
<div style="margin-bottom: 16px;">
|
||||||
|
<strong style="color: var(--accent-primary);">Problema:</strong> Tentativo di attacco ransomware su server ERP
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="margin-bottom: 12px;">
|
||||||
|
<strong style="color: var(--text-primary);">1. Perché è successo?</strong><br>
|
||||||
|
<span style="color: var(--text-secondary);">→ Perché un utente ha aperto un allegato malevolo da email phishing</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="margin-bottom: 12px;">
|
||||||
|
<strong style="color: var(--text-primary);">2. Perché l'utente ha aperto l'allegato?</strong><br>
|
||||||
|
<span style="color: var(--text-secondary);">→ Perché l'email sembrava legittima (spoofing fornitore) e l'utente non ha riconosciuto i segnali di phishing</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="margin-bottom: 12px;">
|
||||||
|
<strong style="color: var(--text-primary);">3. Perché l'utente non ha riconosciuto il phishing?</strong><br>
|
||||||
|
<span style="color: var(--text-secondary);">→ Perché la formazione awareness sulla sicurezza non era sufficientemente frequente e pratica</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="margin-bottom: 12px;">
|
||||||
|
<strong style="color: var(--text-primary);">4. Perché le credenziali dell'utente erano già compromesse?</strong><br>
|
||||||
|
<span style="color: var(--text-secondary);">→ Perché l'utente utilizzava la stessa password su servizi esterni (credential stuffing attack non rilevato)</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<strong style="color: var(--text-primary);">5. Perché non c'era MFA obbligatoria su account amministrativi?</strong><br>
|
||||||
|
<span style="color: var(--text-secondary);">→ Perché la policy MFA era in fase di rollout graduale e non ancora applicata a tutti gli account admin</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="background: var(--bg-tertiary); padding: 16px; border-radius: 6px; border-left: 4px solid var(--danger);">
|
||||||
|
<strong style="color: var(--danger);">ROOT CAUSE IDENTIFICATA:</strong><br>
|
||||||
|
<span style="color: var(--text-secondary); font-size: 13px;">
|
||||||
|
1. MFA non obbligatoria su tutti gli account amministrativi<br>
|
||||||
|
2. Formazione awareness non sufficientemente efficace<br>
|
||||||
|
3. Monitoraggio credential stuffing non attivo<br>
|
||||||
|
4. Policy password debole (riutilizzo su servizi esterni)
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Valutazione Efficacia -->
|
||||||
|
<div class="section">
|
||||||
|
<div class="section-title">Valutazione Efficacia Risposta</div>
|
||||||
|
|
||||||
|
<table class="data-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Fase</th>
|
||||||
|
<th>Valutazione</th>
|
||||||
|
<th>Punti di Forza</th>
|
||||||
|
<th>Aree di Miglioramento</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td><strong>Rilevazione</strong></td>
|
||||||
|
<td><span style="color: var(--success); font-weight: 600;">✅ Eccellente</span></td>
|
||||||
|
<td>EDR ha bloccato immediatamente il malware. TTD: 0.5h</td>
|
||||||
|
<td>Nessuna - detection efficace</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>Triage</strong></td>
|
||||||
|
<td><span style="color: var(--success); font-weight: 600;">✅ Buono</span></td>
|
||||||
|
<td>Classificazione corretta entro 1h. Crisis Team attivato tempestivamente</td>
|
||||||
|
<td>Processo decisionale può essere ulteriormente accelerato</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>Contenimento</strong></td>
|
||||||
|
<td><span style="color: var(--warning); font-weight: 600;">⚠️ Sufficiente</span></td>
|
||||||
|
<td>Isolamento rapido. Nessuna propagazione</td>
|
||||||
|
<td>TTC 2.2h > target 1h per SEV-1. Procedure di isolamento da ottimizzare</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>Eradicazione</strong></td>
|
||||||
|
<td><span style="color: var(--success); font-weight: 600;">✅ Buono</span></td>
|
||||||
|
<td>Rimozione completa minaccia. Hardening applicato</td>
|
||||||
|
<td>Analisi forense richiede più tempo del previsto</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>Ripristino</strong></td>
|
||||||
|
<td><span style="color: var(--success); font-weight: 600;">✅ Buono</span></td>
|
||||||
|
<td>TTR 30.25h < RTO 48h. Backup immutabile efficace</td>
|
||||||
|
<td>Processo di verifica post-ripristino può essere standardizzato</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>Comunicazioni</strong></td>
|
||||||
|
<td><span style="color: var(--success); font-weight: 600;">✅ Eccellente</span></td>
|
||||||
|
<td>Preallarme CSIRT entro 24h. Comunicazioni interne tempestive</td>
|
||||||
|
<td>Template comunicazioni possono essere pre-compilati</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Gap Identificati -->
|
||||||
|
<div class="section">
|
||||||
|
<div class="section-title">Gap Identificati</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label">1. GAP TECNICI</label>
|
||||||
|
<textarea class="form-textarea" readonly>• MFA non obbligatoria su tutti gli account amministrativi
|
||||||
|
• Monitoraggio credential stuffing assente
|
||||||
|
• Filtri email anti-phishing non sufficientemente efficaci
|
||||||
|
• Procedure di isolamento automatico non implementate
|
||||||
|
• Tempo di contenimento superiore al target per SEV-1</textarea>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label">2. GAP PROCEDURALI</label>
|
||||||
|
<textarea class="form-textarea" readonly>• Policy MFA in rollout graduale (non completata)
|
||||||
|
• Procedura di isolamento rapido non documentata
|
||||||
|
• Checklist contenimento SEV-1 non disponibile in formato rapido
|
||||||
|
• Processo di escalation Crisis Team può essere ottimizzato
|
||||||
|
• Template comunicazioni non pre-compilati</textarea>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label">3. GAP ORGANIZZATIVI</label>
|
||||||
|
<textarea class="form-textarea" readonly>• Formazione awareness non sufficientemente frequente
|
||||||
|
• Simulazioni phishing non regolari
|
||||||
|
• Policy password debole (riutilizzo su servizi esterni non vietato esplicitamente)
|
||||||
|
• Competenze forensics interne limitate (dipendenza da consulenti esterni)</textarea>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label">4. GAP FORMATIVI</label>
|
||||||
|
<textarea class="form-textarea" readonly>• Utenti non addestrati a riconoscere phishing avanzato
|
||||||
|
• Account amministrativi senza formazione specifica su minacce mirate
|
||||||
|
• Awareness su riutilizzo password insufficiente
|
||||||
|
• Esercitazioni tabletop incident response non regolari</textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Azioni Correttive -->
|
||||||
|
<div class="section">
|
||||||
|
<div class="section-title">Piano Azioni Correttive</div>
|
||||||
|
|
||||||
|
<table class="data-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>ID</th>
|
||||||
|
<th>Azione Correttiva</th>
|
||||||
|
<th>Categoria</th>
|
||||||
|
<th>Priorità</th>
|
||||||
|
<th>Responsabile</th>
|
||||||
|
<th>Scadenza</th>
|
||||||
|
<th>Org. Rif.</th>
|
||||||
|
<th>Stato</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td><strong>AC-001</strong></td>
|
||||||
|
<td>Implementare MFA obbligatoria su TUTTI gli account amministrativi</td>
|
||||||
|
<td>Tecnica</td>
|
||||||
|
<td><span class="priority-high">ALTA</span></td>
|
||||||
|
<td>IT Manager</td>
|
||||||
|
<td>2024-03-20</td>
|
||||||
|
<td>Org.03</td>
|
||||||
|
<td><span class="status-badge status-progress">In corso</span></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>AC-002</strong></td>
|
||||||
|
<td>Implementare monitoraggio credential stuffing su SIEM</td>
|
||||||
|
<td>Tecnica</td>
|
||||||
|
<td><span class="priority-high">ALTA</span></td>
|
||||||
|
<td>SOC Lead</td>
|
||||||
|
<td>2024-03-25</td>
|
||||||
|
<td>Org.09</td>
|
||||||
|
<td><span class="status-badge status-planned">Pianificata</span></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>AC-003</strong></td>
|
||||||
|
<td>Rafforzare filtri anti-phishing email gateway</td>
|
||||||
|
<td>Tecnica</td>
|
||||||
|
<td><span class="priority-high">ALTA</span></td>
|
||||||
|
<td>IT Security</td>
|
||||||
|
<td>2024-03-15</td>
|
||||||
|
<td>Org.08</td>
|
||||||
|
<td><span class="status-badge status-progress">In corso</span></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>AC-004</strong></td>
|
||||||
|
<td>Implementare isolamento automatico endpoint compromessi</td>
|
||||||
|
<td>Tecnica</td>
|
||||||
|
<td><span class="priority-medium">MEDIA</span></td>
|
||||||
|
<td>IT Security</td>
|
||||||
|
<td>2024-04-15</td>
|
||||||
|
<td>Org.08</td>
|
||||||
|
<td><span class="status-badge status-planned">Pianificata</span></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>AC-005</strong></td>
|
||||||
|
<td>Aggiornare policy password (vietare riutilizzo su servizi esterni)</td>
|
||||||
|
<td>Procedurale</td>
|
||||||
|
<td><span class="priority-high">ALTA</span></td>
|
||||||
|
<td>CISO</td>
|
||||||
|
<td>2024-03-10</td>
|
||||||
|
<td>Org.03</td>
|
||||||
|
<td><span class="status-badge status-progress">In corso</span></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>AC-006</strong></td>
|
||||||
|
<td>Creare checklist rapida contenimento SEV-1</td>
|
||||||
|
<td>Procedurale</td>
|
||||||
|
<td><span class="priority-medium">MEDIA</span></td>
|
||||||
|
<td>CISO</td>
|
||||||
|
<td>2024-03-15</td>
|
||||||
|
<td>Org.10</td>
|
||||||
|
<td><span class="status-badge status-planned">Pianificata</span></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>AC-007</strong></td>
|
||||||
|
<td>Preparare template comunicazioni pre-compilati</td>
|
||||||
|
<td>Procedurale</td>
|
||||||
|
<td><span class="priority-low">BASSA</span></td>
|
||||||
|
<td>CISO</td>
|
||||||
|
<td>2024-04-30</td>
|
||||||
|
<td>Org.10</td>
|
||||||
|
<td><span class="status-badge status-planned">Pianificata</span></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>AC-008</strong></td>
|
||||||
|
<td>Aumentare frequenza formazione awareness (mensile)</td>
|
||||||
|
<td>Formativa</td>
|
||||||
|
<td><span class="priority-high">ALTA</span></td>
|
||||||
|
<td>HR + CISO</td>
|
||||||
|
<td>2024-04-01</td>
|
||||||
|
<td>Org.04</td>
|
||||||
|
<td><span class="status-badge status-planned">Pianificata</span></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>AC-009</strong></td>
|
||||||
|
<td>Implementare simulazioni phishing trimestrali</td>
|
||||||
|
<td>Formativa</td>
|
||||||
|
<td><span class="priority-medium">MEDIA</span></td>
|
||||||
|
<td>CISO</td>
|
||||||
|
<td>2024-04-15</td>
|
||||||
|
<td>Org.04</td>
|
||||||
|
<td><span class="status-badge status-planned">Pianificata</span></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>AC-010</strong></td>
|
||||||
|
<td>Formazione specifica account amministrativi su minacce mirate</td>
|
||||||
|
<td>Formativa</td>
|
||||||
|
<td><span class="priority-medium">MEDIA</span></td>
|
||||||
|
<td>CISO</td>
|
||||||
|
<td>2024-03-30</td>
|
||||||
|
<td>Org.04</td>
|
||||||
|
<td><span class="status-badge status-planned">Pianificata</span></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>AC-011</strong></td>
|
||||||
|
<td>Aggiornare risk assessment con nuovo scenario ransomware</td>
|
||||||
|
<td>Organizzativa</td>
|
||||||
|
<td><span class="priority-high">ALTA</span></td>
|
||||||
|
<td>CISO</td>
|
||||||
|
<td>2024-03-20</td>
|
||||||
|
<td>Org.05</td>
|
||||||
|
<td><span class="status-badge status-planned">Pianificata</span></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>AC-012</strong></td>
|
||||||
|
<td>Pianificare esercitazione tabletop ransomware</td>
|
||||||
|
<td>Organizzativa</td>
|
||||||
|
<td><span class="priority-medium">MEDIA</span></td>
|
||||||
|
<td>CISO</td>
|
||||||
|
<td>2024-05-31</td>
|
||||||
|
<td>Org.08</td>
|
||||||
|
<td><span class="status-badge status-planned">Pianificata</span></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<div style="margin-top: 24px; padding: 16px; background: var(--bg-tertiary); border-radius: 6px;">
|
||||||
|
<strong style="color: var(--text-primary);">Riepilogo Azioni:</strong><br>
|
||||||
|
<div style="display: flex; gap: 24px; margin-top: 12px; font-size: 13px;">
|
||||||
|
<div>
|
||||||
|
<span style="color: var(--text-secondary);">Totali:</span>
|
||||||
|
<strong style="color: var(--text-primary);"> 12</strong>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<span style="color: var(--text-secondary);">Alta priorità:</span>
|
||||||
|
<strong style="color: var(--danger);"> 6</strong>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<span style="color: var(--text-secondary);">Media priorità:</span>
|
||||||
|
<strong style="color: var(--warning);"> 5</strong>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<span style="color: var(--text-secondary);">Bassa priorità:</span>
|
||||||
|
<strong style="color: var(--text-secondary);"> 1</strong>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Raccomandazioni -->
|
||||||
|
<div class="section">
|
||||||
|
<div class="section-title">Raccomandazioni e Lesson Learned</div>
|
||||||
|
|
||||||
|
<div style="background: var(--bg-tertiary); padding: 20px; border-radius: 6px; margin-bottom: 16px;">
|
||||||
|
<h4 style="font-size: 14px; font-weight: 600; color: var(--success); margin-bottom: 12px;">
|
||||||
|
✅ COSA HA FUNZIONATO BENE
|
||||||
|
</h4>
|
||||||
|
<ul style="font-size: 13px; color: var(--text-secondary); line-height: 1.8; margin-left: 20px;">
|
||||||
|
<li>EDR ha bloccato immediatamente il ransomware prima della crittografia</li>
|
||||||
|
<li>Backup immutabile ha permesso ripristino rapido e sicuro</li>
|
||||||
|
<li>Crisis Team ha risposto prontamente e in modo coordinato</li>
|
||||||
|
<li>Comunicazioni CSIRT rispettate nei tempi (preallarme entro 24h)</li>
|
||||||
|
<li>Nessuna propagazione dell'attacco ad altri sistemi</li>
|
||||||
|
<li>Preservazione evidenze forensi efficace</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="background: var(--bg-tertiary); padding: 20px; border-radius: 6px; margin-bottom: 16px;">
|
||||||
|
<h4 style="font-size: 14px; font-weight: 600; color: var(--warning); margin-bottom: 12px;">
|
||||||
|
⚠️ COSA MIGLIORARE
|
||||||
|
</h4>
|
||||||
|
<ul style="font-size: 13px; color: var(--text-secondary); line-height: 1.8; margin-left: 20px;">
|
||||||
|
<li>Tempo di contenimento (2.2h) superiore al target per SEV-1 (<1h)</li>
|
||||||
|
<li>MFA non era obbligatoria su account amministrativi</li>
|
||||||
|
<li>Formazione awareness non sufficientemente efficace</li>
|
||||||
|
<li>Monitoraggio credential stuffing assente</li>
|
||||||
|
<li>Procedure di isolamento rapido non documentate</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="background: var(--bg-tertiary); padding: 20px; border-radius: 6px;">
|
||||||
|
<h4 style="font-size: 14px; font-weight: 600; color: var(--accent-primary); margin-bottom: 12px;">
|
||||||
|
💡 LESSON LEARNED CHIAVE
|
||||||
|
</h4>
|
||||||
|
<ol style="font-size: 13px; color: var(--text-secondary); line-height: 1.8; margin-left: 20px;">
|
||||||
|
<li><strong>MFA è fondamentale:</strong> L'assenza di MFA su account amministrativi è stata la vulnerabilità critica. Implementazione immediata obbligatoria.</li>
|
||||||
|
<li><strong>Backup immutabile salva:</strong> Il backup immutabile ha evitato perdita dati e permesso ripristino rapido. Investimento essenziale.</li>
|
||||||
|
<li><strong>EDR efficace ma non sufficiente:</strong> EDR ha bloccato il malware ma non ha prevenuto il phishing. Serve approccio multi-layer.</li>
|
||||||
|
<li><strong>Formazione continua necessaria:</strong> Awareness sporadica non è efficace. Serve formazione continua e simulazioni pratiche.</li>
|
||||||
|
<li><strong>Procedure automatiche riducono TTC:</strong> Isolamento manuale ha richiesto tempo. Automazione può ridurre significativamente TTC.</li>
|
||||||
|
<li><strong>Comunicazioni tempestive cruciali:</strong> Rispetto scadenze CSIRT e comunicazioni interne hanno evitato complicazioni legali/reputazionali.</li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Finalizzazione -->
|
||||||
|
<div class="section">
|
||||||
|
<div class="section-title">Finalizzazione Post-Incident Review</div>
|
||||||
|
|
||||||
|
<div style="background: var(--bg-tertiary); padding: 16px; border-radius: 6px; margin-bottom: 20px;">
|
||||||
|
<strong style="color: var(--text-primary);">Partecipanti PIR:</strong><br>
|
||||||
|
<ul style="font-size: 13px; color: var(--text-secondary); margin-top: 8px; margin-left: 20px;">
|
||||||
|
<li>CISO - P. Lombardi (coordinatore)</li>
|
||||||
|
<li>SOC Lead - L. Verdi</li>
|
||||||
|
<li>System Admin - G. Rossi</li>
|
||||||
|
<li>Forensics Team - A. Neri</li>
|
||||||
|
<li>IT Manager - M. Bianchi</li>
|
||||||
|
<li>Responsabile Divisione Finance - S. Neri</li>
|
||||||
|
<li>Direzione - CdA Representative</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="display: flex; gap: 12px; justify-content: flex-end; padding-top: 24px; border-top: 1px solid var(--border-color);">
|
||||||
|
<button class="btn" onclick="savePIRDraft()">Salva Bozza</button>
|
||||||
|
<button class="btn" onclick="exportPIR()">📄 Esporta Report</button>
|
||||||
|
<button class="btn btn-primary" onclick="completePIR()">✅ Finalizza PIR e Chiudi Incidente</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function savePIRDraft() {
|
||||||
|
alert('Bozza Post-Incident Review salvata con successo.');
|
||||||
|
}
|
||||||
|
|
||||||
|
function exportPIR() {
|
||||||
|
const tooltip = document.createElement('div');
|
||||||
|
tooltip.style.cssText = `
|
||||||
|
position: fixed;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
background: var(--bg-secondary);
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 24px;
|
||||||
|
box-shadow: 0 8px 24px rgba(0,0,0,0.5);
|
||||||
|
z-index: 10000;
|
||||||
|
max-width: 500px;
|
||||||
|
`;
|
||||||
|
tooltip.innerHTML = `
|
||||||
|
<h3 style="margin-bottom: 16px; color: var(--text-primary);">📄 Export Report Post-Incident Review</h3>
|
||||||
|
<p style="color: var(--text-secondary); margin-bottom: 16px; font-size: 13px;">
|
||||||
|
Report completo PIR per incidente INC-2024-047
|
||||||
|
</p>
|
||||||
|
<div style="background: var(--bg-tertiary); padding: 16px; border-radius: 4px; margin-bottom: 16px; font-family: monospace; font-size: 12px;">
|
||||||
|
📄 PIR_INC-2024-047_Report_Completo.pdf<br>
|
||||||
|
📄 PIR_INC-2024-047_Azioni_Correttive.xlsx<br>
|
||||||
|
📄 PIR_INC-2024-047_Executive_Summary.pdf<br>
|
||||||
|
📄 PIR_INC-2024-047_Lesson_Learned.docx
|
||||||
|
</div>
|
||||||
|
<button onclick="this.parentElement.remove()" style="width: 100%; padding: 10px; background: var(--accent-primary); border: none; border-radius: 6px; color: white; font-weight: 600; cursor: pointer;">
|
||||||
|
Chiudi
|
||||||
|
</button>
|
||||||
|
`;
|
||||||
|
document.body.appendChild(tooltip);
|
||||||
|
}
|
||||||
|
|
||||||
|
function completePIR() {
|
||||||
|
const tooltip = document.createElement('div');
|
||||||
|
tooltip.style.cssText = `
|
||||||
|
position: fixed;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
background: var(--bg-secondary);
|
||||||
|
border: 2px solid var(--success);
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 32px;
|
||||||
|
box-shadow: 0 8px 24px rgba(0,0,0,0.5);
|
||||||
|
z-index: 10000;
|
||||||
|
max-width: 600px;
|
||||||
|
text-align: center;
|
||||||
|
`;
|
||||||
|
tooltip.innerHTML = `
|
||||||
|
<div style="font-size: 48px; margin-bottom: 16px;">✅</div>
|
||||||
|
<h2 style="color: var(--success); margin-bottom: 16px;">Post-Incident Review Completata</h2>
|
||||||
|
<p style="color: var(--text-secondary); margin-bottom: 24px; font-size: 14px;">
|
||||||
|
Incidente INC-2024-047 ufficialmente chiuso
|
||||||
|
</p>
|
||||||
|
<div style="background: var(--bg-tertiary); padding: 20px; border-radius: 6px; margin-bottom: 24px; text-align: left;">
|
||||||
|
<p style="font-size: 13px; color: var(--text-secondary); margin-bottom: 12px;"><strong>Riepilogo Finale:</strong></p>
|
||||||
|
<ul style="font-size: 13px; color: var(--text-secondary); margin-left: 20px;">
|
||||||
|
<li>12 azioni correttive identificate e assegnate</li>
|
||||||
|
<li>6 azioni ad alta priorità in tracking</li>
|
||||||
|
<li>Risk assessment aggiornato (Org.05)</li>
|
||||||
|
<li>Lesson learned condivise con team</li>
|
||||||
|
<li>Report PIR distribuito a stakeholder</li>
|
||||||
|
<li>Relazione finale CSIRT da completare</li>
|
||||||
|
</ul>
|
||||||
|
<p style="font-size: 13px; color: var(--text-secondary); margin-top: 16px;">
|
||||||
|
<strong>Prossimi step:</strong> Monitoraggio azioni correttive tramite sistema non conformità (ID.IM-01)
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div style="display: flex; gap: 12px;">
|
||||||
|
<button onclick="window.location.href='incident-dashboard.html'" style="flex: 1; padding: 12px; background: var(--bg-tertiary); border: 1px solid var(--border-color); border-radius: 6px; color: var(--text-primary); font-weight: 600; cursor: pointer;">
|
||||||
|
Dashboard Incidenti
|
||||||
|
</button>
|
||||||
|
<button onclick="window.location.href='incident-notification.html?id=INC-2024-047&action=final'" style="flex: 1; padding: 12px; background: var(--accent-primary); border: none; border-radius: 6px; color: white; font-weight: 600; cursor: pointer;">
|
||||||
|
Completa Relazione Finale CSIRT
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
document.body.appendChild(tooltip);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
660
docs/nis2/incidente_r01/incident-recovery.html
Normal file
660
docs/nis2/incidente_r01/incident-recovery.html
Normal file
@ -0,0 +1,660 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="it">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Ripristino Servizi - INC-2024-047</title>
|
||||||
|
<style>
|
||||||
|
:root {
|
||||||
|
--bg-primary: #0d1117;
|
||||||
|
--bg-secondary: #161b22;
|
||||||
|
--bg-tertiary: #1c2128;
|
||||||
|
--border-color: #30363d;
|
||||||
|
--text-primary: #c9d1d9;
|
||||||
|
--text-secondary: #8b949e;
|
||||||
|
--accent-primary: #58a6ff;
|
||||||
|
--success: #3fb950;
|
||||||
|
--warning: #d29922;
|
||||||
|
--danger: #f85149;
|
||||||
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Noto Sans', Helvetica, Arial, sans-serif;
|
||||||
|
background-color: var(--bg-primary);
|
||||||
|
color: var(--text-primary);
|
||||||
|
line-height: 1.6;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 1400px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
background-color: var(--bg-secondary);
|
||||||
|
border-bottom: 1px solid var(--border-color);
|
||||||
|
padding: 24px 0;
|
||||||
|
margin-bottom: 32px;
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
z-index: 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-content {
|
||||||
|
max-width: 1400px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0 20px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header h1 {
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.breadcrumb {
|
||||||
|
font-size: 13px;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
margin-top: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.breadcrumb a {
|
||||||
|
color: var(--accent-primary);
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
padding: 8px 16px;
|
||||||
|
background-color: var(--bg-tertiary);
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
border-radius: 6px;
|
||||||
|
color: var(--text-primary);
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 500;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn:hover {
|
||||||
|
border-color: var(--accent-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-success {
|
||||||
|
background-color: var(--success);
|
||||||
|
border-color: var(--success);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-success:hover {
|
||||||
|
background-color: #2ea043;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert-box {
|
||||||
|
background-color: rgba(88, 166, 255, 0.1);
|
||||||
|
border: 1px solid var(--accent-primary);
|
||||||
|
border-left: 4px solid var(--accent-primary);
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 20px;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert-title {
|
||||||
|
font-weight: 600;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert-content {
|
||||||
|
font-size: 13px;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section {
|
||||||
|
background-color: var(--bg-secondary);
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 24px;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text-primary);
|
||||||
|
margin-bottom: 20px;
|
||||||
|
padding-bottom: 12px;
|
||||||
|
border-bottom: 1px solid var(--border-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.checklist {
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checklist li {
|
||||||
|
padding: 12px;
|
||||||
|
background-color: var(--bg-tertiary);
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
border-radius: 4px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checklist input[type="checkbox"] {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checklist li.completed {
|
||||||
|
background-color: rgba(63, 185, 80, 0.1);
|
||||||
|
border-color: var(--success);
|
||||||
|
}
|
||||||
|
|
||||||
|
.priority-badge {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 4px 8px;
|
||||||
|
border-radius: 3px;
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: 700;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.priority-1 {
|
||||||
|
background-color: rgba(248, 81, 73, 0.2);
|
||||||
|
color: var(--danger);
|
||||||
|
border: 1px solid var(--danger);
|
||||||
|
}
|
||||||
|
|
||||||
|
.priority-2 {
|
||||||
|
background-color: rgba(210, 153, 34, 0.2);
|
||||||
|
color: var(--warning);
|
||||||
|
border: 1px solid var(--warning);
|
||||||
|
}
|
||||||
|
|
||||||
|
.data-table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.data-table th {
|
||||||
|
background-color: var(--bg-tertiary);
|
||||||
|
color: var(--text-secondary);
|
||||||
|
font-weight: 600;
|
||||||
|
text-align: left;
|
||||||
|
padding: 10px 12px;
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
font-size: 11px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.data-table td {
|
||||||
|
padding: 10px 12px;
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
color: var(--text-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.data-table tr:hover {
|
||||||
|
background-color: var(--bg-tertiary);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="header">
|
||||||
|
<div class="header-content">
|
||||||
|
<div>
|
||||||
|
<h1>🔄 Ripristino Servizi - INC-2024-047</h1>
|
||||||
|
<div class="breadcrumb">
|
||||||
|
<a href="dashboard.html">Dashboard NIS2</a> /
|
||||||
|
<a href="incident-dashboard.html">Gestione Incidenti</a> /
|
||||||
|
<a href="incident-detail.html?id=INC-2024-047">INC-2024-047</a> /
|
||||||
|
Ripristino
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<a href="incident-detail.html?id=INC-2024-047" class="btn">← Torna all'Incidente</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<div class="alert-box">
|
||||||
|
<div class="alert-title">ℹ️ Processo di Ripristino (RC.RP-01)</div>
|
||||||
|
<div class="alert-content">
|
||||||
|
Ripristino graduale dei servizi secondo priorità BIA. Ogni sistema deve essere verificato per integrità,
|
||||||
|
funzionalità e sicurezza prima del ripristino in produzione. Monitoraggio intensivo post-ripristino per 72 ore.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Priorità Ripristino -->
|
||||||
|
<div class="section">
|
||||||
|
<div class="section-title">Priorità Ripristino (secondo BIA Org.08)</div>
|
||||||
|
|
||||||
|
<table class="data-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Priorità</th>
|
||||||
|
<th>Sistema/Servizio</th>
|
||||||
|
<th>RTO Dichiarato</th>
|
||||||
|
<th>Stato</th>
|
||||||
|
<th>ETA Ripristino</th>
|
||||||
|
<th>Azioni</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td><span class="priority-badge priority-1">P1 - Critico</span></td>
|
||||||
|
<td><strong>Server ERP-PROD-01</strong><br>Sistema gestionale principale</td>
|
||||||
|
<td>≤4h</td>
|
||||||
|
<td><span style="color: var(--warning);">🔄 In ripristino</span></td>
|
||||||
|
<td>2024-03-08 14:00</td>
|
||||||
|
<td><button class="btn" onclick="viewRecoveryDetails('erp')">Dettagli</button></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><span class="priority-badge priority-1">P1 - Critico</span></td>
|
||||||
|
<td><strong>Applicazione SAP ERP</strong><br>Software gestionale</td>
|
||||||
|
<td>≤4h</td>
|
||||||
|
<td><span style="color: var(--text-secondary);">⏸️ In attesa server</span></td>
|
||||||
|
<td>2024-03-08 16:00</td>
|
||||||
|
<td><button class="btn" disabled>In attesa</button></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Checklist Ripristino -->
|
||||||
|
<div class="section">
|
||||||
|
<div class="section-title">Checklist Ripristino Server ERP-PROD-01</div>
|
||||||
|
|
||||||
|
<h3 style="font-size: 16px; font-weight: 600; margin-bottom: 16px; color: var(--text-primary);">1. Valutazione Pre-Ripristino</h3>
|
||||||
|
<ul class="checklist">
|
||||||
|
<li class="completed">
|
||||||
|
<input type="checkbox" checked disabled>
|
||||||
|
<span>Minaccia completamente rimossa ed eradicata</span>
|
||||||
|
</li>
|
||||||
|
<li class="completed">
|
||||||
|
<input type="checkbox" checked disabled>
|
||||||
|
<span>Nessun indicatore di compromissione residuo</span>
|
||||||
|
</li>
|
||||||
|
<li class="completed">
|
||||||
|
<input type="checkbox" checked disabled>
|
||||||
|
<span>Backup verificato e integro (hash matching)</span>
|
||||||
|
</li>
|
||||||
|
<li class="completed">
|
||||||
|
<input type="checkbox" checked disabled>
|
||||||
|
<span>Strategia di ripristino definita: Ripristino da backup immutabile</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h3 style="font-size: 16px; font-weight: 600; margin: 24px 0 16px; color: var(--text-primary);">2. Ripristino Sistema</h3>
|
||||||
|
<ul class="checklist">
|
||||||
|
<li class="completed">
|
||||||
|
<input type="checkbox" checked disabled>
|
||||||
|
<span>Ripristino da backup immutabile avviato (2024-03-07 10:00)</span>
|
||||||
|
</li>
|
||||||
|
<li class="completed">
|
||||||
|
<input type="checkbox" checked disabled>
|
||||||
|
<span>Sistema operativo ripristinato e verificato</span>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="check1" onchange="updateProgress()">
|
||||||
|
<span>Applicazione ERP ripristinata e configurata</span>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="check2" onchange="updateProgress()">
|
||||||
|
<span>Database ripristinato e verificato integrità</span>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="check3" onchange="updateProgress()">
|
||||||
|
<span>Patch di sicurezza applicati (ultimi aggiornamenti)</span>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="check4" onchange="updateProgress()">
|
||||||
|
<span>Configurazione hardening applicata (baseline CIS)</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h3 style="font-size: 16px; font-weight: 600; margin: 24px 0 16px; color: var(--text-primary);">3. Verifica Integrità e Sicurezza</h3>
|
||||||
|
<ul class="checklist">
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="check5" onchange="updateProgress()">
|
||||||
|
<span>Integrità dati verificata (confronto checksum con backup)</span>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="check6" onchange="updateProgress()">
|
||||||
|
<span>Test funzionali applicativi completati con successo</span>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="check7" onchange="updateProgress()">
|
||||||
|
<span>Scansione antimalware completa (nessuna minaccia rilevata)</span>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="check8" onchange="updateProgress()">
|
||||||
|
<span>Verifica assenza IoC residui</span>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="check9" onchange="updateProgress()">
|
||||||
|
<span>Configurazione EDR verificata e attiva</span>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="check10" onchange="updateProgress()">
|
||||||
|
<span>Log attivi e integrati nel SIEM</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h3 style="font-size: 16px; font-weight: 600; margin: 24px 0 16px; color: var(--text-primary);">4. Ripristino Accessi</h3>
|
||||||
|
<ul class="checklist">
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="check11" onchange="updateProgress()">
|
||||||
|
<span>Reset credenziali per tutti gli account potenzialmente compromessi</span>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="check12" onchange="updateProgress()">
|
||||||
|
<span>MFA verificata e funzionante per tutti gli account admin</span>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="check13" onchange="updateProgress()">
|
||||||
|
<span>Riattivazione accessi graduale per ruolo (admin → power user → user)</span>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="check14" onchange="updateProgress()">
|
||||||
|
<span>Monitoraggio accessi post-ripristino attivato</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h3 style="font-size: 16px; font-weight: 600; margin: 24px 0 16px; color: var(--text-primary);">5. Ripristino Connettività</h3>
|
||||||
|
<ul class="checklist">
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="check15" onchange="updateProgress()">
|
||||||
|
<span>Regole firewall aggiornate (IP C2 bloccati permanentemente)</span>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="check16" onchange="updateProgress()">
|
||||||
|
<span>Segmentazione rete verificata</span>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="check17" onchange="updateProgress()">
|
||||||
|
<span>Test connettività end-to-end completati</span>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="check18" onchange="updateProgress()">
|
||||||
|
<span>Monitoraggio traffico anomalo attivo</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h3 style="font-size: 16px; font-weight: 600; margin: 24px 0 16px; color: var(--text-primary);">6. Validazione Finale</h3>
|
||||||
|
<ul class="checklist">
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="check19" onchange="updateProgress()">
|
||||||
|
<span>Sign-off tecnico: Team Incident Response</span>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="check20" onchange="updateProgress()">
|
||||||
|
<span>Sign-off business: Responsabile Divisione</span>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="check21" onchange="updateProgress()">
|
||||||
|
<span>Sign-off sicurezza: CISO</span>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="check22" onchange="updateProgress()">
|
||||||
|
<span>Dichiarazione di ripristino completato</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div style="margin-top: 24px; padding: 20px; background: var(--bg-tertiary); border-radius: 6px; display: flex; justify-content: space-between; align-items: center;">
|
||||||
|
<div>
|
||||||
|
<div style="font-size: 13px; color: var(--text-secondary); margin-bottom: 8px;">Progresso Ripristino</div>
|
||||||
|
<div style="font-size: 24px; font-weight: 700; color: var(--text-primary);" id="progressText">9%</div>
|
||||||
|
</div>
|
||||||
|
<button class="btn btn-success" onclick="completeRecovery()" id="completeBtn" disabled style="opacity: 0.5;">
|
||||||
|
✅ Completa Ripristino
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Monitoraggio Post-Ripristino -->
|
||||||
|
<div class="section">
|
||||||
|
<div class="section-title">Piano Monitoraggio Post-Ripristino</div>
|
||||||
|
|
||||||
|
<div style="background: var(--bg-tertiary); padding: 16px; border-radius: 6px; margin-bottom: 16px;">
|
||||||
|
<h4 style="font-size: 14px; font-weight: 600; color: var(--text-primary); margin-bottom: 12px;">
|
||||||
|
📊 Monitoraggio Intensivo (72 ore)
|
||||||
|
</h4>
|
||||||
|
<ul style="font-size: 13px; color: var(--text-secondary); line-height: 1.8; margin-left: 20px;">
|
||||||
|
<li>Monitoraggio continuo 24/7 da SOC</li>
|
||||||
|
<li>Soglie di alerting ridotte (maggiore sensibilità)</li>
|
||||||
|
<li>Threat hunting mirato ogni 8 ore</li>
|
||||||
|
<li>Report giornaliero stato sistema</li>
|
||||||
|
<li>Verifica integrità file system ogni 12 ore</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="background: var(--bg-tertiary); padding: 16px; border-radius: 6px; margin-bottom: 16px;">
|
||||||
|
<h4 style="font-size: 14px; font-weight: 600; color: var(--text-primary); margin-bottom: 12px;">
|
||||||
|
📈 Monitoraggio Elevato (30 giorni)
|
||||||
|
</h4>
|
||||||
|
<ul style="font-size: 13px; color: var(--text-secondary); line-height: 1.8; margin-left: 20px;">
|
||||||
|
<li>Monitoraggio continuo con priorità alta</li>
|
||||||
|
<li>Threat hunting settimanale</li>
|
||||||
|
<li>Report settimanale a CISO</li>
|
||||||
|
<li>Verifica periodica IoC</li>
|
||||||
|
<li>Analisi comportamentale utenti e processi</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<table class="data-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Metrica</th>
|
||||||
|
<th>Baseline Pre-Incidente</th>
|
||||||
|
<th>Target Post-Ripristino</th>
|
||||||
|
<th>Frequenza Check</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>CPU Usage</td>
|
||||||
|
<td>45-60%</td>
|
||||||
|
<td>45-60% (±5%)</td>
|
||||||
|
<td>Ogni 5 minuti</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Memory Usage</td>
|
||||||
|
<td>70-75%</td>
|
||||||
|
<td>70-75% (±5%)</td>
|
||||||
|
<td>Ogni 5 minuti</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Network Traffic</td>
|
||||||
|
<td>2-5 Gbps</td>
|
||||||
|
<td>2-5 Gbps</td>
|
||||||
|
<td>Continuo</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Failed Login Attempts</td>
|
||||||
|
<td><5/ora</td>
|
||||||
|
<td><3/ora</td>
|
||||||
|
<td>Real-time</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Processi Anomali</td>
|
||||||
|
<td>0</td>
|
||||||
|
<td>0</td>
|
||||||
|
<td>Ogni 15 minuti</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Connessioni Esterne Sospette</td>
|
||||||
|
<td>0</td>
|
||||||
|
<td>0</td>
|
||||||
|
<td>Real-time</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Comunicazioni Ripristino -->
|
||||||
|
<div class="section">
|
||||||
|
<div class="section-title">Comunicazioni Ripristino Completato</div>
|
||||||
|
|
||||||
|
<div style="background: var(--bg-tertiary); padding: 16px; border-radius: 6px; margin-bottom: 16px;">
|
||||||
|
<h4 style="font-size: 14px; font-weight: 600; color: var(--text-primary); margin-bottom: 12px;">
|
||||||
|
📧 Template Comunicazione Interna
|
||||||
|
</h4>
|
||||||
|
<div style="font-size: 13px; color: var(--text-secondary); line-height: 1.8; font-family: monospace; background: var(--bg-primary); padding: 12px; border-radius: 4px;">
|
||||||
|
<strong>Oggetto:</strong> Ripristino Servizio ERP Completato<br><br>
|
||||||
|
Gentili colleghi,<br><br>
|
||||||
|
Vi informiamo che il servizio ERP è stato completamente ripristinato e
|
||||||
|
risulta nuovamente operativo a partire dalle ore [DATA/ORA].<br><br>
|
||||||
|
<strong>Azioni richieste agli utenti:</strong><br>
|
||||||
|
• Effettuare reset password al primo accesso<br>
|
||||||
|
• Verificare che MFA sia attiva<br>
|
||||||
|
• Segnalare immediatamente qualsiasi comportamento anomalo<br><br>
|
||||||
|
Il sistema è sotto monitoraggio intensivo per le prossime 72 ore.<br><br>
|
||||||
|
Per qualsiasi problema contattare l'helpdesk.<br><br>
|
||||||
|
Grazie per la collaborazione.<br>
|
||||||
|
IT Security Team
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="background: var(--bg-tertiary); padding: 16px; border-radius: 6px;">
|
||||||
|
<h4 style="font-size: 14px; font-weight: 600; color: var(--text-primary); margin-bottom: 12px;">
|
||||||
|
📡 Aggiornamento CSIRT Italia
|
||||||
|
</h4>
|
||||||
|
<div style="font-size: 13px; color: var(--text-secondary); line-height: 1.8;">
|
||||||
|
Aggiornare la notifica CSIRT con informazioni sul ripristino completato:
|
||||||
|
<ul style="margin-left: 20px; margin-top: 8px;">
|
||||||
|
<li>Data/ora ripristino completato</li>
|
||||||
|
<li>Servizi ripristinati</li>
|
||||||
|
<li>Downtime totale effettivo vs RTO</li>
|
||||||
|
<li>Misure di hardening applicate</li>
|
||||||
|
<li>Piano di monitoraggio post-ripristino</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function updateProgress() {
|
||||||
|
const total = 22;
|
||||||
|
let checked = 2; // I primi 2 sono già checked
|
||||||
|
|
||||||
|
for (let i = 1; i <= 22; i++) {
|
||||||
|
const checkbox = document.getElementById('check' + i);
|
||||||
|
if (checkbox && checkbox.checked) {
|
||||||
|
checked++;
|
||||||
|
checkbox.parentElement.classList.add('completed');
|
||||||
|
} else if (checkbox) {
|
||||||
|
checkbox.parentElement.classList.remove('completed');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const percentage = Math.round((checked / total) * 100);
|
||||||
|
document.getElementById('progressText').textContent = percentage + '%';
|
||||||
|
|
||||||
|
const completeBtn = document.getElementById('completeBtn');
|
||||||
|
if (percentage === 100) {
|
||||||
|
completeBtn.disabled = false;
|
||||||
|
completeBtn.style.opacity = '1';
|
||||||
|
} else {
|
||||||
|
completeBtn.disabled = true;
|
||||||
|
completeBtn.style.opacity = '0.5';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function completeRecovery() {
|
||||||
|
const tooltip = document.createElement('div');
|
||||||
|
tooltip.style.cssText = `
|
||||||
|
position: fixed;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
background: var(--bg-secondary);
|
||||||
|
border: 2px solid var(--success);
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 32px;
|
||||||
|
box-shadow: 0 8px 24px rgba(0,0,0,0.5);
|
||||||
|
z-index: 10000;
|
||||||
|
max-width: 600px;
|
||||||
|
text-align: center;
|
||||||
|
`;
|
||||||
|
tooltip.innerHTML = `
|
||||||
|
<div style="font-size: 48px; margin-bottom: 16px;">✅</div>
|
||||||
|
<h2 style="color: var(--success); margin-bottom: 16px;">Ripristino Completato con Successo</h2>
|
||||||
|
<div style="background: var(--bg-tertiary); padding: 20px; border-radius: 6px; margin-bottom: 24px; text-align: left;">
|
||||||
|
<p style="font-size: 13px; color: var(--text-secondary); margin-bottom: 12px;"><strong>Riepilogo Ripristino:</strong></p>
|
||||||
|
<table style="width: 100%; font-size: 13px; color: var(--text-secondary);">
|
||||||
|
<tr>
|
||||||
|
<td><strong>Sistema:</strong></td>
|
||||||
|
<td>ERP-PROD-01</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>Data ripristino:</strong></td>
|
||||||
|
<td>${new Date().toLocaleString('it-IT')}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>Downtime totale:</strong></td>
|
||||||
|
<td>30h 15m</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>RTO dichiarato:</strong></td>
|
||||||
|
<td>≤48h</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>Conformità RTO:</strong></td>
|
||||||
|
<td style="color: var(--success); font-weight: 600;">✅ Rispettato</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>TTR (Time to Recover):</strong></td>
|
||||||
|
<td>30.25h</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<p style="font-size: 13px; color: var(--text-secondary); margin-top: 16px;">
|
||||||
|
<strong>Stato:</strong> Sistema operativo, monitoraggio intensivo attivo per 72 ore.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div style="background: var(--bg-tertiary); padding: 16px; border-radius: 6px; margin-bottom: 24px; text-align: left;">
|
||||||
|
<p style="font-size: 13px; color: var(--text-secondary); margin-bottom: 12px;"><strong>Prossime azioni:</strong></p>
|
||||||
|
<ul style="font-size: 13px; color: var(--text-secondary); margin-left: 20px;">
|
||||||
|
<li>Comunicazione utenti inviata</li>
|
||||||
|
<li>Aggiornamento notifica CSIRT</li>
|
||||||
|
<li>Monitoraggio intensivo 72h avviato</li>
|
||||||
|
<li>Pianificazione Post-Incident Review</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div style="display: flex; gap: 12px;">
|
||||||
|
<button onclick="window.location.href='incident-detail.html?id=INC-2024-047'" style="flex: 1; padding: 12px; background: var(--bg-tertiary); border: 1px solid var(--border-color); border-radius: 6px; color: var(--text-primary); font-weight: 600; cursor: pointer;">
|
||||||
|
Torna all'Incidente
|
||||||
|
</button>
|
||||||
|
<button onclick="window.location.href='incident-pir.html?id=INC-2024-047'" style="flex: 1; padding: 12px; background: var(--accent-primary); border: none; border-radius: 6px; color: white; font-weight: 600; cursor: pointer;">
|
||||||
|
Avvia Post-Incident Review
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
document.body.appendChild(tooltip);
|
||||||
|
}
|
||||||
|
|
||||||
|
function viewRecoveryDetails(system) {
|
||||||
|
alert('Dettagli processo di ripristino per: ' + system);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inizializza progresso
|
||||||
|
window.addEventListener('DOMContentLoaded', updateProgress);
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
66
docs/sql/020_asset_relevance.sql
Normal file
66
docs/sql/020_asset_relevance.sql
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
-- ============================================================================
|
||||||
|
-- Migration 020 - Asset Relevance Scoring (NIS2 GV.OC-04)
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
-- Aggiunge la metodologia di scoring rilevanza NIS2 (0-100, 6 criteri pesati)
|
||||||
|
-- alla tabella assets. Adattata dai mockup docs/nis2/assets.html +
|
||||||
|
-- doc-relevant-systems.html (Determina/metodologia CdA, soglia >=40 rilevante).
|
||||||
|
--
|
||||||
|
-- Criteri: C1 Criticita Operativa (0-25), C2 Impatto Interruzione (0-25),
|
||||||
|
-- C3 Dati Trattati (0-20), C4 Dipendenze (0-15),
|
||||||
|
-- C5 Esposizione (0-10), C6 Obblighi Normativi (0-5).
|
||||||
|
-- Classificazione: >=80 critico | 60-79 alto | 40-59 medio | 20-39 basso | <20 trascurabile
|
||||||
|
-- Rilevanza NIS2: score >= 40.
|
||||||
|
--
|
||||||
|
-- IMPORTANTE (vedi CLAUDE.md / memoria): MySQL 8 Ubuntu NON supporta
|
||||||
|
-- "ADD COLUMN IF NOT EXISTS". Questo script usa una stored procedure idempotente
|
||||||
|
-- che verifica information_schema prima di ogni ALTER. Rilanciabile senza danni.
|
||||||
|
-- Eseguire con: mysql -h localhost nis2_agile_db -e "source docs/sql/020_asset_relevance.sql"
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
DELIMITER //
|
||||||
|
|
||||||
|
DROP PROCEDURE IF EXISTS _mig020_add_col //
|
||||||
|
CREATE PROCEDURE _mig020_add_col(IN col VARCHAR(64), IN ddl TEXT)
|
||||||
|
BEGIN
|
||||||
|
IF NOT EXISTS (
|
||||||
|
SELECT 1 FROM information_schema.COLUMNS
|
||||||
|
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'assets' AND COLUMN_NAME = col
|
||||||
|
) THEN
|
||||||
|
SET @sql = CONCAT('ALTER TABLE assets ADD COLUMN ', ddl);
|
||||||
|
PREPARE st FROM @sql; EXECUTE st; DEALLOCATE PREPARE st;
|
||||||
|
END IF;
|
||||||
|
END //
|
||||||
|
|
||||||
|
DELIMITER ;
|
||||||
|
|
||||||
|
CALL _mig020_add_col('relevance_score', "relevance_score TINYINT UNSIGNED NULL COMMENT 'Punteggio rilevanza NIS2 0-100'");
|
||||||
|
CALL _mig020_add_col('relevance_criteria', "relevance_criteria JSON NULL COMMENT 'Dettaglio punteggi C1-C6 per audit'");
|
||||||
|
CALL _mig020_add_col('relevance_class', "relevance_class ENUM('critico','alto','medio','basso','trascurabile') NULL");
|
||||||
|
CALL _mig020_add_col('is_nis2_relevant', "is_nis2_relevant TINYINT(1) NOT NULL DEFAULT 0 COMMENT '1 se score >= 40'");
|
||||||
|
CALL _mig020_add_col('relevance_assessed_at', "relevance_assessed_at DATETIME NULL");
|
||||||
|
CALL _mig020_add_col('relevance_assessed_by', "relevance_assessed_by INT NULL");
|
||||||
|
|
||||||
|
DROP PROCEDURE IF EXISTS _mig020_add_col;
|
||||||
|
|
||||||
|
-- Indice per filtri "sistemi rilevanti" (idempotente via check)
|
||||||
|
DELIMITER //
|
||||||
|
DROP PROCEDURE IF EXISTS _mig020_add_idx //
|
||||||
|
CREATE PROCEDURE _mig020_add_idx()
|
||||||
|
BEGIN
|
||||||
|
IF NOT EXISTS (
|
||||||
|
SELECT 1 FROM information_schema.STATISTICS
|
||||||
|
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'assets' AND INDEX_NAME = 'idx_relevance'
|
||||||
|
) THEN
|
||||||
|
ALTER TABLE assets ADD INDEX idx_relevance (is_nis2_relevant, relevance_score);
|
||||||
|
END IF;
|
||||||
|
END //
|
||||||
|
DELIMITER ;
|
||||||
|
CALL _mig020_add_idx();
|
||||||
|
DROP PROCEDURE IF EXISTS _mig020_add_idx;
|
||||||
|
|
||||||
|
-- ROLLBACK (manuale):
|
||||||
|
-- ALTER TABLE assets
|
||||||
|
-- DROP COLUMN relevance_score, DROP COLUMN relevance_criteria,
|
||||||
|
-- DROP COLUMN relevance_class, DROP COLUMN is_nis2_relevant,
|
||||||
|
-- DROP COLUMN relevance_assessed_at, DROP COLUMN relevance_assessed_by,
|
||||||
|
-- DROP INDEX idx_relevance;
|
||||||
36
docs/sql/021_incident_nis2_taxonomy.sql
Normal file
36
docs/sql/021_incident_nis2_taxonomy.sql
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
-- ============================================================================
|
||||||
|
-- Migration 021 - Tassonomia Incidenti NIS2 (Determina ACN 164179/2025)
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
-- Aggiunge alla tabella incidents:
|
||||||
|
-- - nis2_incident_type: tipologia incidente significativo IS-1/IS-2/IS-3/IS-4
|
||||||
|
-- (Determinazione ACN n. 164179 del 14/04/2025, Allegati 3 e 4).
|
||||||
|
-- - entity_obligation: regime di obblighi applicabile (essential=Allegato 3,
|
||||||
|
-- important=Allegato 4). I soggetti importanti NON sono tenuti all'IS-4
|
||||||
|
-- (incidenti ricorrenti).
|
||||||
|
--
|
||||||
|
-- Fonte: D.Lgs. 138/2024 art. 23 + Determina ACN 164179/2025.
|
||||||
|
-- Idempotente via information_schema. Rilanciabile.
|
||||||
|
-- mysql -h localhost nis2_agile_db -e "source docs/sql/021_incident_nis2_taxonomy.sql"
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
DELIMITER //
|
||||||
|
DROP PROCEDURE IF EXISTS _mig021_add_col //
|
||||||
|
CREATE PROCEDURE _mig021_add_col(IN col VARCHAR(64), IN ddl TEXT)
|
||||||
|
BEGIN
|
||||||
|
IF NOT EXISTS (
|
||||||
|
SELECT 1 FROM information_schema.COLUMNS
|
||||||
|
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'incidents' AND COLUMN_NAME = col
|
||||||
|
) THEN
|
||||||
|
SET @sql = CONCAT('ALTER TABLE incidents ADD COLUMN ', ddl);
|
||||||
|
PREPARE st FROM @sql; EXECUTE st; DEALLOCATE PREPARE st;
|
||||||
|
END IF;
|
||||||
|
END //
|
||||||
|
DELIMITER ;
|
||||||
|
|
||||||
|
CALL _mig021_add_col('nis2_incident_type', "nis2_incident_type ENUM('IS-1','IS-2','IS-3','IS-4') NULL COMMENT 'Tipologia incidente significativo - Determina ACN 164179/2025'");
|
||||||
|
CALL _mig021_add_col('entity_obligation', "entity_obligation ENUM('essential','important') NULL COMMENT 'Regime obblighi: essential=Allegato 3, important=Allegato 4'");
|
||||||
|
|
||||||
|
DROP PROCEDURE IF EXISTS _mig021_add_col;
|
||||||
|
|
||||||
|
-- ROLLBACK:
|
||||||
|
-- ALTER TABLE incidents DROP COLUMN nis2_incident_type, DROP COLUMN entity_obligation;
|
||||||
73
docs/sql/022_incident_metrics_pir.sql
Normal file
73
docs/sql/022_incident_metrics_pir.sql
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
-- ============================================================================
|
||||||
|
-- Migration 022 - Metriche Incidente (TTD/TTC/TTR) + Post-Incident Review
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
-- 1) Timestamp di fase su incidents per calcolare le metriche:
|
||||||
|
-- triaged_at, contained_at, eradicated_at, recovered_at.
|
||||||
|
-- (la tabella aveva solo detected_at e closed_at)
|
||||||
|
-- TTD = triaged_at - detected_at (Time to Detect/triage)
|
||||||
|
-- TTC = contained_at - detected_at (Time to Contain)
|
||||||
|
-- TTR = recovered_at - detected_at (Time to Recover)
|
||||||
|
-- 2) Tabella incident_pir: Post-Incident Review strutturato (RC.CO-03 / NIST CSF),
|
||||||
|
-- con Root Cause Analysis 5-Whys, metriche, costo stimato, lesson learned.
|
||||||
|
--
|
||||||
|
-- Idempotente. mysql -h localhost nis2_agile_db -e "source docs/sql/022_incident_metrics_pir.sql"
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
DELIMITER //
|
||||||
|
DROP PROCEDURE IF EXISTS _mig022_add_col //
|
||||||
|
CREATE PROCEDURE _mig022_add_col(IN col VARCHAR(64), IN ddl TEXT)
|
||||||
|
BEGIN
|
||||||
|
IF NOT EXISTS (
|
||||||
|
SELECT 1 FROM information_schema.COLUMNS
|
||||||
|
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'incidents' AND COLUMN_NAME = col
|
||||||
|
) THEN
|
||||||
|
SET @sql = CONCAT('ALTER TABLE incidents ADD COLUMN ', ddl);
|
||||||
|
PREPARE st FROM @sql; EXECUTE st; DEALLOCATE PREPARE st;
|
||||||
|
END IF;
|
||||||
|
END //
|
||||||
|
DELIMITER ;
|
||||||
|
|
||||||
|
CALL _mig022_add_col('triaged_at', "triaged_at DATETIME NULL COMMENT 'Inizio triage'");
|
||||||
|
CALL _mig022_add_col('contained_at', "contained_at DATETIME NULL COMMENT 'Incidente contenuto'");
|
||||||
|
CALL _mig022_add_col('eradicated_at', "eradicated_at DATETIME NULL COMMENT 'Minaccia eradicata'");
|
||||||
|
CALL _mig022_add_col('recovered_at', "recovered_at DATETIME NULL COMMENT 'Servizi ripristinati'");
|
||||||
|
|
||||||
|
DROP PROCEDURE IF EXISTS _mig022_add_col;
|
||||||
|
|
||||||
|
-- Post-Incident Review (1:1 con incident)
|
||||||
|
CREATE TABLE IF NOT EXISTS incident_pir (
|
||||||
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
incident_id INT NOT NULL,
|
||||||
|
organization_id INT NOT NULL,
|
||||||
|
-- Root Cause Analysis - 5 Whys
|
||||||
|
problem_statement TEXT,
|
||||||
|
why_1 TEXT, why_2 TEXT, why_3 TEXT, why_4 TEXT, why_5 TEXT,
|
||||||
|
root_cause TEXT,
|
||||||
|
-- Metriche (snapshot al momento della review, in minuti)
|
||||||
|
ttd_minutes INT NULL,
|
||||||
|
ttc_minutes INT NULL,
|
||||||
|
ttr_minutes INT NULL,
|
||||||
|
downtime_minutes INT NULL,
|
||||||
|
affected_users INT NULL,
|
||||||
|
estimated_cost_eur DECIMAL(12,2) NULL,
|
||||||
|
notification_compliance TINYINT(1) NULL COMMENT '1 se notifiche entro le tempistiche NIS2',
|
||||||
|
-- Lesson learned & azioni di miglioramento
|
||||||
|
what_went_well TEXT,
|
||||||
|
what_to_improve TEXT,
|
||||||
|
improvement_actions JSON NULL COMMENT 'lista azioni {desc, owner, due_date, status}',
|
||||||
|
participants TEXT,
|
||||||
|
reviewed_by INT NULL,
|
||||||
|
reviewed_at DATETIME NULL,
|
||||||
|
status ENUM('draft','completed') DEFAULT 'draft',
|
||||||
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
|
UNIQUE KEY uniq_incident (incident_id),
|
||||||
|
INDEX idx_org (organization_id),
|
||||||
|
CONSTRAINT fk_pir_incident FOREIGN KEY (incident_id) REFERENCES incidents(id) ON DELETE CASCADE,
|
||||||
|
CONSTRAINT fk_pir_org FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
|
-- ROLLBACK:
|
||||||
|
-- DROP TABLE IF EXISTS incident_pir;
|
||||||
|
-- ALTER TABLE incidents DROP COLUMN triaged_at, DROP COLUMN contained_at,
|
||||||
|
-- DROP COLUMN eradicated_at, DROP COLUMN recovered_at;
|
||||||
@ -466,6 +466,7 @@
|
|||||||
<th>Tipo</th>
|
<th>Tipo</th>
|
||||||
<th>Categoria</th>
|
<th>Categoria</th>
|
||||||
<th>Criticita'</th>
|
<th>Criticita'</th>
|
||||||
|
<th>Rilevanza NIS2</th>
|
||||||
<th>Owner</th>
|
<th>Owner</th>
|
||||||
<th>Stato</th>
|
<th>Stato</th>
|
||||||
<th>Azioni</th>
|
<th>Azioni</th>
|
||||||
@ -482,9 +483,13 @@
|
|||||||
<td>${typeLabels[asset.asset_type] || asset.asset_type || '-'}</td>
|
<td>${typeLabels[asset.asset_type] || asset.asset_type || '-'}</td>
|
||||||
<td>${escapeHtml(asset.category || '-')}</td>
|
<td>${escapeHtml(asset.category || '-')}</td>
|
||||||
<td><span class="criticality-badge ${crit}">${criticalityLabels[crit] || crit}</span></td>
|
<td><span class="criticality-badge ${crit}">${criticalityLabels[crit] || crit}</span></td>
|
||||||
|
<td>${relevanceBadge(asset)}</td>
|
||||||
<td>${escapeHtml(asset.owner_name || '-')}</td>
|
<td>${escapeHtml(asset.owner_name || '-')}</td>
|
||||||
<td><span class="status-badge ${st}">${statusLabels[st] || st}</span></td>
|
<td><span class="status-badge ${st}">${statusLabels[st] || st}</span></td>
|
||||||
<td>
|
<td style="white-space:nowrap;">
|
||||||
|
<button class="btn-icon" onclick="event.stopPropagation(); showScoringModal(${asset.id})" title="Valuta rilevanza NIS2">
|
||||||
|
<svg viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M3 3a1 1 0 011 1v12h12a1 1 0 110 2H3a1 1 0 01-1-1V4a1 1 0 011-1zm14.707 4.707a1 1 0 00-1.414-1.414L12 10.586 9.707 8.293a1 1 0 00-1.414 0L4.586 12 6 13.414l2.293-2.293L10.586 13l5.121-5.293z" clip-rule="evenodd"/></svg>
|
||||||
|
</button>
|
||||||
<button class="btn-icon" onclick="event.stopPropagation(); showEditAssetModal(${asset.id})" title="Modifica">
|
<button class="btn-icon" onclick="event.stopPropagation(); showEditAssetModal(${asset.id})" title="Modifica">
|
||||||
<svg viewBox="0 0 20 20" fill="currentColor"><path d="M13.586 3.586a2 2 0 112.828 2.828l-.793.793-2.828-2.828.793-.793zM11.379 5.793L3 14.172V17h2.828l8.38-8.379-2.83-2.828z"/></svg>
|
<svg viewBox="0 0 20 20" fill="currentColor"><path d="M13.586 3.586a2 2 0 112.828 2.828l-.793.793-2.828-2.828.793-.793zM11.379 5.793L3 14.172V17h2.828l8.38-8.379-2.83-2.828z"/></svg>
|
||||||
</button>
|
</button>
|
||||||
@ -496,6 +501,106 @@
|
|||||||
container.innerHTML = html;
|
container.innerHTML = html;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ── Rilevanza NIS2 (GV.OC-04) ───────────────────────────
|
||||||
|
const relevanceClassColors = {
|
||||||
|
critico: '#dc2626', alto: '#ea580c', medio: '#ca8a04',
|
||||||
|
basso: '#2563eb', trascurabile: '#6b7280'
|
||||||
|
};
|
||||||
|
|
||||||
|
function relevanceBadge(asset) {
|
||||||
|
if (asset.relevance_score === null || asset.relevance_score === undefined || asset.relevance_score === '') {
|
||||||
|
return '<span style="color:var(--gray-400); font-size:0.8rem;">Da valutare</span>';
|
||||||
|
}
|
||||||
|
const cls = asset.relevance_class || 'trascurabile';
|
||||||
|
const color = relevanceClassColors[cls] || '#6b7280';
|
||||||
|
const rel = Number(asset.is_nis2_relevant) ? ' ✓' : '';
|
||||||
|
return `<span style="display:inline-flex;align-items:center;gap:6px;font-size:0.8rem;font-weight:600;color:${color};">
|
||||||
|
<span style="display:inline-block;min-width:30px;text-align:center;padding:2px 6px;border-radius:6px;background:${color}1a;">${asset.relevance_score}</span>
|
||||||
|
${cls.charAt(0).toUpperCase() + cls.slice(1)}${rel}</span>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
let _scoringGrid = null;
|
||||||
|
async function loadScoringGrid() {
|
||||||
|
if (_scoringGrid) return _scoringGrid;
|
||||||
|
const r = await api.getScoringGrid();
|
||||||
|
if (r.success) _scoringGrid = r.data;
|
||||||
|
return _scoringGrid;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function showScoringModal(id) {
|
||||||
|
try {
|
||||||
|
const [assetRes, grid] = await Promise.all([api.getAsset(id), loadScoringGrid()]);
|
||||||
|
if (!assetRes.success || !grid) { showNotification('Errore caricamento dati.', 'error'); return; }
|
||||||
|
const a = assetRes.data;
|
||||||
|
let prev = a.relevance_criteria;
|
||||||
|
if (typeof prev === 'string') { try { prev = JSON.parse(prev); } catch (e) { prev = null; } }
|
||||||
|
|
||||||
|
let body = `<p style="font-size:0.85rem;color:var(--gray-600);margin-bottom:1rem;">
|
||||||
|
Metodologia di scoring rilevanza NIS2 (requisito <strong>GV.OC-04</strong>). Soglia rilevanza: <strong>≥${grid.threshold} punti</strong>.
|
||||||
|
Il punteggio aggiorna automaticamente anche la criticita dell'asset.</p>`;
|
||||||
|
|
||||||
|
for (const [key, def] of Object.entries(grid.grid)) {
|
||||||
|
const sel = prev && prev[key] ? prev[key].value : '';
|
||||||
|
let opts = `<option value="">— seleziona —</option>`;
|
||||||
|
for (const [ov, od] of Object.entries(def.options)) {
|
||||||
|
opts += `<option value="${ov}" data-pts="${od.points}" ${ov === sel ? 'selected' : ''}>${od.label} (${od.points})</option>`;
|
||||||
|
}
|
||||||
|
body += `<div class="form-group" style="margin-bottom:0.75rem;">
|
||||||
|
<label class="form-label" style="font-weight:600;">${def.label} <span style="color:var(--gray-400);font-weight:400;">(max ${def.max})</span></label>
|
||||||
|
<div style="font-size:0.78rem;color:var(--gray-500);margin-bottom:4px;">${def.help}</div>
|
||||||
|
<select class="form-select score-criterion" data-key="${key}" onchange="updateScorePreview()">${opts}</select>
|
||||||
|
</div>`;
|
||||||
|
}
|
||||||
|
body += `<div id="score-preview" style="margin-top:1rem;padding:0.9rem;border-radius:10px;background:var(--gray-50);font-weight:600;text-align:center;">
|
||||||
|
Totale: <span id="score-total">0</span>/100 — <span id="score-class">—</span></div>`;
|
||||||
|
|
||||||
|
showModal(`Valuta Rilevanza NIS2 — ${escapeHtml(a.name)}`, body, {
|
||||||
|
size: 'lg',
|
||||||
|
footer: `<button class="btn btn-secondary" onclick="closeModal()">Annulla</button>
|
||||||
|
<button class="btn btn-primary" onclick="submitScoring(${id})">Calcola e Salva</button>`
|
||||||
|
});
|
||||||
|
updateScorePreview();
|
||||||
|
} catch (e) {
|
||||||
|
showNotification('Errore nell\'apertura della valutazione.', 'error');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateScorePreview() {
|
||||||
|
let total = 0, complete = true;
|
||||||
|
document.querySelectorAll('.score-criterion').forEach(s => {
|
||||||
|
if (!s.value) { complete = false; return; }
|
||||||
|
total += parseInt(s.selectedOptions[0].dataset.pts || '0', 10);
|
||||||
|
});
|
||||||
|
let cls = total >= 80 ? 'critico' : total >= 60 ? 'alto' : total >= 40 ? 'medio' : total >= 20 ? 'basso' : 'trascurabile';
|
||||||
|
const color = relevanceClassColors[cls];
|
||||||
|
document.getElementById('score-total').textContent = total;
|
||||||
|
const clsEl = document.getElementById('score-class');
|
||||||
|
clsEl.textContent = complete ? `${cls.charAt(0).toUpperCase() + cls.slice(1)}${total >= 40 ? ' — Rilevante NIS2 ✓' : ''}` : '(completa tutti i criteri)';
|
||||||
|
clsEl.style.color = complete ? color : 'var(--gray-400)';
|
||||||
|
}
|
||||||
|
|
||||||
|
async function submitScoring(id) {
|
||||||
|
const criteria = {};
|
||||||
|
let complete = true;
|
||||||
|
document.querySelectorAll('.score-criterion').forEach(s => {
|
||||||
|
if (!s.value) complete = false;
|
||||||
|
criteria[s.dataset.key] = s.value;
|
||||||
|
});
|
||||||
|
if (!complete) { showNotification('Compila tutti i 6 criteri.', 'warning'); return; }
|
||||||
|
try {
|
||||||
|
const r = await api.scoreAsset(id, criteria);
|
||||||
|
if (r.success) {
|
||||||
|
showNotification(`Rilevanza calcolata: ${r.data.score}/100 (${r.data.class}).`, 'success');
|
||||||
|
closeModal();
|
||||||
|
loadAssets();
|
||||||
|
} else {
|
||||||
|
showNotification(r.message || 'Errore nel calcolo.', 'error');
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
showNotification('Errore di connessione.', 'error');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ── Asset Detail View ───────────────────────────────────
|
// ── Asset Detail View ───────────────────────────────────
|
||||||
async function showAssetDetail(id) {
|
async function showAssetDetail(id) {
|
||||||
try {
|
try {
|
||||||
@ -581,6 +686,7 @@
|
|||||||
size: 'lg',
|
size: 'lg',
|
||||||
footer: `
|
footer: `
|
||||||
<button class="btn btn-secondary" onclick="closeModal()">Chiudi</button>
|
<button class="btn btn-secondary" onclick="closeModal()">Chiudi</button>
|
||||||
|
<button class="btn btn-secondary" onclick="closeModal(); showScoringModal(${a.id})">Valuta Rilevanza NIS2</button>
|
||||||
<button class="btn btn-primary" onclick="closeModal(); showEditAssetModal(${a.id})">Modifica</button>
|
<button class="btn btn-primary" onclick="closeModal(); showEditAssetModal(${a.id})">Modifica</button>
|
||||||
`
|
`
|
||||||
});
|
});
|
||||||
|
|||||||
@ -230,6 +230,9 @@ $actionMap = [
|
|||||||
'POST:{id}/notification' => 'sendNotification',
|
'POST:{id}/notification' => 'sendNotification',
|
||||||
'POST:{id}/finalReport' => 'sendFinalReport',
|
'POST:{id}/finalReport' => 'sendFinalReport',
|
||||||
'POST:{id}/aiClassify' => 'aiClassify',
|
'POST:{id}/aiClassify' => 'aiClassify',
|
||||||
|
'GET:{id}/metrics' => 'metrics',
|
||||||
|
'GET:{id}/pir' => 'getPir',
|
||||||
|
'POST:{id}/pir' => 'savePir',
|
||||||
],
|
],
|
||||||
|
|
||||||
// ── PolicyController ────────────────────────────
|
// ── PolicyController ────────────────────────────
|
||||||
@ -269,10 +272,13 @@ $actionMap = [
|
|||||||
'assets' => [
|
'assets' => [
|
||||||
'GET:list' => 'list',
|
'GET:list' => 'list',
|
||||||
'POST:create' => 'create',
|
'POST:create' => 'create',
|
||||||
|
'GET:scoringGrid' => 'scoringGrid',
|
||||||
|
'GET:relevantSystems' => 'relevantSystems',
|
||||||
|
'GET:dependencyMap' => 'dependencyMap',
|
||||||
'GET:{id}' => 'get',
|
'GET:{id}' => 'get',
|
||||||
'PUT:{id}' => 'update',
|
'PUT:{id}' => 'update',
|
||||||
'DELETE:{id}' => 'delete',
|
'DELETE:{id}' => 'delete',
|
||||||
'GET:dependencyMap' => 'dependencyMap',
|
'POST:{id}/score' => 'score',
|
||||||
],
|
],
|
||||||
|
|
||||||
// ── AuditController ─────────────────────────────
|
// ── AuditController ─────────────────────────────
|
||||||
@ -284,7 +290,9 @@ $actionMap = [
|
|||||||
'GET:report' => 'generateReport',
|
'GET:report' => 'generateReport',
|
||||||
'GET:logs' => 'getAuditLogs',
|
'GET:logs' => 'getAuditLogs',
|
||||||
'GET:iso27001Mapping' => 'getIsoMapping',
|
'GET:iso27001Mapping' => 'getIsoMapping',
|
||||||
|
'GET:nistCsfMapping' => 'getNistCsfMapping',
|
||||||
'GET:executiveReport' => 'executiveReport',
|
'GET:executiveReport' => 'executiveReport',
|
||||||
|
'GET:relevantSystemsRegister' => 'relevantSystemsRegister',
|
||||||
'GET:export' => 'export',
|
'GET:export' => 'export',
|
||||||
'GET:chainVerify' => 'chainVerify',
|
'GET:chainVerify' => 'chainVerify',
|
||||||
'GET:exportCertified' => 'exportCertified',
|
'GET:exportCertified' => 'exportCertified',
|
||||||
|
|||||||
@ -212,6 +212,10 @@ class NIS2API {
|
|||||||
sendEarlyWarning(id) { return this.post(`/incidents/${id}/early-warning`, {}); }
|
sendEarlyWarning(id) { return this.post(`/incidents/${id}/early-warning`, {}); }
|
||||||
sendNotification(id) { return this.post(`/incidents/${id}/notification`, {}); }
|
sendNotification(id) { return this.post(`/incidents/${id}/notification`, {}); }
|
||||||
sendFinalReport(id) { return this.post(`/incidents/${id}/final-report`, {}); }
|
sendFinalReport(id) { return this.post(`/incidents/${id}/final-report`, {}); }
|
||||||
|
aiClassifyIncident(id) { return this.post(`/incidents/${id}/aiClassify`, {}); }
|
||||||
|
getIncidentMetrics(id) { return this.get(`/incidents/${id}/metrics`); }
|
||||||
|
getIncidentPir(id) { return this.get(`/incidents/${id}/pir`); }
|
||||||
|
saveIncidentPir(id, data) { return this.post(`/incidents/${id}/pir`, data); }
|
||||||
|
|
||||||
// ═══════════════════════════════════════════════════════════════════
|
// ═══════════════════════════════════════════════════════════════════
|
||||||
// Policies
|
// Policies
|
||||||
@ -251,6 +255,11 @@ class NIS2API {
|
|||||||
createAsset(data) { return this.post('/assets/create', data); }
|
createAsset(data) { return this.post('/assets/create', data); }
|
||||||
getAsset(id) { return this.get(`/assets/${id}`); }
|
getAsset(id) { return this.get(`/assets/${id}`); }
|
||||||
updateAsset(id, data) { return this.put(`/assets/${id}`, data); }
|
updateAsset(id, data) { return this.put(`/assets/${id}`, data); }
|
||||||
|
deleteAsset(id) { return this.delete(`/assets/${id}`); }
|
||||||
|
// NIS2 relevance scoring (GV.OC-04)
|
||||||
|
getScoringGrid() { return this.get('/assets/scoringGrid'); }
|
||||||
|
scoreAsset(id, criteria) { return this.post(`/assets/${id}/score`, { criteria }); }
|
||||||
|
listRelevantSystems() { return this.get('/assets/relevantSystems'); }
|
||||||
|
|
||||||
// ═══════════════════════════════════════════════════════════════════
|
// ═══════════════════════════════════════════════════════════════════
|
||||||
// Audit
|
// Audit
|
||||||
|
|||||||
@ -207,11 +207,13 @@ const HelpSystem = (function () {
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
references: [
|
references: [
|
||||||
'Art. 23.1 - Obbligo di notifica degli incidenti significativi',
|
'Direttiva (UE) 2022/2555 - Art. 23.1 - Obbligo di notifica degli incidenti significativi',
|
||||||
'Art. 23.4 (a) - Early warning entro 24 ore',
|
'Direttiva (UE) 2022/2555 - Art. 23.4 (a) - Early warning entro 24 ore',
|
||||||
'Art. 23.4 (b) - Notifica entro 72 ore',
|
'Direttiva (UE) 2022/2555 - Art. 23.4 (b) - Notifica entro 72 ore',
|
||||||
'Art. 23.4 (d) - Relazione finale entro un mese',
|
'Direttiva (UE) 2022/2555 - Art. 23.4 (d) - Relazione finale entro un mese',
|
||||||
'Art. 23.3 - Definizione di incidente significativo'
|
'D.Lgs. 4 settembre 2024, n. 138 - Art. 23 - Notifica degli incidenti (recepimento NIS2)',
|
||||||
|
'Determinazione ACN n. 164179 del 14/04/2025 - Classificazione incidenti significativi (Allegato 3 soggetti essenziali, Allegato 4 soggetti importanti) e tipologie IS-1/IS-2/IS-3/IS-4',
|
||||||
|
'Determinazione ACN n. 333017/2025 - Piattaforma digitale ACN per le notifiche'
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -381,6 +383,15 @@ const HelpSystem = (function () {
|
|||||||
'Il livello di criticita\' influenza la valutazione dei rischi associati.'
|
'Il livello di criticita\' influenza la valutazione dei rischi associati.'
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
heading: 'Rilevanza NIS2 (scoring 0-100)',
|
||||||
|
items: [
|
||||||
|
'Il pulsante <strong>Valuta Rilevanza NIS2</strong> applica una metodologia di scoring documentata a 6 criteri pesati: Criticita Operativa (0-25), Impatto Interruzione (0-25), Dati Trattati (0-20), Dipendenze (0-15), Esposizione (0-10), Obblighi Normativi (0-5).',
|
||||||
|
'Un sistema e considerato <strong>rilevante NIS2 quando il punteggio ≥ 40</strong>. Classi: ≥80 Critico, 60-79 Alto, 40-59 Medio, 20-39 Basso, <20 Trascurabile.',
|
||||||
|
'Il punteggio aggiorna automaticamente anche la criticita dell\'asset e alimenta il registro formale dei <strong>Sistemi Rilevanti</strong>.',
|
||||||
|
'La metodologia supporta il requisito di censimento e classificazione dei sistemi informativi e di rete rilevanti, da approvare a livello di Direzione.'
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
heading: 'Mappa delle Dipendenze',
|
heading: 'Mappa delle Dipendenze',
|
||||||
items: [
|
items: [
|
||||||
@ -399,10 +410,11 @@ const HelpSystem = (function () {
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
references: [
|
references: [
|
||||||
'Art. 21.2 (i) - Sicurezza delle risorse umane, politiche di controllo dell\'accesso e gestione degli attivi',
|
'Direttiva (UE) 2022/2555 - Art. 21.2 (i) - Sicurezza delle risorse umane, controllo degli accessi e gestione degli attivi',
|
||||||
'Art. 21.2 (a) - Politiche di analisi dei rischi e di sicurezza dei sistemi informatici',
|
'Direttiva (UE) 2022/2555 - Art. 21.2 (a) - Politiche di analisi dei rischi e di sicurezza dei sistemi informatici',
|
||||||
'Art. 21.2 (c) - Continuita\' operativa, gestione dei backup e ripristino in caso di disastro',
|
'Direttiva (UE) 2022/2555 - Art. 21.2 (c) - Continuita\' operativa, gestione dei backup e ripristino',
|
||||||
'Considerando 79 - Adeguatezza delle misure rispetto ai rischi per le reti e i sistemi informativi'
|
'D.Lgs. 4 settembre 2024, n. 138 - Art. 24 - Obblighi in materia di misure di gestione del rischio',
|
||||||
|
'Identificazione e classificazione dei sistemi rilevanti - metodologia di scoring 0-100 approvata dalla Direzione'
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
{"version":"1.6.1","build":"20260529g","date":"2026-05-29T14:55:00+02:00","changelog":"Doc: aggiornati help.js (sezione Impostazioni con Sessioni/Preferenze/Branding/Reset/Tenant), i18n.js (chiavi IT/EN per Fasi 2-5), product knowledge AI AgileHub (card NIS2 id=914)"}
|
{"version":"1.7.0","build":"20260529h","date":"2026-05-29T16:30:00+02:00","changelog":"FEAT integrazione analisi docs/nis2: (1) Asset Relevance Scoring NIS2 0-100 a 6 criteri (GV.OC-04) + registro formale stampabile; (2) Tassonomia incidenti Determina ACN 164179/2025 (IS-1..4, regime essenziale/importante Allegati 3-4); (3) Post-Incident Review strutturato 5-Whys + metriche TTD/TTC/TTR; (4) Layer mapping NIST CSF 2.0 (43 controlli); (5) Fonti normative certe: registry citabile + grounding AI + citazioni help + ingest PDF normativi nella KB RAG."}
|
||||||
|
|||||||
213
scripts/ingest-nis2-sources.php
Normal file
213
scripts/ingest-nis2-sources.php
Normal file
@ -0,0 +1,213 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* NIS2 Agile - Ingest Fonti Normative Certe nella Knowledge Base (RAG)
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
* Indicizza i PDF normativi ufficiali (docs/nis2/*.pdf, registrati in
|
||||||
|
* application/config/nis2_sources.php) nella collection Qdrant `nis2_kb` con
|
||||||
|
* scope SYSTEM, cosi' che AIService::askWithRag() possa citare le fonti certe.
|
||||||
|
*
|
||||||
|
* ESEGUIRE SU HETZNER (richiede accesso a Qdrant + Voyage), es:
|
||||||
|
* docker exec -i nis2-app php /var/www/nis2-agile/scripts/ingest-nis2-sources.php
|
||||||
|
* # oppure dalla root del progetto:
|
||||||
|
* php scripts/ingest-nis2-sources.php
|
||||||
|
*
|
||||||
|
* Estrazione testo: usa `pdftotext` (poppler-utils) se disponibile, altrimenti
|
||||||
|
* ricade sull'API document di Claude. Idempotente: cancella i chunk SYSTEM del
|
||||||
|
* documento (per `source` stabile) prima del re-upsert.
|
||||||
|
*
|
||||||
|
* Opzioni:
|
||||||
|
* --only=determina_164179_2025 ingerisce una sola fonte (key del registry)
|
||||||
|
* --dry-run estrae e mostra le statistiche senza upsert
|
||||||
|
* ============================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (PHP_SAPI !== 'cli') { fwrite(STDERR, "Solo CLI\n"); exit(1); }
|
||||||
|
|
||||||
|
if (!defined('BASE_PATH')) define('BASE_PATH', dirname(__DIR__));
|
||||||
|
if (!defined('APP_PATH')) define('APP_PATH', BASE_PATH . '/application');
|
||||||
|
|
||||||
|
require_once APP_PATH . '/config/env.php';
|
||||||
|
require_once APP_PATH . '/config/config.php';
|
||||||
|
require_once APP_PATH . '/config/database.php';
|
||||||
|
require_once APP_PATH . '/services/EmbedService.php';
|
||||||
|
require_once APP_PATH . '/services/VectorService.php';
|
||||||
|
|
||||||
|
$opts = getopt('', ['only::', 'dry-run']);
|
||||||
|
$only = $opts['only'] ?? null;
|
||||||
|
$dryRun = isset($opts['dry-run']);
|
||||||
|
|
||||||
|
$sources = require APP_PATH . '/config/nis2_sources.php';
|
||||||
|
|
||||||
|
function logln(string $m): void { echo '[' . date('Y-m-d H:i:s') . "] $m\n"; }
|
||||||
|
|
||||||
|
/** Estrae testo da un PDF: pdftotext -> fallback Claude document API. */
|
||||||
|
function extractPdfText(string $absPath): string
|
||||||
|
{
|
||||||
|
// 0) Cache di testo pre-estratto accanto al PDF (<file>.pdf.txt).
|
||||||
|
// Utile quando l'ingest gira in un container privo di pdftotext:
|
||||||
|
// si estrae prima sull'host e si rilegge il .txt qui.
|
||||||
|
$cache = $absPath . '.txt';
|
||||||
|
if (is_file($cache)) {
|
||||||
|
$t = (string) file_get_contents($cache);
|
||||||
|
if (strlen(trim($t)) > 200) { logln(' uso cache testo: ' . basename($cache)); return $t; }
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1) pdftotext (veloce, gratuito)
|
||||||
|
$bin = trim((string)@shell_exec('command -v pdftotext 2>/dev/null'));
|
||||||
|
if ($bin !== '') {
|
||||||
|
$tmp = tempnam(sys_get_temp_dir(), 'nis2pdf') . '.txt';
|
||||||
|
@shell_exec(escapeshellcmd($bin) . ' -enc UTF-8 -nopgbrk ' . escapeshellarg($absPath) . ' ' . escapeshellarg($tmp) . ' 2>/dev/null');
|
||||||
|
$txt = is_file($tmp) ? (string)file_get_contents($tmp) : '';
|
||||||
|
@unlink($tmp);
|
||||||
|
if (strlen(trim($txt)) > 200) return $txt;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2) Fallback: Claude document API
|
||||||
|
logln(' pdftotext non disponibile/insufficiente -> uso Claude document API');
|
||||||
|
$data = base64_encode((string)file_get_contents($absPath));
|
||||||
|
$body = [
|
||||||
|
'model' => defined('ANTHROPIC_MODEL') ? ANTHROPIC_MODEL : 'claude-sonnet-4-5-20250929',
|
||||||
|
'max_tokens' => 8000,
|
||||||
|
'messages' => [[
|
||||||
|
'role' => 'user',
|
||||||
|
'content' => [
|
||||||
|
['type' => 'document', 'source' => ['type' => 'base64', 'media_type' => 'application/pdf', 'data' => $data]],
|
||||||
|
['type' => 'text', 'text' => 'Estrai integralmente il testo di questo documento normativo in testo semplice, mantenendo numeri di articolo, commi, allegati e tabelle. Non riassumere, non commentare.'],
|
||||||
|
],
|
||||||
|
]],
|
||||||
|
];
|
||||||
|
$ch = curl_init('https://api.anthropic.com/v1/messages');
|
||||||
|
curl_setopt_array($ch, [
|
||||||
|
CURLOPT_RETURNTRANSFER => true,
|
||||||
|
CURLOPT_POST => true,
|
||||||
|
CURLOPT_HTTPHEADER => [
|
||||||
|
'content-type: application/json',
|
||||||
|
'x-api-key: ' . ANTHROPIC_API_KEY,
|
||||||
|
'anthropic-version: 2023-06-01',
|
||||||
|
],
|
||||||
|
CURLOPT_POSTFIELDS => json_encode($body),
|
||||||
|
CURLOPT_TIMEOUT => 180,
|
||||||
|
]);
|
||||||
|
$res = curl_exec($ch);
|
||||||
|
if ($res === false) { logln(' ERRORE curl: ' . curl_error($ch)); curl_close($ch); return ''; }
|
||||||
|
curl_close($ch);
|
||||||
|
$j = json_decode($res, true);
|
||||||
|
return $j['content'][0]['text'] ?? '';
|
||||||
|
}
|
||||||
|
|
||||||
|
function chunkText(string $text, int $size = 2000, int $overlap = 200): array
|
||||||
|
{
|
||||||
|
// Multibyte-safe: usa mb_* per non spezzare caratteri UTF-8 a meta'
|
||||||
|
// (altrimenti json_encode produce body non valido -> Voyage HTTP 400).
|
||||||
|
$text = mb_convert_encoding($text, 'UTF-8', 'UTF-8'); // bonifica sequenze invalide
|
||||||
|
$chunks = []; $len = mb_strlen($text, 'UTF-8'); $start = 0;
|
||||||
|
while ($start < $len) {
|
||||||
|
$take = min($size, $len - $start);
|
||||||
|
$piece = mb_substr($text, $start, $take, 'UTF-8');
|
||||||
|
if (trim($piece) !== '') $chunks[] = $piece;
|
||||||
|
if ($start + $take >= $len) break;
|
||||||
|
$start += ($size - $overlap);
|
||||||
|
}
|
||||||
|
return $chunks;
|
||||||
|
}
|
||||||
|
|
||||||
|
function uuid(): string
|
||||||
|
{
|
||||||
|
$b = random_bytes(16);
|
||||||
|
$b[6] = chr((ord($b[6]) & 0x0f) | 0x40);
|
||||||
|
$b[8] = chr((ord($b[8]) & 0x3f) | 0x80);
|
||||||
|
return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($b), 4));
|
||||||
|
}
|
||||||
|
|
||||||
|
logln('=== Ingest fonti normative NIS2 nella KB (scope SYSTEM) ===');
|
||||||
|
if ($dryRun) logln('MODALITA DRY-RUN: nessun upsert.');
|
||||||
|
|
||||||
|
$embed = null; $vector = null;
|
||||||
|
if (!$dryRun) {
|
||||||
|
$embed = new EmbedService();
|
||||||
|
$vector = new VectorService();
|
||||||
|
$vector->ensureCollection($embed->dims);
|
||||||
|
}
|
||||||
|
|
||||||
|
$totalChunks = 0; $done = 0;
|
||||||
|
foreach ($sources as $key => $src) {
|
||||||
|
if ($only && $key !== $only) continue;
|
||||||
|
if (empty($src['file'])) { logln("SKIP {$key}: nessun file PDF associato"); continue; }
|
||||||
|
|
||||||
|
$abs = BASE_PATH . '/' . $src['file'];
|
||||||
|
if (!is_file($abs)) { logln("SKIP {$key}: file non trovato {$abs}"); continue; }
|
||||||
|
|
||||||
|
logln("Fonte: {$src['short']} ({$src['file']})");
|
||||||
|
$text = extractPdfText($abs);
|
||||||
|
$text = preg_replace('/[ \t]+/', ' ', $text);
|
||||||
|
$text = preg_replace('/\n{3,}/', "\n\n", trim($text));
|
||||||
|
if (strlen($text) < 200) { logln(" ERRORE: testo estratto troppo breve, salto."); continue; }
|
||||||
|
|
||||||
|
// Prefisso citazione su ogni documento: aiuta il modello a citare correttamente
|
||||||
|
$header = "FONTE NORMATIVA: {$src['citation']}\nAUTORITA: {$src['authority']}\n\n";
|
||||||
|
$chunks = chunkText($header . $text, 2000, 200);
|
||||||
|
logln(' testo: ' . strlen($text) . ' char -> ' . count($chunks) . ' chunk');
|
||||||
|
$totalChunks += count($chunks);
|
||||||
|
|
||||||
|
if ($dryRun) { $done++; continue; }
|
||||||
|
|
||||||
|
// Idempotenza: rimuovi i chunk SYSTEM esistenti per questa fonte
|
||||||
|
try {
|
||||||
|
$vector->deleteByFilter(['must' => [
|
||||||
|
['key' => 'scope', 'match' => ['value' => 'SYSTEM']],
|
||||||
|
['key' => 'source', 'match' => ['value' => $src['citation']]],
|
||||||
|
]]);
|
||||||
|
} catch (Exception $e) { logln(' (warning) delete precedente: ' . $e->getMessage()); }
|
||||||
|
|
||||||
|
$docUuid = uuid();
|
||||||
|
$points = [];
|
||||||
|
foreach ($chunks as $i => $chunk) {
|
||||||
|
// Embedding con retry/backoff: Voyage puo' restituire errori transitori
|
||||||
|
// (HTTP 0 timeout / 429 rate limit) su grandi volumi di chunk.
|
||||||
|
$vec = null;
|
||||||
|
for ($try = 1; $try <= 5; $try++) {
|
||||||
|
try { $vec = $embed->embed($chunk); break; }
|
||||||
|
catch (Throwable $e) {
|
||||||
|
if ($try === 5) { logln(" ERRORE embed chunk {$i} dopo 5 tentativi: " . $e->getMessage()); throw $e; }
|
||||||
|
logln(" retry embed chunk {$i} (tentativo {$try}): " . substr($e->getMessage(), 0, 60));
|
||||||
|
sleep($try); // backoff lineare 1s,2s,3s,4s
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$points[] = [
|
||||||
|
'id' => uuid(),
|
||||||
|
'vector' => $vec,
|
||||||
|
'payload' => [
|
||||||
|
'doc_uuid' => $docUuid,
|
||||||
|
'title' => $src['short'] . ($i > 0 ? ' (parte ' . ($i + 1) . ')' : ''),
|
||||||
|
'chunk' => $chunk,
|
||||||
|
'entity_type' => 'normativa',
|
||||||
|
'source' => $src['citation'],
|
||||||
|
'lang' => 'it',
|
||||||
|
'scope' => 'SYSTEM',
|
||||||
|
'consulting_firm_id' => null,
|
||||||
|
'organization_id' => null,
|
||||||
|
'shared_with_orgs' => [],
|
||||||
|
'uploaded_by' => 0,
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
// Upsert a batch (per non superare i limiti di payload)
|
||||||
|
foreach (array_chunk($points, 64) as $batch) {
|
||||||
|
$vector->upsertBatch($batch);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tracking MySQL (best-effort)
|
||||||
|
try {
|
||||||
|
$stmt = Database::getInstance()->prepare(
|
||||||
|
"INSERT INTO kb_uploaded_documents
|
||||||
|
(qdrant_doc_uuid, scope, consulting_firm_id, organization_id, uploaded_by, title, entity_type, source, lang, chunk_count, shared_with_orgs, status)
|
||||||
|
VALUES (?, 'SYSTEM', NULL, NULL, 0, ?, 'normativa', ?, 'it', ?, '[]', 'ready')"
|
||||||
|
);
|
||||||
|
$stmt->execute([$docUuid, $src['short'], $src['citation'], count($chunks)]);
|
||||||
|
} catch (Exception $e) { logln(' (warning) tracking insert: ' . $e->getMessage()); }
|
||||||
|
|
||||||
|
logln(" OK indicizzato (doc_uuid={$docUuid})");
|
||||||
|
$done++;
|
||||||
|
}
|
||||||
|
|
||||||
|
logln("=== Completato: {$done} fonti, {$totalChunks} chunk totali ===");
|
||||||
Loading…
Reference in New Issue
Block a user