Analizzare una URL

Incolla un indirizzo e guardalo come lo vede un browser: schema, host, porta, percorso, query e frammento, più ogni parametro sulla sua riga. La scomposizione la fa il parser incorporato nel browser — lo stesso che decide dove porta davvero un clic — e non un’espressione regolare, che giudicherebbe diversamente proprio nei casi limite.

Risultato

La risposta compare qui mentre scrivi.

  • Dove gira

    Non viene caricato nulla, perché non c’è nessun file: il calcolo avviene in questa pagina.

  • Nessuna coda, nessun account

    Risponde alla velocità della tua macchina e non chiede mai chi sei.

  • Tutte le volte che vuoi

    Non si conta né si limita nulla: rispondere di nuovo non ci costa niente.

Come funziona

  1. Incolla l’indirizzo. Se manca lo schema, viene assunto https.
  2. Leggi i pezzi separati, con i parametri della query string.
  3. Non è stato caricato niente, e non è stato visitato niente.

Lo stesso parser che usa il tuo browser

La scomposizione qui usa l’oggetto `URL` del browser, cioè l’implementazione dello standard WHATWG che decide davvero dove porta un indirizzo quando ci si clicca sopra. Non è un dettaglio di eleganza: è l’unico modo per essere certi che il risultato mostrato coincida con il comportamento reale.

Le espressioni regolari per le URL girano da vent’anni e sbagliano tutte nello stesso punto, i casi limite — ed è lì che si annidano gli inganni. Una URL costruita per sembrare di un dominio e puntare a un altro passa una regex e non passa un parser, quindi uno strumento basato su regex mostrerebbe esattamente quello che l’autore dell’inganno voleva far vedere.

L’host è il punto in cui la faccenda si fa seria

La domanda che conta davvero è quasi sempre una sola: dove va a finire questo link. La risposta è l’host, e l’host è la parte fra lo schema e la prima barra — non quella che compare per prima nel testo, non quella che si legge meglio.

Da qui nascono gli inganni classici. `https://banca.esempio.it.tracker.example/` ha come host `tracker.example`, non `banca.esempio.it`; una `@` dentro l’indirizzo sposta tutto ciò che la precede nella parte delle credenziali e cambia l’host completamente. Vederlo estratto da solo, in un campo suo, è il motivo per cui questa pagina è utile su un link ricevuto per email.

Qui non si visita niente

La pagina non contatta il dominio, non risolve il nome, non segue redirect e non mostra anteprime. L’indirizzo viene scomposto come stringa e nient’altro, il che è esattamente ciò che serve quando quello che hai in mano è un link sospetto.

La conseguenza vale in entrambe le direzioni. Chi controlla quel dominio non viene a sapere che il link è stato esaminato, il che su un link di phishing con un identificatore unico dentro sarebbe un segnale prezioso per chi lo ha inviato. E l’indirizzo non viene consumato: un link a uso singolo, come una reimpostazione di password, resta valido dopo essere stato analizzato qui.

Perché il percorso esce più corto di come lo hai scritto

Un percorso che contiene `..` o `.` viene normalizzato: `/documenti/a/../b` diventa `/documenti/b`. Non è una semplificazione decisa da questo strumento, è quello che prescrive la specifica e quello che il browser fa prima di inviare la richiesta.

La conseguenza da conoscere è che il percorso mostrato è quello che il server riceverà davvero, e non quello che c’era scritto nel link. Se stai confrontando una URL con una riga di log, la forma normalizzata è quella giusta da confrontare — ed è anche il motivo per cui un tentativo di attraversamento di directory scritto in modo ingenuo si vede a colpo d’occhio qui.

Il frammento resta nella barra degli indirizzi

Tutto quello che segue il `#` viene mostrato qui come parte della URL, e non compare in nessuna richiesta HTTP: il server non lo riceve. È la parte destinata al browser, usata per la posizione dentro la pagina e per lo stato di un’interfaccia.

Ne segue una cosa utile e una fuorviante. L’utile: se una URL presa da un log non ha frammento, non è stato tolto, non è mai arrivato. La fuorviante: il frammento è comunque nella cronologia, nei segnalibri e a disposizione di ogni script della pagina, quindi non è un posto sicuro — è solo un posto che non finisce nei log del server.

La porta che non compare

