Note di Matteo


Progetti

Ho scritto su LinkedIn:

I use the Internet a lot, I read a lot, I browse many websites. I'm disheartened by the amount of stuff I come across that is clearly written by AI or vibe coded. These days you find a project that looks interesting but you quickly realize it's mostly slop. People's writing has become machine writing. Websites and posters all look the same.

I don’t know whether I prefer the old world (my work was slower), but for now, the new world is a very sad flattening of care and effort in things. If people get used to this, what's the point of putting in the effort?

I wrote the blog post below like I would have done 4 years ago, hand-typing 3,500 words. An AI could write some bloated article in 2 minutes, it took me 10+ hours of research, writing and review. It won't make me money and few people will read it. Some parts may sound unnatural (English is not my native language). I still think that's the right thing to defend.

#553 /
6 luglio 2026
/
13:37
/ #ai#mondo#scrivere

DMARC e DNSSEC

Ho pubblicato un articolo su DMARCwise (Why DMARC's new "np" tag can fail with DNSSEC) che evidenzia come rilevare se un dominio esiste o meno è più complicato di quello che la RFC di DMARC suggerisce quando c'è di mezzo DNSSEC. Molti grossi provider DNS, come Cloudflare, NS1, AWS Route 53, Azure DNS, Oracle Cloud DNS e Bunny DNS, usano il metodo NSEC "black lies" o "compact denial of existence" (RFC 9824) per semplificare la generazione della risposta DNS negativa, rinunciando però così al codice di risposta NXDOMAIN, che è il metodo con cui storicamente si rilevava la mancata esistenza di un dominio.

Visto che di questi tempi serve dirlo, ho scritto l'articolo di 3.500 parole a mano impiegandoci più di 8 ore di lavoro. Ho usato Codex con GPT-5.5 per revisionare typo, sintassi, grammatica e correttezza del contenuto, applicando qualche correzione qua e là.

L'ho pubblicato ieri su Hacker News, dove di domenica è più facile ottenere attenzioni, e ora ha 50 punti e 20 commenti. Posizione massima in homepage, numero 10:

Il traffico è stato di circa 1.000 visite ma con un impatto essenzialmente irrilevante sul resto del sito (zero nuove iscrizioni):

#552 /
6 luglio 2026
/
09:40
/ #dev

Ho pubblicato Il digitale secondo Trentino Trasporti (parte 4 - edizione olimpica) sul mio blog:

Sono in corso le Olimpiadi invernali Milano-Cortina, che si svolgono in parte anche in Trentino, a Tesero e Predazzo (val di Fiemme). Per l’occasione sono stati finanziati diversi interventi legati al trasporto pubblico, tra cui il rinnovamento della stazione ferroviaria di Trento e il nuovo hub intermodale di Cavalese (bello).

Trentino Trasporti ha poi pubblicato una sezione dedicata del sito, tra l’altro rinnovato da poco, per illustrare le linee di autobus che si possono usare per raggiungere i luoghi delle gare.

Come se la sono cavata? Eh…

#350 /
14 febbraio 2026
/
15:22
/ #mobilità

Le cit. su questo sito hanno un nuovo stile.

Prima:

Dopo:

#316 /
31 gennaio 2026
/
17:55
/ #dev#web-dev

2FA for developers

Ho aggiunto il supporto all'autenticazione a due fattori su DMARCwise e ho fatto fatica a trovare informazioni su best practice attorno alla 2FA con OTP, per cui segno quello che ho scoperto qui.

Intanto, l'algoritmo si chiama Time-based One-Time Password (TOTP) e permette di generare un codice di N cifre ogni T secondi partendo da un secret. Non tutte le app "authenticator" supportano tutte le configurazioni, per cui la più comune è:

  • Codici di 6 cifre.
  • Intervallo di tempo T di 30 secondi.
  • Algoritmo HMAC-SHA1.

Il secret nella maggior parte dei casi è di 20 byte (160 bit) e viene codificato in Base32 (es. CVEBO7GKWLFDRBJRPPTOZ7I6VEPDIGIT). Va generato diverso per ogni utente.

Per la verifica del TOTP la RFC consiglia di usare una tolleranza (drift window) di +/- un intervallo di tempo T (quindi vale sia il codice precedente che quello successivo).

Il secret andrebbe cifrato prima di essere inserito nel database. Nel mio caso ho scelto AES-256 GCM. Nel db vanno quindi salvati il secret cifrato (Base64) più il nonce e il tag AES.

Per la validazione dei codici ho usato la libreria Otp.NET per .NET/C#. Per AES ho usato l'implementazione nativa di .NET.

Per la configurazione iniziale del secondo fattore, all'utente vanno forniti il secret e i vari parametri menzionati sopra (o anche no, dato che quelli indicati qui sopra sono di solito il default), oppure un QR code che contiene un URI con questo formato (inizialmente definito da Google ma ora standard de facto):

otpauth://totp/{label}:{accountName}?secret={secret}&issuer={issuer}";

I parametri vanno URL encoded. La prima etichetta viene mostrata nella UI dell'applicazione authenticator di turno (Google Authenticator, Ente Auth, ecc.) assieme al nome dell'account, mentre l'issuer dovrebbe essere a uso interno.

Il codice QR lo genero server-side in SVG con ZXing.QrCode e lo ritorno nella risposta JSON delle API. Probabilmente si può fare anche client-side, ma avevo già generato QR in C# in un altro progetto per cui ho riciclato il codice.

Per confermare l'abilitazione della 2FA l'utente deve inserire un primo codice TOTP generato dall'app authenticator. C'è la possibilità che l'utente abbandoni il processo a metà, per cui ci vuole un cleanup delle configurazioni che non sono ancora state abilitate dopo 24/48 ore.

Andrebbero poi generati e forniti dei codici di backup/recupero. Nel mio caso sono 10 codici di 8 caratteri presi dall'alfabeto ABCDEFGHJKLMNPQRSTUVWXYZ23456789 (es. BVEZ-MMWP). Sono hashati con Argon2id, come le password, e salvati in una tabella del db. Di conseguenza nel momento della verifica del backup code bisogna verificarli tutti uno a uno per trovare se c'è un match, e poi segnare il codice individuato come già usato.

Come si implementa la verifica del secondo fattore in fase di login? Il login restituisce un token di tipo TwoFactorPending e il frontend fa redirect alla pagina di verifica. Questo token temporaneo permette di usare solo l'endpoint di verifica 2FA. Se il codice inserito dall'utente è corretto viene invalidato il token temporaneo (che ha comunque scadenza breve, es. 5 minuti) e ne viene creato uno nuovo "standard".

La disattivazione del secondo fattore deve richiedere la password dell'utente, mentre la rigenerazione dei codici di backup deve richiedere un codice TOTP valido (per verificare che l'utente sia effettivamente ancora in possesso del secondo fattore).

Bonus: il 95% del codice è stato scritto da Claude Code e dall'inizio alla fine ci abbiamo impiegato circa 3 giorni (progettazione, implementazione di 6 endpoint backend, integration test e tutta la UI con SvelteKit).

#291 /
16 gennaio 2026
/
20:25
/ #dev#security

certs.email

Ho pubblicato certs.email: un mini-servizio per essere notificati all'avvicinamento della scadenza dei certificati SSL/TLS dei propri domini.

È gratis e open source e in realtà mi serve prevalentemente per avere un dominio in più che invia email, per poter testare meglio DMARCwise.

#290 /
15 gennaio 2026
/
17:32
/ #dev#security

Nuovo mini progetto work in progress:

#262 /
24 dicembre 2025
/
15:28
/ #dev