Come funziona questo controllo
Scanaris analizza l'HTML della tua pagina principale e cerca moduli che contengano un campo <input type="password">: un login, una registrazione, un cambio password. Se non ce n'è nessuno, non fa nulla. Se c'è, verifica due cose. Prima: se la pagina stessa è stata servita in HTTP, apre un rilievo di gravità alta, perché tutto ciò che l'utente digita viaggia in chiaro. Seconda: se la pagina è HTTPS ma l'attributo action del modulo inizia con http://, apre un altro rilievo di gravità alta con quell'URL, perché l'invio della password parte non cifrato anche se la pagina che la chiede era sicura. Viene esaminata solo la pagina scansionata; se il tuo login vive su un'altra rotta, scansionala direttamente.
Perché è importante
Una password è il dato più prezioso che un utente ti consegna, ed è quello che le connessioni non cifrate trattano peggio. Quando un modulo viaggia in HTTP, chiunque lungo il percorso (il wifi di un bar, il fornitore di accesso, un router compromesso) legge utente e password così come sono, senza alcuna tecnica. E siccome la maggior parte delle persone riutilizza le password, ciò che trapela non è solo l'accesso al tuo sito. I browser lo sanno: Chrome e Firefox segnano in rosso qualsiasi campo password in una pagina HTTP e avvisano l'utente che "non è sicuro", quindi oltre a un rischio reale è una perdita di fiducia visibile.
Perché succede
Il primo caso compare quando il sito non reindirizza da HTTP a HTTPS e qualcuno arriva da un vecchio link. Il secondo è quasi sempre un action scritto a mano durante lo sviluppo (http://localhost:3000/login o http://api.miodominio.it/auth) che nessuno ha cambiato, o un modulo copiato da un esempio. Succede anche quando il login punta a un servizio esterno che non ha ancora il certificato.
Come risolvere
- Servi tutto il sito in HTTPS e reindirizza HTTP. È la base di tutto il resto; il controllo reindirizzamento HTTPS ti dice se ce l'hai. Su Vercel, Netlify o Cloudflare è già fatto; sul tuo server, un blocco di reindirizzamento in nginx o Apache.
- Cambia l'action in un percorso relativo (
action="/login"), che eredita il protocollo della pagina, o nell'URL completo conhttps://. Se usi un framework (Nuxt, Next.js, Laravel, Django), l'URL dell'API deve venire da una variabile d'ambiente con il valore di produzione, non essere scritto nel template. - Se il login lo gestisce un terzo (Auth0, Supabase, Firebase, Clerk), il suo endpoint è già HTTPS; il rilievo punta allora a un
actiontuo che non dovrebbe esserci. - Aggiungi HSTS perché il browser non riprovi mai più HTTP, nemmeno al primo salto; lo misura HSTS debole.
Verifica che sia risolto
curl -sI http://tuodominio.it/login | grep -iE "^(HTTP|location)"
curl -s https://tuodominio.it/login | grep -oE '<form[^>]*action="[^"]*"'
Il primo deve restituire un 301 verso https://. Nel secondo, nessun action può iniziare con http://; di norma vedi percorsi relativi o nulla (i moduli senza action inviano alla pagina stessa).
Domande frequenti
Il mio modulo invia via JavaScript, non tramite action. Mi riguarda?
Questo controllo guarda l'attributo action, quindi un modulo che fa fetch non viene segnalato per quella via. Ma il rischio è lo stesso se il fetch punta a http://: in una pagina HTTPS il browser lo bloccherà come contenuto misto, e in una pagina HTTP viaggerà in chiaro. Controlla comunque l'URL dell'API.
È solo un ambiente di test senza utenti reali.
Allora non scansionarlo come se fosse produzione, o accetta il rilievo. Ma attenzione agli ambienti di test che finiscono su Google: se qualcuno vi crea un account con la sua password abituale, il problema è reale.
Un campo password in una pagina HTTPS con action relativo va bene?
Sì. È la configurazione corretta e non genera rilievi. Resta da guardare come conservi poi la sessione: cookie insicuri e token nello storage coprono quella parte.