Vai al contenuto
HexaTransfer
Torna al blog
Crittografia e sicurezza

Header di sicurezza per applicazioni web: guida alla configurazione

Configura gli header di sicurezza essenziali per la tua app di trasferimento. CSP, HSTS, X-Frame-Options contro attacchi web comuni.

Gli header di sicurezza sono campi di risposta HTTP che dicono ai browser come limitare il comportamento di una pagina. Per un'app di trasferimento file che esegue crittografia AES-256-GCM lato client, sei header contano di più: Strict-Transport-Security per forzare HTTPS, Content-Security-Policy per bloccare l'iniezione di script, X-Frame-Options per prevenire il clickjacking, Referrer-Policy per fermare le perdite di frammenti URL, Permissions-Policy per disabilitare le API del browser non utilizzate, e Cross-Origin-Opener-Policy per isolare il contesto di navigazione. Configurati correttamente, bloccano l'80% degli attacchi pratici lato client senza cambiare una riga di JavaScript.

HSTS e la preload list

Strict-Transport-Security: max-age=63072000; includeSubDomains; preload dice ai browser di non connettersi mai più tramite HTTP semplice, per due anni. La direttiva preload ti qualifica per la HSTS preload list di Chrome (hstspreload.org), distribuita con il browser — anche la prima richiesta al tuo dominio va su HTTPS, eliminando la finestra iniziale di MITM. L'iscrizione è irreversibile; la rimozione richiede mesi. Testa con max-age=300 per qualche giorno prima. Un servizio di trasferimento file senza HSTS preload è a un dirottamento DNS di distanza dal servire un modulo di upload falso.

Content Security Policy che funziona davvero

CSP è l'header più difficile da implementare e il più prezioso. Una policy rigorosa per un'app di trasferimento file ha questo aspetto: default-src 'none'; script-src 'self' 'wasm-unsafe-eval'; connect-src 'self' https://upload.hexatransfer.com; style-src 'self'; img-src 'self' data:; font-src 'self'; frame-ancestors 'none'; base-uri 'none'; form-action 'self'. Nessuno script inline, nessun eval eccetto wasm, nessuna connessione di terze parti. Sposta qualsiasi gestore di eventi inline in addEventListener in file esterni. Il 'wasm-unsafe-eval' è necessario per libsodium.js; senza di esso, Argon2id non si instanzia.

Subresource Integrity su ogni bundle

Se il tuo JavaScript si carica da una CDN come jsDelivr o unpkg, aggiungi attributi integrity="sha384-..." su ogni tag script. Il browser rifiuta di eseguire script il cui hash non corrisponde — una CDN compromessa non può silenziosamente distribuire un bundle con backdoor. Per gli script auto-ospitati serviti dal tuo dominio, SRI è meno critico ma comunque difendibile. Abbina SRI a require-sri-for script style di CSP (deprecato ma Chrome lo rispetta ancora) o applica tramite pipeline di build. HexaTransfer pubblica hash per ogni release così gli utenti attenti possono verificare manualmente.

X-Frame-Options e frame-ancestors

Gli attacchi di clickjacking caricano la tua pagina di upload in un iframe trasparente sopra una pagina diversa, inducendo gli utenti a cliccare "invia" su un file che non intendevano condividere. X-Frame-Options: DENY blocca tutto il framing; il sostituto moderno è Content-Security-Policy: frame-ancestors 'none'. Distribuisci entrambi — i browser più vecchi rispettano solo l'header legacy, quelli più recenti preferiscono CSP. Non usare mai SAMEORIGIN per un'app di trasferimento file; non hai alcun motivo legittimo per incorniciare l'UI di upload da un'altra pagina.

Referrer-Policy per fermare le perdite di frammenti

