modulo 18 di 24 / Ore 41-60
Moduli 17-24 / Checkpoint 60 ore
Checklist sicurezza per il progetto
Checklist sicurezza specifica per il Registro: input validati, messaggi senza dettagli tecnici, dati personali non loggati, localStorage non esposto, errori gestiti.
Checklist sicurezza per il progetto
Questa lezione appartiene al Modulo 18 — Sicurezza minima e validazione.
Il lavoro continua il progetto guida, il Registro del laboratorio scolastico. Questa lezione è una checklist di sicurezza pratica: non teoria astratta, ma voci concrete da verificare nel codice reale del progetto.
Obiettivo della lezione
Verificare sistematicamente che il Registro non abbia i problemi di sicurezza più comuni per un’applicazione browser-only con localStorage. Non serve diventare esperti di sicurezza — serve non fare gli errori ovvi.
Alla fine devi avere: la checklist compilata con ogni voce verificata sul codice reale.
Sicurezza per un’applicazione browser-only
Il Registro è un’applicazione browser-only con localStorage. Non c’è un server, non ci sono sessioni, non c’è autenticazione vera. Questo semplifica molti problemi ma ne lascia altri irrisolti:
- il browser è un ambiente aperto — chiunque abbia accesso alla macchina può aprire DevTools
- localStorage non è crittografato — i dati sono leggibili da chiunque apra la console
- l’input dell’utente arriva sempre come stringa non validata
Le voci della checklist sono calibrate su questi rischi reali.
Procedura guidata
- Apri il codice del Registro e scorri la checklist.
- Per ogni voce, cerca il punto corrispondente nel codice.
- Segna “OK” se la voce è soddisfatta con un esempio concreto.
- Segna “DA FARE” se manca, con una stima del tempo per correggerla.
- Segna “N/A” se la voce non si applica al tuo progetto (spiega perché).
Attività in classe
Usa questa scheda mentre verifichi:
## Sicurezza — Registro del laboratorio
Voci OK: __ / 15
Voci da correggere: __
Stima tempo correzioni: __ min
Spiegazione guidata per studiare
La sicurezza in un progetto scolastico non significa implementare OAuth o crittografia. Significa non fare errori che un revisore trovererebbe immediatamente: input non validato, messaggi di errore che espongono stack trace, dati sensibili loggati in console, localStorage manipolabile senza controlli.
Il livello di sicurezza ragionevole per il Registro è: un utente onesto non può corrompere i dati per errore, e un utente curioso che apre DevTools non trova informazioni che non dovrebbe vedere.
Passo per passo nel progetto
Segui la checklist voce per voce:
## Checklist sicurezza — Registro del laboratorio
### Validazione input
- [ ] Tutti i campi obbligatori nei form vengono controllati prima di chiamare il caso d'uso
Dove nel codice? (file e funzione):
- [ ] I valori stringa vengono trimmati con .trim() prima dell'uso
Esempio nel codice:
- [ ] Gli ID generati sono con crypto.randomUUID() e non incrementali (1, 2, 3...)
Motivo: gli ID incrementali rendono prevedibile la struttura dei dati
- [ ] I valori letti da localStorage vengono validati prima dell'uso (almeno un controllo che sia un array)
Esempio:
### Messaggi di errore
- [ ] I messaggi mostrati all'utente sono in italiano e non contengono codici interni tipo "Error: STRUMENTO_NON_TROVATO"
Esempio di messaggio corretto:
- [ ] Non vengono mostrati stack trace o dettagli tecnici all'utente
Come lo verifico: apri DevTools, prova un'operazione che fallisce, guarda cosa appare nella UI
- [ ] Il catch nel gestore degli eventi mostra un messaggio generico per gli errori non previsti
Esempio nel codice:
### Dati in localStorage
- [ ] Nessun dato personale identificabile (nome studente, email, ecc.) viene salvato senza necessità
Dati salvati nel Registro: (elenco)
- [ ] Non vengono loggati in console dati che potrebbero essere sensibili
Verificare: cerca tutti i console.log nel codice e controlla cosa stampano
- [ ] La chiave localStorage ha un prefisso specifico (es. "registro_strumenti" non solo "strumenti")
Motivo: evitare collisioni con altri script o applicazioni sullo stesso dominio
### Gestione degli errori
- [ ] Ogni caso d'uso ha un try/catch nel suo punto di chiamata (nella Presentation)
File e riga dove si trova il try/catch principale:
- [ ] Gli errori infrastrutturali (localStorage non disponibile, JSON corrotto) vengono catturati
Come gestisci il caso in cui JSON.parse fallisce?
- [ ] Non ci sono chiamate a archivio.caricaTutti() senza gestione del caso di dato null
Controlla: cosa succede se localStorage.getItem restituisce null?
### Comportamento con input anomali
- [ ] Cosa succede se l'utente invia un form con ID strumento vuoto?
Comportamento attuale:
- [ ] Cosa succede se l'utente inserisce un ID che non esiste?
Comportamento attuale:
- [ ] Cosa succede se i dati in localStorage sono stati modificati a mano e sono corrotti?
Comportamento attuale:
Esempio JS — validazione input e gestione dato null
// infrastructure/archivioStrumentiLocalStorage.js — con gestione robusta
export function caricaTutti() {
try {
const raw = localStorage.getItem("registro_strumenti");
if (!raw) return []; // localStorage vuoto → array vuoto, non errore
const parsed = JSON.parse(raw);
if (!Array.isArray(parsed)) {
console.warn("Dati corrotti in localStorage — reset array strumenti");
return [];
}
return parsed.map(dtoToStrumento);
} catch (errore) {
console.error("Errore lettura localStorage:", errore.message);
return [];
}
}
// presentation/azioni.js — validazione input prima del caso d'uso
btnPresta.addEventListener("click", () => {
const strumentoId = inputId.value.trim(); // .trim() obbligatorio
if (!strumentoId) {
mostraMessaggio("Inserisci un ID strumento valido.");
return; // blocca prima di chiamare il caso d'uso
}
try {
apriPrestito({ strumentoId }, archivioStrumenti, archivioPrestiti);
mostraMessaggio("Prestito aperto con successo.");
} catch (errore) {
const messaggi = {
"STRUMENTO_NON_TROVATO": "Strumento non trovato.",
"STRUMENTO_NON_DISPONIBILE": "Lo strumento non è disponibile."
};
// messaggio generico per errori non previsti — non mostra dettagli tecnici
mostraMessaggio(messaggi[errore.message] ?? "Operazione non riuscita. Riprova.");
}
});
Esempio JS — cosa NON fare
// SBAGLIATO — espone dettagli tecnici all'utente
try {
apriPrestito({ strumentoId }, archivioStrumenti, archivioPrestiti);
} catch (errore) {
mostraMessaggio(errore.message); // mostra "STRUMENTO_NON_TROVATO" all'utente
mostraMessaggio(errore.stack); // mostra lo stack trace — mai farlo
console.log("Dati utente:", datiForm); // logga dati che potrebbero essere sensibili
}
Prova di comprensione
Rispondi per iscritto:
- Perché usare
crypto.randomUUID()invece di ID incrementali? - Cosa mostra il tuo sistema se l’utente cancella manualmente un dato da localStorage e poi ricarica?
- Qual è il rischio di fare
mostraMessaggio(errore.message)direttamente nella UI? - Quale voce della checklist era già OK nel tuo progetto senza averci pensato? Quale mancava completamente?
Errori da evitare
- saltare la validazione dell’input perché “tanto l’utente sa cosa inserire”;
- esporre stack trace o codici di errore interni nella UI;
- loggare in
console.logoggetti con dati degli utenti; - dimenticare il caso
JSON.parse(null)che lancia errore; - non gestire il caso di dato localStorage corrotto.
Prodotto da consegnare
La checklist compilata con tutte le 15 voci e almeno due correzioni applicate al codice. Come verifica: apri DevTools, prova ogni scenario anomalo della lista e controlla il comportamento.
Checklist di chiusura
- ho verificato ogni voce sul codice reale, non a memoria;
- ogni voce ha un esempio concreto nel codice o una motivazione per “N/A”;
- i messaggi di errore mostrati all’utente sono tutti in italiano;
- il
catchprincipale gestisce gli errori non previsti con messaggio generico; JSON.parseè protetto datry/catchnell’adapter.
Risultato atteso
Ho completato la checklist sicurezza.
Voci OK: [numero]/15.
Correzioni applicate: [lista].
Problema più importante trovato: [descrizione].
Il Registro ora gestisce correttamente: input vuoto, ID inesistente, dati corrotti.