Torna al blog
Tecnologia

Immagine rotta su un altro sito? Albero di debug 403 e hotlink 2026

Pubblicato il13 min read
Condividi

Incolli il link di un'immagine su un blog, in anteprima locale è tutto a posto. Pubblichi, e gli altri vedono un riquadro con l'icona rotta. O peggio ancora: al posto dell'immagine c'è uno spazio bianco, niente di niente.

In questa buca ci sono caduto più di una volta. Una volta è esplosa in produzione mentre spostavo le immagini del forum di un amico: in locale tutto verde, online un terzo delle miniature in home era rotto, e io pensavo pure fosse la cache non svuotata. Ho fatto debug per tre giorni prima di scoprire che non era colpa mia — era il sito sorgente delle immagini che aveva attivato l'hotlink protection: qualsiasi richiesta non proveniente dal suo stesso dominio veniva bloccata.

Dal punto di vista architetturale, "l'immagine non si vede su un altro sito" è in realtà tre fallimenti completamente diversi mescolati in una sola frase. Per aggiustare giusto, il primo passo è distinguere quale dei tre hai davanti.

Prima distinguiamo: 403, immagine rotta e 200 bianco sono tre cose diverse

Molti, appena vedono l'immagine sparita, la chiamano genericamente "immagine rotta" e poi provano a caso. Il fatto è che le cause profonde di questi tre sintomi sono lontanissime, e anche i percorsi di debug corrispondenti sono diversi.

Sintomo Codice HTTP Causa più probabile Direzione di debug
Riquadro icona rotta (icona spezzata) 403 / 404 Bloccato da hotlink, o link sbagliato di suo Controlla Referer e correttezza URL
Riquadro icona rotta (icona spezzata) 200 ma non immagine Ricevi una pagina HTML di errore, non un file immagine Controlla Content-Type
Spazio bianco (senza icona spezzata) 200 CSS che copre, o CSP che blocca il caricamento Controlla Console DevTools e CSP
Icona che gira e poi sparisce Timeout / CORS Policy cross-origin o timeout del server Controlla i dettagli della request in Network

Prima il codice di stato, poi il Content-Type, e solo alla fine la schermata. Se inverti quest'ordine, giri a vuoto.

Come funziona sotto: Referer e hotlink protection

Per capire perché l'immagine di un altro sito viene bloccata, bisogna prima sapere cosa fa di nascosto il browser mentre carica l'immagine.

Quando la pagina A usa <img src="https://B.com/photo.jpg"> per caricare l'immagine del sito B, la richiesta emessa dal browser porta con sé un header Referer (sì, questa parola è storicamente scritta male, manca una r, e l'errore è rimasto fino a oggi). Questo header dice al sito B: "questa immagine è stata richiesta dalla pagina del sito A".

Il funzionamento è questo: il server o il CDN del sito B, ricevuta la richiesta, prende il dominio del Referer e lo confronta con una whitelist. La logica di confronto è più o meno —

1. Referer vuoto (apertura diretta, segnalibro) → dipende dalla config: passa o blocca
2. Dominio del Referer nella whitelist → passa
3. Dominio del Referer fuori dalla whitelist → risponde 403 Forbidden

Questo è l'hotlink protection. Lo scopo è semplice: non far consumare ad altri la propria banda gratis. Se incorpori nel tuo sito un'immagine del sito B, ogni volta che qualcuno naviga la tua pagina il conto del traffico va sulla testa del sito B, e a B ovviamente la cosa non va giù.

