# Security header per i siti web: impostare correttamente gli header di sicurezza

> Impostare i security header per i siti web: CSP, HSTS, X-Content-Type-Options e altro con esempi per Nginx e Apache, più verifica ed errori tipici.

Fonte: https://phpsos.de/it/ratgeber/sicherheits-header/  
Stato: 25/10/2026  
Fornitore: PHP SOS, Assistenza di emergenza PHP e sicurezza dei server. Assistenza immediata su WhatsApp: https://wa.me/491736494914?text=Buongiorno%20PHP%20SOS%2C%20abbiamo%20bisogno%20di%20aiuto%20con%20il%20nostro%20server%20PHP.%20Azienda%3A%20%E2%80%A6%20Sito%20web%3A%20%E2%80%A6

**In breve:** i security header sono istruzioni del server web al browser che proteggono i visitatori da attacchi come cross-site scripting, clickjacking e connessioni non cifrate. I più importanti sono HSTS, Content Security Policy, X-Content-Type-Options, protezione dai frame esterni, Referrer-Policy e Permissions-Policy. Sono un hardening sensato, ma non sostituiscono gli aggiornamenti sul server.

## Che cosa fanno i security header e che cosa no

A ogni richiesta di pagina il server web invia, oltre al contenuto, anche degli header. Alcuni controllano funzioni di sicurezza del browser. Con essi si può stabilire, ad esempio, che una pagina venga caricata solo tramite HTTPS o che il browser non esegua script di domini esterni.

Per i gestori è importante l'inquadramento: gli header proteggono in primo luogo i visitatori, ad esempio dalla sottrazione di sessioni o da moduli manipolati. Non chiudono vulnerabilità sul server. Una debolezza in PHP, nel CMS o in un'estensione resta, per quanto bene siano impostati gli header. In combinazione con un codice pulito limitano però in modo sensibile le conseguenze di molti errori.

## I security header più importanti in sintesi

| Header | Scopo | Raccomandazione come punto di partenza |
|---|---|---|
| Strict-Transport-Security (HSTS) | impone HTTPS per le richieste future | `max-age=31536000; includeSubDomains` |
| Content-Security-Policy (CSP) | stabilisce le fonti consentite per script, immagini, frame | individuale, prima come report-only |
| X-Content-Type-Options | impedisce al browser di indovinare i tipi di file | `nosniff` |
| X-Frame-Options ovvero CSP frame-ancestors | impedisce l'incorporamento in siti esterni (clickjacking) | `SAMEORIGIN` ovvero `frame-ancestors 'self'` |
| Referrer-Policy | limita quale indirizzo viene trasmesso ad altri siti | `strict-origin-when-cross-origin` |
| Permissions-Policy | disattiva funzioni del browser come fotocamera o posizione | consentire solo le funzioni necessarie |

HSTS dovrebbe essere impostato solo quando tutti i sottodomini sono raggiungibili in modo affidabile tramite HTTPS. Il browser ricorda l'istruzione per il tempo indicato; un errore non si può allora annullare subito. Se necessario inizi con una durata breve e la aumenti dopo test riusciti. L'opzione aggiuntiva `preload` inserisce il dominio in modo permanente negli elenchi dei produttori di browser e andrebbe impostata solo dopo un'attenta verifica.

Gli header inoltre non sono l'unico punto in cui il browser offre protezione. I cookie dovrebbero avere gli attributi `Secure`, `HttpOnly` e `SameSite`, in modo che le sessioni non vengano sottratte tramite connessioni non cifrate o script. Come impostarlo in PHP è descritto nella guida sulle sessioni.

## Impostare i security header in Nginx

In Nginx gli header vanno nel blocco `server` del rispettivo sito. L'aggiunta `always` fa sì che vengano inviati anche con le pagine di errore.

```nginx
server {
    # ...
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;
    add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
    add_header Content-Security-Policy-Report-Only "default-src 'self'; img-src 'self' data:; object-src 'none'; base-uri 'self'; frame-ancestors 'self'; form-action 'self'" always;

    server_tokens off;
}
```

