Note di Matteo


#security

DNS-PERSIST-01: A New Model for DNS-based Challenge Validation. C'è un nuovo tipo di challenge di autorizzazione nel protocollo ACME per l'emissione e rinnovo dei certificati TLS. Permette di verificare la proprietà di un dominio con un record DNS persistente, da impostare una volta con validità infinita. Normalmente si usa un record TXT _acme-challenge con un token con validità associata all'ordine del certificato. Il nuovo metodo dns-persist-01 permette invece di autorizzare uno specifico account ACME, opzionalmente con una data di scadenza:

_validation-persist.example.com. IN TXT (
  "letsencrypt.org;"
  " accounturi=https://acme-v02.api.letsencrypt.org/acme/acct/1234567890"
)
#385 /
16 marzo 2026
/
15:07
/ #security

Andrea Ayer in Why IP Address Certificates Are Dangerous and Usually Unnecessary spiega perché i certificati per indirizzi IP sono poco sicuri. Per via della rapida intercambiabilità degli IP in ambienti cloud e delle regole di validazione della proprietà dell'indirizzo molto allentate, è relativamente facile per un attaccante disporre di un certificato valido per un indirizzo IP che non è più autorizzato a rappresentare.

The basic security property provided by a certificate is that the certificate authority has validated that the certificate subscriber (the person who applies for the certificate and knows its private key) is authorized to represent the domain name or IP address in the certificate. This ensures that the other end of a TLS connection is truly the domain or IP address that you want to connect to, not a MitM impostor.

But the validation is not done every time a TLS connection is established; rather, it was done at some point in the past. Thus, the certificate subscriber may no longer be authorized to represent the domain or IP address.

How old might the validation be? As of February 2026, certificate authorities are allowed to issue certificates that are valid for up to 398 days. So the validation may be 398 days old. But it gets worse. When issuing a certificate, CAs are allowed to rely on a validation that was done up to 398 days prior to issuance. So when you establish a TLS connection, you may be relying on a validation that was performed a whopping 796 days ago. You could be talking not to the current assignee of the domain or IP address, but to anyone who was assigned the domain or IP address at any point in the last 2+ years.

È un problema che c'è evidentemente anche con i domini, ma lo spazio dei nomi di dominio è molto più grande di quello degli IPv4 e quindi il problema non è di fatto un problema:

This is a problem with both domains and IP addresses, but it's way worse with IP addresses. While it's still very possible to register a domain that no one has ever registered before, you don't have this luxury with IPv4 addresses. There are no unassigned IPv4 addresses left; when you get an IPv4 address, it has already been assigned to someone else.

Questa vulnerabilità si ridurra assieme alla riduzione della durata massima dei certificati (47 giorni + 10 giorni di periodo di validazione nel 2029). Nel frattempo si può consultare o monitorare i log di trasparenza (es. crt.sh) per vedere quali certificati sono stati emessi per un indirizzo IP o un dominio.

#355 /
22 febbraio 2026
/
10:22
/ #reti#security#cloud

WhatsApp Encryption, a Lawsuit, and a Lot of Noise è un ottimo articolo di Matthew Green, esperto di crittografia e professore della Johns Hopkins University, sulla recente causa di uno studio legale nei confronti di Meta in cui si sostiene che WhatsApp non sia in realtà end-to-end encrypted. Alla causa è seguito l'appoggio, ovviamente, dei soliti mistificatori Elon Musk e Pavel Durov.

Il riassunto è che le accuse sono completamente infondate e che se WhatsApp stesse facendo qualcosa di losco ce ne saremmo accorti e sarebbe la frode più grande della storia della tecnologia. "Se stai commettendo un crimine, farlo in un modo che sia rilevabile forensicamente è molto stupido".

Given the closed-source nature of WhatsApp, how do we know that WhatsApp is actually encrypting its data? The company is very clear in its claims that it does encrypt. But if we accept the possibility that they’re lying: is it at least possible that WhatsApp contains a secret “backdoor” that causes it to secretly exfiltrate a second copy of each message (or perhaps just the encryption keys) to a special server at Meta?

I cannot definitively tell you that this is not the case. I can, however, tell, you that if WhatsApp did this, they (1) would get caught, (2) the evidence would almost certainly be visible in WhatsApp’s application code, and (3) it would expose WhatsApp and Meta to exciting new forms of ruin.

The most important thing to keep in mind here is that Meta’s encryption happens on the client application, the one you run on your phone. If the claims in this lawsuit are true, then Meta would have to alter the WhatsApp application so that plaintext (unencrypted) data would be uploaded from your app’s message database to some infrastructure at Meta, or else the keys would. And this should not be some rare, occasional glitch. The allegations in the lawsuit state that this applied to nearly all users, and for every message ever sent by those users since they signed up.

Those constraints would tend to make this a very detectable problem. [...] If you’re going to (metaphorically) commit a crime, doing it in a forensically-detectable manner is very stupid.