Se scrivi `https://esempio.it:443/`, la porta non viene mostrata. Non è una svista: 443 è la porta predefinita per `https`, come 80 lo è per `http`, e la specifica prescrive di ometterla perché l’indirizzo con e senza sono lo stesso indirizzo.

Conta in un caso pratico, il confronto fra origini. Due URL che differiscono solo per una porta predefinita esplicita hanno la stessa origine, quindi per le regole di CORS e per la memorizzazione dei dati nel browser sono indistinguibili. Una porta diversa dalla predefinita, invece, viene mostrata e crea un’origine diversa a tutti gli effetti.

Quasi tutto è uno schema valido

Una URL che comincia con `htp://` non è un errore di sintassi: `htp` è uno schema perfettamente formato, semplicemente non ne esiste un gestore. Il parser lo accetta e lo mostra, perché il suo compito è dire com’è fatto l’indirizzo e non se qualcosa saprà cosa farne.

Vale anche per gli schemi che non hanno un host: `mailto:`, `tel:`, `data:` e `javascript:` sono URL a tutti gli effetti e non hanno niente dopo i due punti che assomigli a un dominio. Se il campo dell’host risulta vuoto, la prima cosa da guardare è lo schema — è quasi sempre lì che sta la spiegazione.

Credenziali dentro l’indirizzo

La sintassi `https://utente:[email protected]/` è prevista dalla specifica e i browser la trattano in modo ambivalente: alcuni la accettano, altri la rifiutano o avvisano, perché è stata usata per anni per far sembrare un indirizzo qualcosa che non era.

Qui utente e password vengono mostrati nei loro campi, per rendere visibile che ci sono. È un tipo di URL che compare ancora in vecchie stringhe di connessione e in script interni, ed è sempre un problema: quella password finisce nella cronologia, nei log dei proxy e in qualunque copia-incolla del comando. Se ne vedi una, la cosa da fare non è analizzarla ma sostituirla.

I nomi internazionalizzati vengono riscritti

Un dominio con caratteri accentati non viaggia così com’è: viene convertito in Punycode, la forma che comincia con `xn--`, ed è quella che il sistema dei nomi risolve davvero. Un indirizzo come `perché.example` ha quindi due scritture, e la seconda è quella reale.

La forma Punycode viene mostrata apposta, perché è l’unica in cui due domini diversi si vedono diversi. Parecchi alfabeti contengono lettere identiche a quelle latine, e un dominio composto con quelle è indistinguibile a occhio dall’originale mentre in Punycode diventa una stringa `xn--` evidentemente estranea. È il modo pratico di riconoscere un attacco di omografia senza doverne sapere niente.

Analizzare una URL: domande frequenti

L’indirizzo viene visitato?

No. Non viene contattato il dominio, non viene risolto il nome e non vengono seguiti redirect: la stringa viene scomposta e basta. È voluto, perché una richiesta automatica direbbe a chi controlla quel dominio che il link è stato esaminato, e perché un link a uso singolo non deve essere consumato.

Perché l’host non è quello che mi aspettavo?

Perché l’host è la parte fra lo schema e la prima barra, e non quella che si legge per prima. In `https://banca.esempio.it.tracker.example/` l’host è tracker.example. Una @ dentro l’indirizzo sposta tutto ciò che la precede nelle credenziali e cambia l’host: è esattamente il meccanismo con cui un link inganna chi lo legge di fretta.

Perché la mia porta 443 sparisce?

Perché è quella predefinita per https, come 80 lo è per http, e la specifica prescrive di ometterla: l’indirizzo con e senza è lo stesso indirizzo. Una porta diversa dalla predefinita viene invece mostrata, e crea un’origine diversa ai fini di CORS e della memorizzazione dei dati nel browser.

Perché htp:// non viene segnalato come errore?

Perché non è un errore di sintassi: htp è uno schema ben formato, semplicemente non esiste niente che sappia gestirlo. Il parser dice com’è fatto l’indirizzo, non se qualcuno saprà cosa farne. Lo stesso vale per mailto:, tel: e data:, che sono URL valide senza host.

Se la URL contiene una password, viene mostrata?

Sì, nel suo campo, e apposta: renderla visibile è il modo di accorgersi che c’è. Resta comunque nella tua scheda e non viene inviata da nessuna parte. Se trovi una URL del genere in uno script o in una stringa di connessione, quella password va considerata compromessa e sostituita.

Altri strumenti