Un dettaglio che molti non sanno: la Referrer-Policy predefinita dei browser moderni è strict-origin-when-cross-origin. Nelle richieste cross-origin invia solo il "dominio di origine" (per esempio https://a.com/), non il percorso completo. Quindi l'hotlink protection ottiene comunque il tuo nome di dominio, abbastanza per confrontarlo con la whitelist e abbastanza per bloccarti. Ecco perché l'anti-hotlink riesce a fermare l'hotlink.

Perché la tua immagine si rompe su un altro sito: un albero di debug

Aprendo il principio di sopra, la causa profonda dell'immagine rotta si condensa in un albero. Basta scendere seguendolo.

Ramo 1: il codice di stato è 403?

In tal caso, nove volte su dieci è hotlink protection. Il sito B vede che il tuo Referer non è nella sua whitelist e rifiuta di netto. In questa situazione la config del sito B non la puoi cambiare, l'unica soluzione è smettere di fare hotlink alla sua immagine (la soluzione giusta è più avanti).

Ramo 2: il codice è 200, ma la schermata è rotta?

Apri il contenuto grezzo di questa "immagine". Molto probabilmente hai ricevuto una pagina HTML — certi siti non rispondono 403 ma restituiscono una pagina "vietato l'hotlink" con codice 200. Il browser interpreta l'HTML come immagine e ovviamente te la spezza. Il Content-Type ti smaschera tutto: un'immagine normale è image/jpeg, image/png, una pagina di errore è text/html.

Ramo 3: hai incollato il "link della pagina" e non il "link diretto dell'immagine"?

È la trappola più tipica dei principianti. https://imgur.com/aBcDeFg è una pagina, https://i.imgur.com/aBcDeFg.jpg è il file immagine vero e proprio. Se carichi il primo con <img src>, ricevi un'intera pagina HTML, non un'immagine. Cambia una i. e un'estensione, e il risultato è agli antipodi.

Ramo 4: la Referrer-Policy si è ritorta contro di te?

Uno dei casi più nascosti. Se la tua pagina ha impostato Referrer-Policy: no-referrer, il browser durante il caricamento dell'immagine non invia affatto il Referer. Alcune config di hotlink sono "Referer vuoto sempre bloccato", e così vieni fermato proprio dalla tua stessa impostazione sulla privacy. Nella pratica questo caso salta fuori sui siti molto attenti alla privacy, che spengono a fondo il meta referrer.

Diagnosi pratica: DevTools e curl, due mosse per individuare la causa

Finita la teoria, come si controlla in concreto? Uso fissi due strumenti, che in cinque minuti individuano il novanta per cento delle immagini rotte.

Prima mossa: pannello Network di DevTools

Apri gli strumenti per sviluppatori (F12), passa a Network, ricarica la pagina e nel filtro scrivi il nome del file immagine. Clicca su quella richiesta e guarda tre cose:

  • Status: è 403, 404 o 200?
  • Content-Type nei Response Headers: è image/* o text/html?
  • Referer nei Request Headers: cosa è stato effettivamente inviato? Vuoto o il tuo dominio?

Guardati tutti e tre e la causa profonda quasi affiora da sola.

Seconda mossa: curl per controllare il Referer a mano

DevTools mostra il fenomeno, ma per verificare "se è davvero hotlink" curl è il più netto. Puoi infilare a mano un Referer qualsiasi e vedere come cambia la reazione del server:

# Senza alcun Referer (simula apertura diretta)
curl -I "https://example.com/photo.jpg"

# Con un Referer che "finge di venire dal sito sorgente stesso"
curl -I -H "Referer: https://example.com/" "https://example.com/photo.jpg"

# Con un Referer "dal tuo sito esterno"
curl -I -H "Referer: https://your-blog.com/" "https://example.com/photo.jpg"

L'interpretazione è intuitiva. Se il primo e il terzo rispondono 403 ma il secondo risponde 200 — complimenti, hotlink protection confermato. Il server riconosce solo il Referer del sito sorgente stesso e blocca tutto il resto. Se tutti e tre rispondono 200, allora l'immagine rotta non c'entra con l'anti-hotlink: torna a controllare il tuo URL o la CSP.

La mia abitudine nei test è lanciare le tre righe insieme: confrontare i risultati è molto più chiaro che guardarne una sola. Ecco perché curl è più efficiente che cliccare a caso nel browser.

Comportamento anti-hotlink dei tipici image hosting / CDN

Il carattere predefinito dei vari servizi cambia parecchio. Sotto ci sono le mie osservazioni raccolte in questi anni spostando immagini; le config effettive ognuno può ritoccarle in qualsiasi momento, ma la direzione generale è questa.

Tipo di servizio Anti-hotlink predefinito Comportamento con Referer vuoto Adatto al link diretto esterno?
Nginx / Apache self-hosted Dipende da come lo imposti Di solito passa Dipende dalla config
CDN enterprise (whitelist configurabile) Attivabile o no Impostabile passa o blocca Sì, se configurato giusto
Alcuni image hosting gratuiti Spesso attivo Spesso blocca Spesso bloccato
Domini immagine dei social Quasi sempre attivo Quasi sempre bloccato No, scordatelo
Image hosting orientato alla condivisione Di solito spento Passa Sì, è il suo senso di esistere

Il punto è l'ultima riga. Le immagini dei social (i domini CDN di quei social network), l'URL che copi fuori quasi al cento per cento non fa link esterno, perché il loro modello di business è tenerti chiuso dentro il sito. Portare quelle immagini a incollarle altrove è vicolo cieco.

E l'image hosting orientato alla "condivisione" ha l'anti-hotlink spento di default — il suo senso di esistere è proprio far caricare in modo stabile le tue immagini da siti esterni. Queste due categorie non vanno mai confuse.

La trappola della Referrer-Policy: pure il browser può ritorcersi contro di te

Ho accennato prima a un caso nascosto, qui lo apro, perché è quello che fa dubitare della propria sanità mentale in fase di debug.

La Referrer-Policy è un header che la pagina (quella che emette la richiesta) può impostare. Decide quanta informazione Referer il browser deve inviare. I valori sono diversi:

  • no-referrer: non invia nulla.
  • origin: invia solo il dominio di origine.
  • strict-origin-when-cross-origin: cross-origin invia solo il dominio, con downgrade a HTTP non invia (predefinito moderno).
  • unsafe-url: invia pure il percorso completo (sconsigliato, perde privacy).

Il paradosso è qui. L'anti-hotlink si basa sul Referer per giudicare l'origine, ma le policy sulla privacy incoraggiano a inviarne poco o niente. Quando un sito, per privacy, imposta no-referrer e va a caricare un'immagine con anti-hotlink e "Referer vuoto sempre bloccato", si rompe tutto.

La volta che è esplosa in produzione era proprio così: un sito molto attento alla privacy aveva no-referrer su tutto il sito, e tutte le immagini in link esterno si sono rotte. Sul momento pensavo fosse l'image hosting caduto, ho cercato per un pezzo prima di scoprire che era la mia impostazione meta a strozzare il Referer. Questa mina non è facile da immaginare, perché "rafforzare la privacy" come fa a farti del male?

Il metodo giusto: non fare hotlink alle immagini altrui

Alla fine del debug arrivi a una verità cruda: finché l'immagine non è ospitata da te, qualsiasi "immagine di un altro sito" può sparire in un momento che non controlli. L'altro cambia l'anti-hotlink, cambia URL, cancella il file, o chiude tutto il sito, e la tua pagina si rompe di conseguenza.

Le uniche strade davvero solide sono due.

Primo, ri-ospita l'immagine in un posto che controlli tu. Non incorporare direttamente l'URL di un altro. Scarica l'immagine, caricala sul tuo spazio o su un image hosting che permette il link esterno, e usa quell'URL stabile. Dal punto di vista architetturale, questo passo riporta la disponibilità della tua pagina dalle mani del server altrui alle tue — finché la sorgente non è sotto il tuo controllo, qualsiasi loro ritocco all'anti-hotlink, revisione della struttura URL o messa offline dell'intero sito si riflette direttamente in un'immagine rotta sulla tua pagina, e nemmeno ricevi un preavviso: spesso lo scopri solo quando te lo segnala un lettore. Se hai già un intero lotto di vecchi link sparsi su domini altrui da spostare in blocco, ho scritto a parte una SOP completa per la sostituzione batch dei link immagine: con uno script scansioni tutti i vecchi URL del sito e li sostituisci in una volta, molto meno faticoso che a mano una per una. Una sorgente controllabile è l'unica sorgente stabile.

Secondo, scegli un image hosting con anti-hotlink spento di default. Molti image hosting gratuiti, per risparmiare banda, bloccano il link esterno e su forum o blog ti mostrano l'immagine rotta. Per il link esterno, scegli un servizio che permette esplicitamente il link diretto.

È anche uno dei principi con cui abbiamo fatto lpic.cc: dopo l'upload ti diamo un URL diretto stabile dell'immagine, senza bloccare di default i siti esterni, così puoi incollarla su forum, blog e Discord e viene mostrata normalmente, senza diventare 403 dal nulla. Per le immagini che vuoi private, la protezione con password controlla chi le vede. Se vuoi provare, carica gratis un'immagine, incolla il link su un'altra pagina e verifichi al volo se regge.

Onestamente devo dire anche i limiti: al momento le immagini del piano gratuito hanno 30 giorni di conservazione, non è archivio permanente, e il servizio si regge sulla pubblicità. Per archivio a lungo termine o grandi librerie commerciali, dovresti valutare un piano professionale a pagamento o un'archiviazione cloud con backup che gestisci tu. Uno strumento ha senso solo se scelto per lo scenario giusto — questo l'ho imparato prendendo la buca.

Domande frequenti (FAQ)

Q: perché lo stesso link immagine da me si apre e su un altro sito si rompe?

Perché quando "apri l'immagine direttamente" il Referer è vuoto o proviene da una sorgente permessa, e l'anti-hotlink passa. Incollata su un altro sito, il Referer diventa quel dominio esterno, non in whitelist, e viene bloccata con 403. Stesso URL, Referer diverso, risultato completamente diverso.

Q: 403 e immagine rotta sono la stessa cosa?

No. Il 403 è un rifiuto esplicito del server (codice 403), l'immagine rotta è solo la rappresentazione visiva del browser che "non riesce a disegnare l'immagine". Il 403 causa immagini rotte, ma l'immagine rotta può venire anche da URL sbagliato, Content-Type sbagliato, CSP che blocca il caricamento e altre cause. Guarda prima il codice di stato per sapere di quale caso si tratta.

Q: impostare la pagina su Referrer-Policy: no-referrer aggira l'anti-hotlink?

A volte sì, a volte è pure peggio. Se l'anti-hotlink dell'altro è "Referer vuoto passa", non inviare il Referer in effetti supera il blocco. Ma se l'altro è "Referer vuoto sempre bloccato", ti si rompe tutto. Questa mossa non è affidabile, non usarla come soluzione buona.

Q: catturo l'immagine con un programma (Python / Node) e prendo comunque 403, che faccio?

Come per il browser — il tuo programma non porta il Referer giusto. Testa prima con curl quale Referer riconosce l'altro, poi aggiungi lo stesso header nella tua richiesta HTTP. Nota però: aggirare l'anti-hotlink altrui per catturare immagini può violare i termini di servizio, valuta tu.

Q: come capire in fretta se un image hosting permette il link esterno?

Carica un'immagine di prova, prendi il suo URL diretto e lancia curl -I -H "Referer: https://google.com/". Se risponde 200 permette il link esterno, se risponde 403 ha anti-hotlink, non usarlo per i siti esterni. Trenta secondi e hai verificato.

References

#hotlink protection#anti-hotlink#403 Forbidden#Referer#Referrer-Policy#CDN#link diretto immagini 2026
H

Scritto da

Harvey Zhang

Co-Fondatore & CTO

Ingegnere backend diventato architetto, offre un'analisi tecnica approfondita dell'infrastruttura di hosting di immagini.