#331 /
5 febbraio 2026
/
11:12
/ #meta#security

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

A volte sorprende come le grandi aziende prendano così poco seriamente la sicurezza e che sia impossibile segnalare vulnerabilità:

Despite its vast wealth, Condé Nast lacks a security.txt file that explains how to report a vulnerability to them. Nowhere on its site did it plainly explain how to report a vulnerability to them.

Trying to help Condé Nast avoid compromise of what was described to me as a serious vulnerability risking more than 33 million users’ accounts, I reached out to people I know at WIRED. I also reached out to Condé Nast but received no replies from them.

(Condé Nast gets hacked)

#265 /
28 dicembre 2025
/
09:36
/ #security


Let's Encrypt compie 10 anni

A conspicuous part of Let’s Encrypt’s history is how thoroughly our vision of scalability through automation has succeeded.

In March 2016, we issued our one millionth certificate. Just two years later, in September 2018, we were issuing a million certificates every day. In 2020 we reached a billion total certificates issued and as of late 2025 we’re frequently issuing ten million certificates per day. We’re now on track to reach a billion active sites, probably sometime in the coming year.

(LE)

#227 /
14 dicembre 2025
/
10:54
/ #security#cloud


Vercel ha pagato 750mila dollari di bug bounty per 15 bypass WAF contro React2Shell durante il weekend.

#216 /
8 dicembre 2025
/
21:06
/ #security

HTTPS by default

In Chrome dall'ottobre 2026:

One year from now, with the release of Chrome 154 in October 2026, we will change the default settings of Chrome to enable “Always Use Secure Connections”. This means Chrome will ask for the user's permission before the first access to any public site without HTTPS.

#133 /
6 novembre 2025
/
21:07
/ #http#browser#security


Lavorare con Safari è una pena:

  • i cookie Secure non vanno su localhost perché Safari non supporta Secure Context come gli altri browser.
  • i sottodomini di localhost non funzionano fino a macOS 26, da cui starò alla larga per un po'.
  • nella scheda Storage -> Cookies non si vedono i cookie di terze parti o dei sottodomini??? come in tutti gli altri browser.
  • al momento non riesco a far funzionare un semplice cookie SameSite=Lax del tutto, su localhost con HTTPS. Nella risposta c'è, ma non lo salva. Con gli altri browser funziona.
  • ok, non sono l'unico. Rinuncio.
#82 /
18 ottobre 2025
/
10:08
/ #dev#security#browser

Defunte definitivamente quasi tutte le iniziative di Chrome per uccidere i cookie di terze parti (Privacy Sandbox), restano solo i cookie partizionati e poco altro:

CHIPS and FedCM, which improve cookie privacy and security and streamline identity flows respectively, have seen broad adoption, including support from other browsers. We'll continue to support those APIs and evaluate opportunities for future enhancements. We'll also maintain Private State Tokens and explore additional approaches to help developers reduce fraud and abuse.

After evaluating ecosystem feedback about their expected value and in light of their low levels of adoption, we've decided to retire the following Privacy Sandbox technologies: Attribution Reporting API (Chrome and Android), IP Protection, On-Device Personalization, Private Aggregation (including Shared Storage), Protected Audience (Chrome and Android), Protected App Signals, Related Website Sets (including requestStorageAccessFor and Related Website Partition), SelectURL, SDK Runtime and Topics (Chrome and Android). We will follow Chrome and Android processes for phasing out these technologies and share updates on our developer site.

#81 /
18 ottobre 2025
/
09:46
/ #dev#security#browser

Fineco scrive via email: "Attenzione alle frodi bancarie". Alla fine si specifica che il sito ufficiale è https://it.finecobank.com, ma il link non porta lì. Non è così che si costruisce un sistema di fiducia.

#77 /
16 ottobre 2025
/
22:43
/ #security

SameSite e protezione CSRF con Sec-Fetch-Site

Un po' di risorse sulle tecniche moderne per la protezione da CSRF:

#75 /
16 ottobre 2025
/
21:34
/ #dev#security#browser

TIL Argon2 per le password non è più sicuro di bcrypt come si pensa:

[...] Me (@jmgosney) and @Sc00bzT were both on the experts panel for the Password Hashing Competition, and both of us will tell you not to use Argon2 for password hashing. It is weaker than bcrypt at runtimes < 1000 ms.

Yep, we basically completely failed. We set out to identify The One True PHF and instead we selected yet another KDF. We also placed way too much emphasis on "memory hardness" when we should have been emphasizing "cache hardness."

@TerahashCorp

Bottom line, if you're already using argon2, you're totally fine. It's still a good PHF and much better than most everything out there. But if you aren't using argon2, bcrypt is a better choice.

@jmgosney

#69 /
14 ottobre 2025
/
21:07
/ #dev#security