I browser rimuovono i frammenti URL (la parte #key=... dove risiede la tua chiave di decrittografia) dalle intestazioni Referer per impostazione predefinita, ma la parte del path viene ancora trasmessa. Referrer-Policy: no-referrer blocca tutte le informazioni referrer — nessuna intestazione Referer sui link in uscita, nessuna perdita cross-origin, nessun fingerprinting URL da tracker esterni. Per una pagina di download su /d/7Kj9xQmN2vP8rBwLsE4fT#k=abc, questo impedisce allo slug di trapelare verso qualsiasi dominio esterno su cui l'utente clicca. Impostala a livello di sito tramite header; non fare affidamento sul rel="noreferrer" per singolo link.

Permissions-Policy per la difesa in profondità

Se la tua app non usa la fotocamera, il microfono, la geolocalizzazione o l'API USB, negali esplicitamente: Permissions-Policy: camera=(), microphone=(), geolocation=(), usb=(), bluetooth=(), accelerometer=(), magnetometer=(), gyroscope(), payment=(). Un XSS che ha superato CSP non riesce comunque ad accendere la webcam per registrare il volto dell'utente. Questo header è economico da implementare, non ha impatto sull'UX per un flusso di trasferimento file, e segnala ai revisori della sicurezza che hai pensato al sandboxing.

Header per l'isolamento cross-origin

Per accedere a timer ad alta risoluzione e SharedArrayBuffer (necessari per alcune implementazioni wasm di crittografia), i browser richiedono l'isolamento cross-origin tramite Cross-Origin-Opener-Policy: same-origin e Cross-Origin-Embedder-Policy: require-corp. Questi header prevengono anche attacchi side-channel di tipo Spectre che potrebbero far trapelare le chiavi AES da origini adiacenti. Il compromesso: le risorse di terze parti incorporate (video YouTube, checkout Stripe) si rompono a meno che non servano Cross-Origin-Resource-Policy: cross-origin. Per un'app di trasferimento file a scopo unico senza embed di terze parti, l'isolamento è gratuito.

Cache-Control per le pagine sensibili

La pagina di conferma del download potrebbe mostrare una chiave di decrittografia a breve durata o un token di sessione. Previeni il caching: Cache-Control: no-store, must-revalidate e Pragma: no-cache. Non fare affidamento solo su no-cache — quello consente la rivalidazione con l'origine, il che significa che il caching avviene comunque. Per il bundle JavaScript della pagina di upload, vale l'opposto: max-age lungo con nomi di file con hash del contenuto (/js/main-a7b3c9.js) così il caching CDN funziona senza problemi di invalidazione. Applica gli header in modo chirurgico per percorso.

X-Content-Type-Options e il MIME sniffing

X-Content-Type-Options: nosniff impedisce ai browser di indovinare i tipi MIME in base al contenuto. Senza di esso, un file .txt caricato da un attaccante contenente <script> potrebbe essere renderizzato come HTML quando viene servito. Per un servizio di trasferimento che serve download controllati dall'utente, combina nosniff con Content-Disposition: attachment; filename="..." così il browser scarica invece di renderizzare. Valida il nome del file contro il path traversal (../../../etc/passwd) lato server; non fidarti dei metadati dell'upload per nulla tranne che per la visualizzazione.

Monitoraggio e report CSP

Distribuisci CSP in modalità report-only prima, raccogli le violazioni in un endpoint report-uri per una settimana, risolvi i problemi legittimi, poi applica. Usa Content-Security-Policy-Report-Only per l'osservazione, passa a Content-Security-Policy per l'applicazione. L'endpoint di report riceve POST JSON che descrivono ogni violazione: URI bloccato, direttiva violata, file sorgente, numero di riga. Servizi come Report URI o un sentry auto-ospitato li raccolgono. Rivedi settimanalmente — gli attacchi reali appaiono come URI bloccati insoliti che non hai mai visto prima.

Valutare il tuo lavoro

Esegui il tuo URL di produzione attraverso securityheaders.com e Mozilla Observatory. Un voto A o A+ non è la perfezione ma è il minimo accettabile. La maggior parte dei concorrenti nel trasferimento file ottiene B o peggio perché dimenticano Permissions-Policy o consentono 'unsafe-inline' in CSP. Un servizio piccolo può facilmente battere il punteggio degli header di sicurezza di WeTransfer; gli header non costano nulla da aggiungere, e il percorso di audit per le conversazioni "perché il tuo CSP non è rigoroso" con gli auditor SOC 2 è più breve quando hai iniziato in modo rigoroso.

Provalo su hexatransfer.com — gratis, senza registrazione, fino a 10 GB.

Invia file di grandi dimensioni in modo sicuro con crittografia end-to-end

Trasferisci file fino a 10 GB gratuitamente con crittografia end-to-end. Nessun account necessario. I tuoi file vengono crittografati nel browser prima del caricamento — nessun altro può leggerli.

Invia un file