Una particolarità di Nginx: se un blocco `location` imposta proprie istruzioni `add_header`, gli header del blocco `server` lì non vengono ereditati. Controlli quindi anche le sottopagine e i file statici. Ulteriore hardening per questa combinazione è descritto in [Mettere in sicurezza Nginx con PHP-FPM](https://phpsos.de/it/server/nginx-php-fpm/).

## Impostare i security header in Apache

Con Apache serve il modulo `mod_headers`. Le istruzioni vanno nel VirtualHost oppure, se non c'è accesso, nel `.htaccess`.

```apache
<IfModule mod_headers.c>
    Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
    Header always set X-Content-Type-Options "nosniff"
    Header always set X-Frame-Options "SAMEORIGIN"
    Header always set Referrer-Policy "strict-origin-when-cross-origin"
    Header always set Permissions-Policy "camera=(), microphone=(), geolocation=()"
    Header always set Content-Security-Policy-Report-Only "default-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'"
</IfModule>

ServerTokens Prod
ServerSignature Off
```

`ServerTokens` e `ServerSignature` vanno nella configurazione principale. Impediscono al server di indicare la propria versione esatta nelle risposte e nelle pagine di errore. Nel `php.ini` si ottiene lo stesso per PHP con `expose_php = Off`.

## Introdurre gradualmente la Content Security Policy

La Content Security Policy è l'header più efficace, ma anche il più impegnativo. Stabilisce da quali fonti possono essere caricati script, fogli di stile, immagini, caratteri e frame. Se uno script introdotto di nascosto viene ricaricato da un dominio esterno, il browser lo blocca.

I siti moderni integrano spesso strumenti di analisi, fornitori di pagamento, servizi di mappe o video. Una policy troppo severa mette allora fuori uso delle funzioni. Proceda quindi per gradi:

- Iniziare prima con `Content-Security-Policy-Report-Only`. Il browser segnala le violazioni nella console per sviluppatori o a un indirizzo di raccolta, ma non blocca nulla.
- Rilevare tutte le fonti necessarie e autorizzarle in modo mirato, invece di usare segnaposto generici.
- Spostare gradualmente gli script inline in file oppure fornirli di nonce, in modo da poter rinunciare a `'unsafe-inline'`.
- Passare a `Content-Security-Policy` solo dopo una fase di test senza segnalazioni inattese.

> **Consiglio:**
> La CSP integra un escaping pulito nel codice, ma non lo sostituisce. Come mettere in sicurezza correttamente gli output in PHP è spiegato nella guida [Prevenire il cross-site scripting in PHP](https://phpsos.de/it/ratgeber/xss-php/).

## Verificare gli header ed evitare gli errori tipici

Dopo ogni modifica dovrebbe verificare che gli header arrivino davvero. Si può fare senza strumenti aggiuntivi con `curl`:

```bash
# Testare la configurazione e ricaricarla
nginx -t && systemctl reload nginx

# Mostrare gli header della home page e di un file statico
curl -sI https://www.example.de/ | grep -iE 'strict|content-security|x-content|x-frame|referrer|permissions|server'
curl -sI https://www.example.de/favicon.ico | grep -iE 'strict|x-content'
```

Errori tipici sono gli header impostati due volte, quando server web e applicazione inviano gli stessi header, una CDN a monte che rimuove o sovrascrive gli header e header che compaiono solo sulla home page ma non nei reindirizzamenti o nelle pagine di errore. Controlli inoltre, dopo aggiornamenti del CMS o di estensioni di sicurezza, se gli header siano cambiati.

Stabilisca quindi un unico punto in cui gli header vengono gestiti, meglio il server web o il servizio a monte. Molte estensioni dei CMS offrono anch'esse impostazioni per gli header di sicurezza. È comodo, ma porta facilmente a indicazioni doppie o contraddittorie se anche il server imposta degli header. Per singoli test sono adatti anche gli strumenti per sviluppatori del browser: nella scheda Rete vede per ogni richiesta gli header di risposta e la console mostra le violazioni della Content Security Policy.

## Come aiuta concretamente PHP SOS?

- Verifichiamo gli header attuali di tutti i Suoi siti, anche dietro CDN e proxy, e mostriamo lacune e contraddizioni.
- Impostiamo gli header in modo centralizzato nel server web nell'ambito dell'[hardening del server](https://phpsos.de/it/leistungen/server-haertung/) e testiamo home page, sottopagine e pagine di errore.
- Introduciamo la Content Security Policy in modalità report-only, analizziamo le segnalazioni e la attiviamo dopo accordo.
- Dove le modifiche al codice non sono subito possibili, integriamo la protezione con [regole WAF e virtual patching](https://phpsos.de/it/leistungen/waf-virtuelles-patching/).


## Domande frequenti

**Che cosa sono i security header?**  
I security header sono informazioni aggiuntive nella risposta del server web. Dicono al browser, ad esempio, di caricare la pagina solo tramite HTTPS, di non eseguire script esterni o di non mostrare la pagina in frame esterni. Proteggono soprattutto i visitatori.

**I security header proteggono da PHP2Shell?**  
No. PHP2Shell è una vulnerabilità di PHP sul server, gli header agiscono nel browser del visitatore. Contro PHP2Shell aiuta l'aggiornamento a una versione corretta di PHP e il riavvio di tutti i worker. Gli header sono un hardening complementare per altri tipi di attacco.

**Una Content Security Policy può rompere il mio sito?**  
Sì, una policy troppo severa blocca script, caratteri o contenuti incorporati necessari. Per questo la si introduce prima in modalità report-only, si analizzano le segnalazioni e solo dopo si passa all'applicazione.

**X-XSS-Protection ha ancora senso?**  
No. I browser attuali non valutano più questo header e la raccomandazione è di ometterlo o di impostarlo a 0. La protezione dal cross-site scripting la offrono un escaping pulito nel codice e una Content Security Policy.

## Fonti

- [OWASP Cheat Sheet Series (HTTP Headers)](https://cheatsheetseries.owasp.org/)
- [OWASP Top 10](https://owasp.org/www-project-top-ten/)
- [BSI: raccomandazioni per i server web](https://www.bsi.bund.de/)
