
Joomla su LiteSpeed: CSS e JavaScript in 403 con query string
- Joomla
- 17 settembre 2026
Indice dei contenuti
Il backend Joomla si apre, ma appare quasi privo di CSS. I menu non rispondono e diverse funzionalità JavaScript smettono di funzionare. Nel frattempo, il frontend continua a essere normalmente utilizzabile.
In questo caso reale, il problema è stato isolato confrontando due richieste allo stesso file: senza query string il server rispondeva HTTP 200; con il token completo del media versioning Joomla restituiva HTTP 403.
Il comportamento indicava un blocco legato al trattamento della richiesta lato server. Cambiare temporaneamente il valore di versioning ha consentito di recuperare l’operatività del backend, ma non ha risolto la causa del blocco.
Il ticket presso il provider è ancora aperto: non è stato confermato quale regola o componente di sicurezza generi il 403.
Joomla backend senza CSS: i sintomi osservati
L’ambiente interessato utilizzava:
| Componente | Configurazione |
|---|---|
| CMS | Joomla 3.8.5 |
| PHP | 5.6 |
| Web server | LiteSpeed |
| Template amministrativo | Isis |
Il frontend continuava a funzionare, mentre l’amministrazione presentava due problemi evidenti: mancavano buona parte degli stili e diverse interazioni non erano operative.
Questa combinazione suggeriva di controllare il caricamento degli asset prima di intervenire sul template. Un backend senza CSS può dipendere da risorse non raggiungibili; menu e pulsanti inattivi possono essere la conseguenza del mancato caricamento delle librerie JavaScript.
La differenza tra frontend e backend, da sola, non identificava la causa: le due aree possono richiedere risorse e URL diversi. Il passaggio successivo era verificare quali richieste fallissero realmente.
Analizzare CSS e JavaScript nella scheda Network
Aprendo gli strumenti sviluppatore del browser e ricaricando l’amministrazione, nella scheda Network comparivano risposte HTTP 403 per alcuni file CSS e JavaScript.
Per ripetere una verifica simile:
- Aprire DevTools prima di ricaricare la pagina.
- Selezionare Network e disabilitare temporaneamente la cache del browser.
- Filtrare le richieste per CSS e JavaScript.
- Controllare stato HTTP, URL completo, header e corpo della risposta.
- Confrontare una richiesta fallita con una variante funzionante.
L’URL completo è decisivo: limitarsi al nome template.css nasconde proprio il dettaglio che, in questo caso, cambiava il risultato.
Anche la Console può aiutare, ma gli errori JavaScript possono essere conseguenze secondarie. Se jQuery non viene caricato, gli script che lo utilizzano possono fallire a cascata. Conviene quindi partire dalla richiesta di rete bloccata.
Il test decisivo: stesso file, HTTP 200 oppure 403
Il confronto più significativo riguardava il foglio di stile del template Isis.
Senza query string:
/administrator/templates/isis/css/template.css
→ HTTP 200
Con il token completo generato dal media versioning:
/administrator/templates/isis/css/template.css?76822fa6c99b0bedb5fe9d45ee7638a8
→ HTTP 403
Lo stesso comportamento interessava JavaScript come:
/media/jui/js/jquery.min.js?76822fa6c99b0bedb5fe9d45ee7638a8
→ HTTP 403
Il file JavaScript senza query string risultava accessibile.
Ulteriori prove hanno permesso di restringere il problema:
| Variante della richiesta | Esito osservato |
|---|---|
| File senza query string | Funzionante |
Query string semplice ?x=1 | Funzionante |
| Query string corta derivata dal token | Funzionante |
| Token completo del media versioning | HTTP 403 |
Questi risultati non dimostrano che LiteSpeed rifiutasse tutte le query string o qualsiasi stringa lunga. Dimostrano che quel valore completo, nelle condizioni del test, era associato al blocco.
Per distinguere un controllo sulla lunghezza da uno sul contenuto sarebbero necessarie altre prove controllate e, soprattutto, i log del server.
Perché il sospetto riguarda il server e non un CSS corrotto
I file esistevano ed erano leggibili. Le directory avevano permessi 755 e i file 644. Inoltre, nel caso osservato, il 403 veniva restituito direttamente da LiteSpeed.
Il dato più forte restava però il confronto: mantenendo lo stesso percorso e cambiando soltanto la query string, la risposta passava da 200 a 403.
Questo rendeva poco plausibile un problema limitato al contenuto del CSS o del JavaScript. Un errore di sintassi può compromettere lo stile o l’esecuzione dopo il download; non spiega normalmente un rifiuto HTTP selettivo basato sull’URL richiesto.
I permessi numerici, da soli, non escludono ogni problema di accesso, perché possono intervenire proprietario, ACL e configurazione del server. Tuttavia, l’accessibilità dello stesso file senza token rendeva questa pista meno coerente con le osservazioni.
Non era emersa neppure una normale regola evidente nel .htaccess capace di spiegare il comportamento. Questo non escludeva configurazioni ereditate o regole non visibili dall’account hosting.
La conclusione diagnostica era quindi circoscritta: indagare il trattamento lato server delle richieste contenenti quello specifico token. Un filtro di sicurezza era un’ipotesi plausibile, ma il componente responsabile restava da identificare.
La documentazione LiteSpeed descrive diverse possibili cause di 403, comprese regole ModSecurity: la presenza di questo codice HTTP non basta ad attribuire automaticamente il problema a un WAF specifico. Documentazione LiteSpeed sui 403.
Come funziona il media versioning degli asset Joomla
Il media versioning aggiunge una versione all’URL degli asset per favorire il caricamento delle risorse aggiornate.
Il principio è il cache busting: se cambia l’URL, il browser può distinguere la nuova risorsa da quella già memorizzata. Il comportamento delle cache intermedie dipende anche dalla loro configurazione.
La documentazione della serie Joomla 3 descrive la media version come una stringa aggiunta agli asset del core per favorire il ricaricamento di CSS e JavaScript. API Joomla 3: media version.
Nel template amministrativo del caso analizzato erano presenti chiamate come:
JHtml::_('script', 'template.js', array(
'version' => 'auto',
'relative' => true
));
JHtml::_('stylesheet', 'template.css', array(
'version' => 'auto',
'relative' => true
));
L’opzione 'version' => 'auto' richiedeva il versioning automatico. Negli URL osservati, il risultato era un token dopo il punto interrogativo, senza un nome di parametro come ver=.
Quel token era un identificatore di versione, non un’indicazione che il file fosse danneggiato. Il problema emergeva quando la richiesta contenente il valore completo veniva trattata dal server.
I workaround temporanei applicati al template Isis
L’obiettivo immediato era recuperare l’accesso operativo all’amministrazione, mantenendo aperta l’indagine con l’hosting.
Gli interventi seguenti riguardano il caso Joomla 3.8.5 con Isis: non sono istruzioni universali da applicare a qualunque versione Joomla.
Disattivare il versioning per alcuni asset
Come primo intervento temporaneo, per alcune risorse l’opzione è stata modificata così:
JHtml::_('script', 'template.js', array(
'version' => false,
'relative' => true
));
JHtml::_('stylesheet', 'template.css', array(
'version' => false,
'relative' => true
));
Con 'version' => false si evita l’aggiunta della versione attraverso quelle chiamate.
Il limite è la copertura: intervenire sul CSS e sullo script del template non modifica necessariamente le risorse caricate da framework, componenti o plugin.
Impostare temporaneamente una media version diversa
Successivamente è stato applicato un workaround più generale nel template amministrativo, prima del caricamento del framework JavaScript:
// Workaround temporaneo, da rimuovere dopo la correzione lato hosting.
$this->setMediaVersion('1');
Nel contesto del template, il metodo imposta la media version del documento. La relativa API è documentata nella serie Joomla 3. API Joomla: Document::setMediaVersion.
Nel caso osservato, il valore '1' ha consentito di evitare il token che provocava il blocco. Non significa che sia un valore universalmente “sicuro” o che riscriva qualsiasi URL prodotto dalle estensioni.
Dopo la modifica:
- i CSS del backend venivano caricati;
- jQuery risultava nuovamente disponibile;
- i menu amministrativi funzionavano;
- le richieste principali erano tornate HTTP 200.
Prima di intervenire su un’installazione analoga, occorre conservare una copia del file e documentare la modifica: gli aggiornamenti possono sovrascrivere gli interventi diretti sul template.
Perché entrambi gli interventi devono restare temporanei
Disabilitare il versioning riduce l’efficacia del cache busting. Anche fissare stabilmente la versione a '1' interrompe il normale cambiamento dell’identificatore.
Dopo un aggiornamento, browser o cache intermedie potrebbero continuare a utilizzare risorse precedenti, secondo le rispettive politiche di cache. Il backend potrebbe quindi presentare nuovi malfunzionamenti dovuti a file non allineati.
Entrambi gli interventi aggirano il sintomo: non correggono la regola che genera il 403.
Il problema aggiuntivo riscontrato con JCE Editor
Durante il ripristino è emerso anche un problema con JCE Editor. Passando temporaneamente a TinyMCE, le funzioni di modifica e salvataggio degli articoli sono tornate operative.
Questo risultato va descritto senza estendere oltre le prove la diagnosi.
Il cambio di editor ha recuperato quelle funzioni, ma non dimostra che JCE fosse difettoso né che il suo problema dipendesse dalla stessa regola che bloccava CSS e JavaScript.
Per approfondire servirebbe verificare separatamente:
- gli asset richiesti da JCE;
- gli eventuali errori nella Console;
- le richieste generate durante modifica e salvataggio;
- la versione dell’estensione e la compatibilità con l’ambiente.
TinyMCE è stato quindi un ulteriore ripiego operativo temporaneo, non la prova della causa del malfunzionamento di JCE.
La soluzione definitiva da richiedere al provider hosting
La correzione definitiva richiede di individuare lato hosting la regola o il componente che rifiuta la richiesta legittima, quindi correggerne il comportamento.
Il provider dovrebbe correlare le prove con i log del web server e degli eventuali sistemi di sicurezza. LiteSpeed documenta anche l’integrazione ModSecurity/WAF e la registrazione dei relativi errori nei log del server. Documentazione LiteSpeed su ModSecurity/WAF.
Un ticket utile deve contenere:
- data, ora e fuso orario delle prove;
- URL completo funzionante e URL bloccato;
- IP sorgente del test, comunicato privatamente;
- codici HTTP, header e risposta ricevuta;
- risultati con query string semplice, token corto e token completo;
- descrizione dei workaround già applicati.
La richiesta tecnica può essere formulata così:
Lo stesso file statico restituisce HTTP 200 senza query string e HTTP 403 con il token completo allegato. Potete verificare nei log quale componente genera il rifiuto e, se presente, identificare regola e condizione che lo attivano?
Se viene confermato un falso positivo, l’intervento dovrebbe essere mirato. Disabilitare globalmente il WAF non è una correzione appropriata del singolo problema.
Dopo la modifica lato hosting, occorre riprovare l’URL originariamente bloccato, rimuovere i workaround, ripristinare il versioning automatico e verificare nuovamente le funzioni amministrative.
Al momento della stesura, il ticket è ancora aperto: non è disponibile una conferma del provider sulla causa precisa.
Checklist diagnostica per file statici in 403
Questo metodo è riutilizzabile anche su WordPress e su altre applicazioni che aggiungono versioni agli URL degli asset. Cambiano le API del CMS, ma resta valido il confronto tra richieste.
| Controllo | Informazione da ricavare |
|---|---|
| Individuare le richieste fallite | Quali risorse sono realmente bloccate |
| Confrontare URL con e senza query | Se il rifiuto dipende dalla query string |
| Provare varianti controllate | Quali valori riproducono il problema |
| Mantenere uguali sessione e condizioni | Evitare confronti falsati |
| Controllare corpo e header | Distinguere asset, errore e reindirizzamento |
| Verificare file e accessi | Escludere problemi del percorso |
| Correlare richieste e log | Identificare il componente responsabile |
| Registrare le modifiche temporanee | Consentire il ripristino |
| Riprovare dopo la correzione | Verificare la rimozione della causa |
Anche un HTTP 200 va controllato: deve contenere effettivamente il CSS o JavaScript atteso, non una pagina HTML di login o di errore.
Backend ripristinato, diagnosi lato hosting ancora aperta
Il passaggio risolutivo per la diagnosi è stato confrontare lo stesso asset con e senza media version. Questo ha spostato l’indagine dai file al trattamento della richiesta lato server.
I workaround hanno ripristinato le funzioni principali, ma la chiusura tecnica del problema richiede ancora l’identificazione e la correzione della regola responsabile. Il versioning automatico dovrà poi essere ripristinato.
FAQ tecniche
Per i test con curl è meglio usare GET oppure HEAD?
Conviene partire da GET, lo stesso metodo normalmente utilizzato dal browser per caricare gli asset. HEAD può essere gestito diversamente e non restituisce il corpo utile a riconoscere una pagina di blocco.
Come confrontare da terminale le due richieste?
Sostituendo example.com con il dominio da verificare:
curl -sS -D - -o /dev/null \
'https://example.com/administrator/templates/isis/css/template.css'
curl -sS -D - -o /dev/null \
'https://example.com/administrator/templates/isis/css/template.css?76822fa6c99b0bedb5fe9d45ee7638a8'
Questi comandi mostrano gli header senza scaricare il corpo sul terminale.
E se curl restituisce 200 mentre il browser riceve 403?
Le richieste potrebbero differire per cookie, header, IP sorgente o passaggio attraverso una cache. Occorre confrontarle mantenendo condizioni equivalenti, proteggendo eventuali credenziali presenti nelle richieste copiate.
L’header Server: LiteSpeed identifica la regola responsabile?
No. Può indicare il server che risponde, ma non identifica da solo il componente che ha deciso il blocco. Servono log correlati alla richiesta ed eventualmente l’identificativo della regola.
È utile allegare un file HAR al ticket hosting?
Sì, perché documenta le richieste di rete. Prima di condividerlo bisogna verificare che non contenga cookie, token di sessione, dati personali o altre informazioni riservate non necessarie alla diagnosi.
Se il tuo backend Joomla presenta CSS mancanti o JavaScript in 403, posso offrirti assistenza tecnica Joomla, analizzare le richieste bloccate e raccogliere le evidenze necessarie per un intervento mirato con il provider hosting.






















