Cabeçalhos de Segurança para Aplicações Web: Guia Completo de Configuração
Configure cabeçalhos de segurança essenciais para a sua aplicação web de transferência de ficheiros. CSP, HSTS, X-Frame-Options e mais contra ataques web comuns.
Os cabeçalhos de segurança são campos de resposta HTTP que dizem aos browsers como restringir o comportamento de uma página. Para uma aplicação de transferência de ficheiros que faz encriptação AES-256-GCM no lado do cliente, seis cabeçalhos importam mais: Strict-Transport-Security para forçar HTTPS, Content-Security-Policy para bloquear injeção de scripts, X-Frame-Options para evitar clickjacking, Referrer-Policy para travar fugas do fragmento de URL, Permissions-Policy para desativar APIs de browser não utilizadas e Cross-Origin-Opener-Policy para isolar o contexto de navegação. Configure-os corretamente e bloqueia 80% dos ataques práticos no lado do cliente sem alterar uma linha de JavaScript.
HSTS e a lista de pré-carregamento
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload diz aos browsers para nunca mais se ligarem em HTTP simples, durante dois anos. A diretiva preload qualifica-o para a lista de pré-carregamento HSTS do Chrome (hstspreload.org), que é distribuída com o browser — mesmo o primeiro pedido ao seu domínio vai sobre HTTPS, eliminando a janela MITM inicial. A submissão é de sentido único; a remoção demora meses. Teste primeiro com max-age=300 durante alguns dias. Um serviço de transferência de ficheiros sem pré-carregamento HSTS está a um sequestro de DNS de distância de servir um formulário de upload falso.
Content Security Policy que realmente funciona
CSP é o cabeçalho mais difícil de implementar e o mais valioso. Uma política rigorosa para uma aplicação de transferência de ficheiros parece-se com: 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'. Sem scripts inline, sem eval exceto wasm, sem ligações de terceiros. Mova quaisquer gestores de eventos inline para addEventListener em ficheiros externos. O 'wasm-unsafe-eval' é necessário para libsodium.js; sem ele, o Argon2id não instancia.
Subresource Integrity em cada bundle
Se o seu JavaScript carrega de uma CDN como jsDelivr ou unpkg, adicione atributos integrity="sha384-..." em cada tag de script. O browser recusa executar scripts cujo hash não corresponda — uma CDN comprometida não consegue silenciosamente empurrar um bundle com backdoor. Para scripts auto-hospedados servidos do seu próprio domínio, SRI é menos crítico mas ainda defensável. Combine SRI com require-sri-for script style no CSP (depreciado mas o Chrome ainda o respeita) ou aplique através de pipeline de build. O HexaTransfer publica hashes por versão para que utilizadores avançados possam verificar manualmente.
X-Frame-Options e frame-ancestors
Os ataques de clickjacking carregam a sua página de upload num iframe transparente sobre outra página, enganando utilizadores para clicarem em "enviar" num ficheiro que não pretendiam partilhar. X-Frame-Options: DENY bloqueia todo o enquadramento; o substituto moderno é Content-Security-Policy: frame-ancestors 'none'. Envie ambos — browsers mais antigos respeitam apenas o cabeçalho legado, os mais recentes preferem CSP. Nunca use SAMEORIGIN para uma aplicação de transferência de ficheiros; não tem razão legítima para enquadrar o interface de upload a partir de outra página.
Referrer-Policy para travar fugas de fragmento
Os browsers eliminam fragmentos de URL (a parte #chave=... onde vive a sua chave de desencriptação) dos cabeçalhos Referer por defeito, mas a parte do caminho ainda vaza. Referrer-Policy: no-referrer bloqueia toda a informação de referência — sem cabeçalho Referer em ligações de saída, sem fugas de origem cruzada, sem impressão digital de URL por rastreadores externos. Para uma página de transferência em /d/7Kj9xQmN2vP8rBwLsE4fT#k=abc, isto evita que o slug vaze para qualquer domínio externo através do qual o utilizador clique. Defina-o em todo o sítio via cabeçalho; não confie em rel="noreferrer" por ligação.
Permissions-Policy para defesa em profundidade
Se a sua aplicação não usa a câmara, microfone, geolocalização ou API USB, negue-os explicitamente: Permissions-Policy: camera=(), microphone=(), geolocation=(), usb=(), bluetooth=(), accelerometer=(), magnetometer=(), gyroscope(), payment=(). Um XSS que escapou ao CSP ainda não consegue ligar a câmara web para gravar o rosto do utilizador. Este cabeçalho é barato de implementar, não tem impacto na UX para um fluxo de trabalho de transferência de ficheiros, e sinaliza a revisores de segurança que pensou no isolamento.
Cabeçalhos de isolamento de origem cruzada
Para acesso a temporizadores de alta resolução e SharedArrayBuffer (necessários para algumas implementações wasm de criptografia), os browsers exigem isolamento de origem cruzada via Cross-Origin-Opener-Policy: same-origin e Cross-Origin-Embedder-Policy: require-corp. Estes cabeçalhos também evitam ataques de canal lateral estilo Spectre que poderiam vazar chaves AES de origens adjacentes. A troca: recursos de terceiros incorporados (vídeos YouTube, checkout Stripe) quebram a menos que sirvam Cross-Origin-Resource-Policy: cross-origin. Para uma aplicação de transferência de ficheiros de propósito único sem embeds de terceiros, o isolamento é gratuito.
Cache-Control para páginas sensíveis
A página de confirmação de transferência pode exibir uma chave de desencriptação de curta duração ou token de sessão. Evite a cache: Cache-Control: no-store, must-revalidate e Pragma: no-cache. Não confie apenas em no-cache — isso permite revalidação contra a origem, o que significa que a cache ainda acontece. Para o bundle JavaScript da página de upload, aplica-se o oposto: max-age longo com nomes de ficheiro com hash de conteúdo (/js/main-a7b3c9.js) para que a cache de CDN funcione sem problemas de invalidação. Aplique cabeçalhos cirurgicamente por caminho.
X-Content-Type-Options e sniffing de MIME
X-Content-Type-Options: nosniff impede os browsers de adivinhar tipos MIME com base no conteúdo. Sem isto, um ficheiro .txt carregado por um atacante contendo <script> poderia ser renderizado como HTML quando servido de volta. Para um serviço de transferência que serve transferências controladas pelo utilizador, combine nosniff com Content-Disposition: attachment; filename="..." para que o browser transfira em vez de renderizar. Valide o nome do ficheiro contra travessia de caminho (../../../etc/passwd) do lado do servidor; não confie nos metadados do upload para nada além de visualização.
Monitorização e relatórios CSP
Implemente CSP em modo report-only primeiro, recolha violações num endpoint report-uri durante uma semana, corrija questões legítimas e depois aplique. Use Content-Security-Policy-Report-Only para observação, mude para Content-Security-Policy para aplicação. O endpoint de relatório recebe POSTs JSON descrevendo cada violação: URI bloqueado, diretiva violada, ficheiro de origem, número de linha. Serviços como Report URI ou um Sentry auto-hospedado recolhem estes. Reveja semanalmente — ataques genuínos aparecem como URIs bloqueados incomuns que nunca viu antes.
Classificar o seu trabalho
Execute o URL de produção no securityheaders.com e no Mozilla Observatory. Uma classificação A ou A+ não é perfeição mas é o mínimo exigido. A maioria dos concorrentes na transferência de ficheiros obtém B ou pior porque esquecem Permissions-Policy ou permitem 'unsafe-inline' no CSP. Um serviço pequeno pode facilmente superar a pontuação de cabeçalhos de segurança do WeTransfer; os cabeçalhos não custam nada a adicionar, e o rasto de auditoria para conversas de "porque é que o seu CSP não é rigoroso" com auditores SOC 2 é mais curto quando começou rigoroso.
Experimente em hexatransfer.com — gratuito, sem conta, até 10 GB.
Envie arquivos grandes com segurança e criptografia de ponta a ponta
Transfira arquivos de até 10 GB gratuitamente com criptografia de ponta a ponta. Sem necessidade de conta. Seus arquivos são criptografados no navegador antes do envio — ninguém mais pode lê-los.
Enviar um arquivo