prepare($sql); $s->execute($a); } function one(PDO $p, string $sql, array $a = []) { $s=$p->prepare($sql); $s->execute($a); return $s->fetch(PDO::FETCH_ASSOC); } $NOW='2026-06-20 10:35:00'; $org = one($pdo, "SELECT id FROM organizations WHERE name=?", ['Nuova Agile Technology srl']); if (!$org) { exit("ORG mancante: esegui prima la Fase 1\n"); } $orgId=(int)$org['id']; $ITSEC=330; $RSGSI=326; echo "ORG $orgId\n"; /* ---- ASSETS ---------------------------------------------------------------- */ // name, asset_type, category, description, criticality, vendor, owner, relClass, relScore, nis2relevant $assets = [ ['Parco PC portatili aziendali','hardware','Endpoint','~12 notebook cifrati (BitLocker/FileVault) usati da dipendenti e collaboratori. Unico hardware gestito: nessun server in sede.','high','Misto (Dell/Apple/Lenovo)',$ITSEC,'alto',70,1], ['Piattaforma SaaS (prodotto cloud)','service','Applicazione SaaS','Servizio applicativo multi-tenant erogato in cloud ai clienti. Asset primario di erogazione del servizio.','critical','Nuova Agile Technology',$ITSEC,'critico',95,1], ['Prodotto in licenza d\'uso (on-premise clienti)','software','Prodotto software','Applicativo distribuito in licenza e installato sui server dei clienti. Manutenzione e aggiornamenti a carico nostro.','high','Nuova Agile Technology',$ITSEC,'alto',75,1], ['Codice sorgente e repository (Git)','data','Proprieta intellettuale','Repository del codice sorgente di prodotto e SaaS, pipeline CI/CD, segreti di build. Asset critico di IP.','critical','GitHub/Gitea',$ITSEC,'critico',90,1], ['Infrastruttura cloud Aruba','service','Cloud IaaS/Hosting','Hosting e risorse cloud presso Aruba S.p.A. (data center in Italia). Fornitore primario di infrastruttura.','critical','Aruba S.p.A.',$ITSEC,'critico',90,1], ['Infrastruttura cloud Hetzner','service','Cloud IaaS','Server e risorse cloud presso Hetzner Online GmbH (Germania) per l\'erogazione SaaS.','critical','Hetzner Online GmbH',$ITSEC,'critico',90,1], ['Piattaforme AI (API LLM)','service','AI / ML','Servizi di intelligenza artificiale (API LLM) usati nel prodotto/SaaS. Trattamento dati verso sub-fornitore AI.','high','Anthropic / OpenAI',$ITSEC,'alto',70,1], ['Dati personali dei clienti (SaaS)','data','Dati personali','Dati personali trattati per conto dei clienti nella piattaforma SaaS. Ambito GDPR + ISO 27018.','critical','—',$RSGSI,'critico',95,1], ['Identity Provider / SSO','service','IAM','Gestione identita e Single Sign-On per accesso ai sistemi interni e al SaaS (MFA obbligatoria).','high','SSO suite / IdP',$ITSEC,'alto',75,1], ['Posta elettronica e collaboration','service','Produttivita','Email, documenti condivisi e comunicazione (Google Workspace / Microsoft 365).','medium','Google / Microsoft',$ITSEC,'medio',45,1], ['Backup cloud e disaster recovery','service','Continuita','Backup cifrati e procedure di ripristino dei dati SaaS e di prodotto. Regola 3-2-1 su cloud.','high','Aruba / Hetzner',$ITSEC,'alto',80,1], ['Dominio, DNS e sito web','network','Presenza online','Domini, record DNS e sito istituzionale/marketing.','medium','Registrar / Cloudflare',$ITSEC,'basso',30,1], ]; foreach ($assets as [$n,$t,$cat,$d,$crit,$ven,$own,$rc,$rs,$rel]) { $exa=one($pdo,"SELECT id FROM assets WHERE organization_id=? AND name=?",[$orgId,$n]); if(!$exa){ ex($pdo,"INSERT INTO assets (organization_id,name,asset_type,category,description,criticality,owner_user_id,vendor,status,discovery_source,is_nis2_relevant,relevance_class,relevance_score,relevance_assessed_at,relevance_assessed_by,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?, 'active','manual', ?,?,?,?,?,?,?)", [$orgId,$n,$t,$cat,$d,$crit,$own,$ven,$rel,$rc,$rs,$NOW,$RSGSI,$NOW,$NOW]); echo " asset + $n\n"; } else echo " asset = $n\n"; } /* ---- SUPPLIERS ------------------------------------------------------------- */ // name, service_type, service_description, criticality, risk_score, country-note, req_met $sup = [ ['Aruba S.p.A.','Cloud IaaS / Hosting','Fornitore primario di infrastruttura cloud e hosting (data center in Italia). Erogazione SaaS e servizi interni.','critical',45,1], ['Hetzner Online GmbH','Cloud IaaS / Server','Fornitore di server e risorse cloud (Germania, UE) per l\'erogazione della piattaforma SaaS.','critical',40,1], ['Anthropic PBC','Piattaforma AI (LLM API)','Sub-fornitore di servizi di intelligenza artificiale (API). Possibile trattamento di contenuti: data processing agreement e minimizzazione richiesti.','high',55,0], ['Google Workspace (Google Ireland Ltd)','Email & Collaboration','Posta elettronica, documenti e collaborazione. Trattamento dati aziendali e di comunicazione.','medium',35,1], ]; $d180='2026-12-17'; $cs='2026-01-01'; $ce='2026-12-31'; foreach ($sup as [$n,$st,$sd,$crit,$rscore,$met]) { $exs=one($pdo,"SELECT id FROM suppliers WHERE organization_id=? AND name=?",[$orgId,$n]); if(!$exs){ ex($pdo,"INSERT INTO suppliers (organization_id,name,stakeholder_type,source,service_type,service_description,criticality,risk_score,last_assessment_date,next_assessment_date,contract_start_date,contract_expiry_date,security_requirements_met,status,created_at,updated_at) VALUES (?,?, 'supplier','manual', ?,?,?,?, ?,?,?,?, ?, 'active', ?,?)", [$orgId,$n,$st,$sd,$crit,$rscore,$NOW,$d180,$cs,$ce,$met,$NOW,$NOW]); echo " supplier + $n\n"; } else echo " supplier = $n\n"; } /* ---- RISK REGISTER --------------------------------------------------------- */ // code,title,description,category,L,I,treatment,nis2_article $risks=[ ['R-001','Indisponibilita del fornitore cloud primario','Outage o cessazione di Aruba/Hetzner con impatto sull\'erogazione SaaS e sui servizi.','supply_chain',3,5,'mitigate','21.2.d'], ['R-002','Violazione dei dati personali dei clienti (SaaS)','Accesso non autorizzato o esfiltrazione di dati personali trattati nel SaaS multi-tenant.','cyber',3,5,'mitigate','21.2.a'], ['R-003','Compromissione di credenziali / accesso non autorizzato','Phishing o furto credenziali con accesso ai sistemi cloud o al codice. Mitigato da MFA.','cyber',3,4,'mitigate','21.2.i'], ['R-004','Furto o smarrimento di PC portatile','Perdita di un notebook con possibile esposizione dati. Mitigato da cifratura disco e MDM.','physical',3,3,'mitigate','21.2.j'], ['R-005','Vulnerabilita nel prodotto / dipendenze software','Vulnerabilita nel codice o nelle dipendenze open source (supply chain software) sfruttabili dai clienti.','cyber',3,4,'mitigate','21.2.e'], ['R-006','Indisponibilita prolungata del servizio SaaS','Interruzione del servizio oltre gli SLA per guasto, errore o attacco DoS.','operational',3,4,'mitigate','21.2.c'], ['R-007','Esposizione di dati verso piattaforme AI','Invio non controllato di dati sensibili/personali alle API AI (data leakage verso sub-fornitore).','compliance',3,4,'mitigate','21.2.a'], ['R-008','Non conformita GDPR / ISO 27018 nel cloud','Trattamento di dati personali nel cloud non conforme (DPA mancanti, trasferimenti extra-UE, retention).','compliance',2,4,'mitigate','21.2.a'], ['R-009','Rischio da collaboratori esterni (P.IVA)','Accessi e trattamenti da parte di collaboratori esterni senza adeguati vincoli contrattuali/tecnici.','human',2,3,'mitigate','21.2.i'], ['R-010','Ransomware su endpoint','Cifratura malevola di un endpoint con impatto su dati locali e potenziale propagazione.','cyber',3,4,'mitigate','21.2.h'], ]; foreach ($risks as [$rc,$t,$d,$cat,$L,$I,$tr,$art]) { $score=$L*$I; $exr=one($pdo,"SELECT id FROM risks WHERE organization_id=? AND risk_code=?",[$orgId,$rc]); if(!$exr){ ex($pdo,"INSERT INTO risks (organization_id,risk_code,title,description,category,likelihood,impact,inherent_risk_score,treatment,status,owner_user_id,review_date,nis2_article,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?, 'treating', ?, ?, ?, ?, ?)", [$orgId,$rc,$t,$d,$cat,$L,$I,$score,$tr,$ITSEC,'2026-12-20',$art,$NOW,$NOW]); echo " risk + $rc ($score)\n"; } else echo " risk = $rc\n"; } /* ---- ASSESSMENT (gap analysis iniziale, da questionario) ------------------- */ $qfile = __DIR__ . '/../data/nis2_questionnaire.json'; $ass = one($pdo,"SELECT id FROM assessments WHERE organization_id=? AND title=?",[$orgId,'Gap Analysis iniziale NIS2 2026']); if (!$ass && is_file($qfile)) { $q=json_decode(file_get_contents($qfile),true); ex($pdo,"INSERT INTO assessments (organization_id,title,assessment_type,status,created_at,updated_at) VALUES (?,?, 'initial','in_progress',?,?)", [$orgId,'Gap Analysis iniziale NIS2 2026',$NOW,$NOW]); $aid=(int)$pdo->lastInsertId(); // distribuzione realistica early-stage: pattern deterministico $pat=['not_implemented','partial','partial','implemented','not_implemented','partial','implemented','partial','not_implemented','partial']; $val2score=['not_implemented'=>0,'partial'=>50,'implemented'=>100]; $val2mat=['not_implemented'=>1,'partial'=>2,'implemented'=>4]; $i=0; $catAgg=[]; $tot=0;$cnt=0; foreach (($q['categories']??[]) as $c) { $catId=$c['id']; $iso=($c['iso27001_controls'][0]??null); $art=$c['nis2_article']??null; $sum=0;$n=0; foreach (($c['questions']??[]) as $qq) { $code=$qq['code']??('Q'.$i); $txt=$qq['text_it']??($qq['text_en']??$code); $rv=$pat[$i % count($pat)]; $i++; ex($pdo,"INSERT INTO assessment_responses (assessment_id,question_code,nis2_article,iso27001_control,category,question_text,response_value,maturity_level,answered_by,answered_at) VALUES (?,?,?,?,?,?,?,?,?,?)", [$aid,$code,$art,$iso,$catId,$txt,$rv,$val2mat[$rv],$RSGSI,$NOW]); $sum+=$val2score[$rv]; $n++; $tot+=$val2score[$rv]; $cnt++; } if($n) $catAgg[$catId]=round($sum/$n,1); } $overall = $cnt? round($tot/$cnt,2) : 0; ex($pdo,"UPDATE assessments SET overall_score=?, category_scores=? WHERE id=?",[$overall,json_encode($catAgg),$aid]); echo " assessment + id=$aid ($cnt risposte, score $overall%)\n"; } else echo " assessment = (gia presente o questionario assente)\n"; echo "\nFASE 2 OK\n";