
Audit di .htaccess: perché il sito restituisce 500 e quali regole non funzionano
Trascina il file — lo strumento troverà il BOM, le direttive morte, le regole ad alto rischio di errore 500 e i segni di un intervento esterno. Il file viene letto nel tuo browser e non viene inviato da nessuna parte.
Il testo è stato incollato a mano, quindi il blocco di controlli sui byte è stato saltato. Per vedere BOM, CRLF e caratteri invisibili trascina il file stesso.
Un .htaccess pulito non cura una compromissione. Se il sito è compromesso, il codice dannoso vive nel PHP e il .htaccess ne è solo la conseguenza: il dropper riscriverà il file pochi minuti dopo che l'hai ripulito. L'ordine è inverso — prima trovare il codice eseguibile, poi mettere ordine nella configurazione.
Qui comparirà il file di origine con i numeri di riga.
Le righe con rilievi sono contrassegnate da !: rosse per gli errori, ambra per gli avvisi. I caratteri invisibili e non stampabili sono mostrati con un punto · — nel file, al loro posto, non c'è nulla.
La pulizia rimuove il BOM, converte i fine riga in LF, elimina i caratteri non stampabili, sostituisce gli spazi unificatori con spazi normali e aggiunge un a capo finale. Le direttive non vengono modificate. Il file viene salvato come htaccess-clean.txt: rinominalo in .htaccess prima di caricarlo sul server.
# BEGIN WordPress
# The directives (lines) between "BEGIN WordPress" and "END WordPress" are
# dynamically generated, and should only be modified via WordPress filters.
# Any changes to the directives between these markers will be overwritten.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
È esattamente questo che WordPress scrive da solo. Metti le tue regole sopra la riga # BEGIN WordPress: tutto ciò che sta tra i marcatori viene riscritto ogni volta che salvi le impostazioni dei permalink.
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]
# add a trailing slash to /wp-admin
RewriteRule ^([_0-9a-zA-Z-]+/)?wp-admin$ $1wp-admin/ [R=301,L]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^([_0-9a-zA-Z-]+/)?(wp-(content|admin|includes).*) $2 [L]
RewriteRule ^([_0-9a-zA-Z-]+/)?(.*\.php)$ $2 [L]
RewriteRule . index.php [L]
</IfModule>
# END WordPress
Per un multisite su sottodomini il blocco è lo stesso, ma senza il prefisso ^([_0-9a-zA-Z-]+/)? nelle ultime tre regole: RewriteRule ^(wp-(content|admin|includes).*) $1 [L] e RewriteRule ^(.*\.php)$ $1 [L].
Sostituire il blocco non ripristina da solo i permalink: dopo la modifica vai in Impostazioni → Permalink e premi «Salva» — WordPress controllerà il blocco e, se serve, lo riscriverà.
Il file viene letto nel tuo browser: il suo contenuto non viene inviato da nessuna parte né memorizzato.
Perché un file e non del testo incollato
La causa più frequente di un errore 500 dopo aver modificato .htaccess non si vede affatto nel testo. È il BOM: tre byte invisibili all'inizio del file, aggiunti dal Blocco note di Windows quando si salva in UTF-8. Apache li considera parte della prima direttiva e non riesce ad analizzarla. Per questo lo strumento accetta proprio il file: solo così si possono leggere i byte e vedere il BOM, gli a capo in stile Windows e i caratteri invisibili dentro le righe. Il secondo gruppo di problemi sono le direttive che non fanno nulla ma sembrano funzionanti. mod_gzip_on è sintassi di Apache 1.3: sui server moderni viene ignorata in silenzio, mentre per anni si crede che la compressione sia attiva. Anche un blocco ExpiresByType racchiuso in un controllo su mod_headers.c invece che mod_expires.c non funzionerà — e senza un suggerimento non lo si nota. Terzo: php_value e php_flag. Funzionano solo se PHP è caricato come modulo Apache. Sugli hosting moderni con PHP-FPM una riga del genere viene ignorata oppure restituisce subito un 500. E a parte, sulla sicurezza: se nel file si trovano regole che reindirizzano i visitatori a seconda del motore di ricerca da cui arrivano, o che nascondono il redirect all'amministratore, è un segno tipico di compromissione. Ma un .htaccess pulito non cura la violazione: quasi sempre da qualche parte nei file vive uno script PHP che lo riscriverà.
