Por framework
Segurança do Laravel — uma referência de hardening para produção
Referência de hardening do Laravel em produção: checklist por prioridade, os padrões perigosos e orientação por área — de segredos e config a autorização e CVEs de dependências, mais um checklist de autoverificação. Defensivo, sem passos de ataque.
Para: qualquer pessoa que opere o Laravel em produção. Sem passos de ataque aqui — esta é uma referência de trabalho para hardening: um checklist por prioridade, os padrões perigosos, orientação por área e autoverificação. Para o panorama entre frameworks, veja o hub de segurança por framework.
Checklist de hardening por prioridade
Faça esta tabela de cima para baixo. P0 é pré-requisito para o resto, P1 é a fonte mais frequente de incidentes, P2 é higiene operacional contínua.
P0 ── Pré-requisito (faça primeiro)
Debug desligado em produção / segredos fora da superfície pública com permissões 600 / gerenciar a APP_KEY
P1 ── Principal fonte de incidentes
Autorização (Policy/Gate) / controle de Mass Assignment / CVEs de dependências / cache de produção
P2 ── Higiene operacional
Sessões/CSRF/cookies / validação de uploads / HTTPS, cabeçalhos, limitação de taxa
| Prioridade | Controle | Especificidades (Laravel) |
|---|---|---|
| P0 | Desligar o debug de produção | APP_DEBUG=false / APP_ENV=production, fixado com config:cache. Não vaze internos na página de erro |
| P0 | Segredos fora da superfície pública | .env, backups, chaves fora de public/, permissões 600. storage/logs não público |
| P0 | Gerenciar a APP_KEY com segurança | Sustenta criptografia, cookies assinados, sessões. Injete a partir do ambiente; rotacione em caso de vazamento |
| P1 | Autorização explícita | Policy / Gate + middleware authorize() / can, com escopo por proprietário/permissão |
| P1 | Controlar o Mass Assignment | Declare $fillable; evite atribuir em massa $request->all(), use validated() |
| P1 | Monitorar CVEs do Composer | composer audit / osv-scanner; julgue pela versão em execução, corrija rápido |
| P1 | Cache de produção | config:cache route:cache view:cache para configurações confiáveis + velocidade |
| P2 | Segurança de sessão/cookie | Defina secure http_only same_site; regenere a sessão no login |
| P2 | Validação de uploads | Valide tipo/tamanho, armazene fora de public/, sem permissão de execução |
| P2 | HTTPS/cabeçalhos/limitação de taxa | Forçar HTTPS, HSTS, throttle no login/API |
1. Segredos e APP_KEY (P0)
O Laravel mantém o .env fora da raiz do documento (na raiz do projeto) por padrão. Os incidentes vêm em sua maioria de colocar segredos onde eles não deveriam estar.
- Nunca coloque
.env, dumps de banco, backups ou arquivos de chave empublic/. Mantenha segredos fora da raiz do app com permissões 600 (só do proprietário). - Não exponha
storage/oustorage/logs/(logs podem conter segredos ou dados pessoais). Não faça commit do.envno repositório. APP_KEYsustenta a criptografia, as URLs assinadas, os cookies criptografados e as sessões. Injete-a a partir do ambiente e rotacione prontamente se vazar (note que isso invalida dados/sessões criptografados existentes).
Para o princípio geral, veja mantenha segredos fora dos diretórios públicos; para um caso real de exposição completa, veja uma exposição completa de .env.
2. Config de produção: DEBUG, ambiente, cache (P0)
APP_DEBUG=false / APP_ENV=production
Fixe a config com cache
php artisan config:cache (+ route:cache view:cache) faz as configurações se aplicarem de forma confiável e acelera o app. Nota: depois de config:cache, env() fora de config/ retorna null, então referencie os valores via config('...') no app.Não exponha ferramentas de diagnóstico em produção
3. Autorização: Broken Access Control (P1 — a principal fonte)
O incidente de produção mais comum é "autenticado, mas não autorizado". Poder fazer login não significa ter permissão para executar a ação.
Comum (perigoso)
- sem autorização — "logado = pode ver/atualizar"
- o route-model binding busca o ID de outro usuário
Model::create($request->all())aceita todos os campos- um campo de privilégio como
is_adminatribuído a partir de entrada do usuário
Correto
- Policy / Gate + middleware
authorize()/can, dando escopo por proprietário/permissão toda vez - leituras também com escopo de proprietário (ex.
where('user_id', $me)) - limite a entrada com
$request->validated()(FormRequest) - declare
$fillablepara bloquear o Mass Assignment
Veja o que é IDOR. O ponto-chave é uma verificação de propriedade em cada caminho de leitura/atualização/exclusão.
4. Injeção e saída
O Eloquent/query builder do Laravel faz o binding de valores com placeholders, e o Blade escapa a saída por padrão. A regra é não desativar essa segurança por conta própria.
- SQL: não misture entrada do usuário em
whereRaw/DB::rawpor concatenação de strings. Mesmo quando SQL bruto for necessário, use bindings (→ o que é injeção de SQL). - XSS: o
{{ }}do Blade escapa;{!! !!}é saída bruta. Não passe entrada do usuário para{!! !!}. Se precisar emitir HTML, só depois de sanitizar (→ o que é XSS). - Validação: valide tipo/intervalo/valores permitidos com FormRequest /
validate()antes de usar.
5. Sessões, CSRF, cookies (P2)
- CSRF: não desative globalmente a proteção CSRF do middleware web. Use
@csrfnos formulários e o tratamento de token adequado para SPAs (→ o que é CSRF). - Cookies/sessões: defina
secure(HTTPS),http_only,same_siteemconfig/session.php. Regenere a sessão no login para prevenir fixation (a auth do Laravel regenera). - Força bruta: aplique
throttle/ limites de tentativas de login ao login.
6. Uploads de arquivos e arquivos públicos (P2)
- Valide tipo mime, extensão e tamanho, e não confie no nome de arquivo fornecido pelo cliente.
- Armazene fora de
public/(ex.storage/) com nenhuma permissão de execução. Sirva apenas o que precisa ser público, por um caminho controlado. - Coloque autorização na entrega também, para que links diretos sequenciais não possam buscar o arquivo de outro usuário.
7. HTTPS, cabeçalhos de segurança, limitação de taxa (P2)
- Force HTTPS (
URL::forceScheme('https'), etc.) + HSTS. Atrás de um balanceador de carga, useTrustProxiespara que o esquema seja detectado corretamente. - Cabeçalhos de segurança (X-Content-Type-Options, etc.; desenhe a CSP em torno da sua configuração de assets). Verifique seu próprio site com o verificador de cabeçalhos de segurança.
- Limitação de taxa: aplique
throttleao login, às APIs e à redefinição de senha.
8. Dependências e versões (P1)
- Monitore CVEs de dependências do Composer com
composer auditou osv-scanner, julgue pela versão em execução e corrija rápido (→ monitorando CVEs de dependências · o manual de resposta a vulnerabilidades). - Mantenha Laravel e PHP em versões suportadas. Não deixe versões EOL no lugar (falhas insanáveis se acumulam).
Verifique: seu Laravel está realmente protegido?
Construir não é o fim — só está pronto depois de verificar. Estas são autoverificações defensivas contra o seu próprio site/ambiente.
Segredos não são acessíveis por URL
/.env e /storage/logs/laravel.log e confirme que eles retornam 404 (se acessíveis, corrija imediatamente e rotacione as chaves).Sem exposição de debug em produção
A autorização se sustenta
Cookies/sessões e dependências
composer audit está limpo.A visão deste site: mesmo com padrões fortes, autorização e dependências são responsabilidade sua
O Laravel tem muitos bons padrões, mas a autorização — quem pode fazer o quê — e a atualidade das dependências são específicas do app e da operação, então nenhum framework consegue protegê-las automaticamente. Os incidentes que continuamos vendo são menos ataques elaborados do que padrões de configuração/operação: "autenticado, mas sem verificação de propriedade", "debug aberto em produção", "um segredo exposto". Então o centro de gravidade é trabalhar a tabela acima de cima para baixo e fazer o trabalho sem glamour — dar escopo a cada leitura/atualização por proprietário e monitorar as dependências em busca de CVEs.
Leia a seguir
- Hub: segurança por framework · segurança do Next.js
- Segredos: mantenha segredos fora dos diretórios públicos · Caso: uma exposição completa de .env
- Autorização / prática: o que é IDOR · o manual de resposta a vulnerabilidades · monitorando CVEs de dependências
- Glossário: injeção de SQL · XSS · CSRF
FAQ
QO que devo fazer primeiro para proteger o Laravel?
Os três itens P0: (1) garantir APP_DEBUG=false em produção e fixar a config com config:cache; (2) manter .env e arquivos de segredos fora do diretório público com permissões restritas; (3) gerenciar a APP_KEY com segurança (ela sustenta a criptografia, os cookies assinados e as sessões, então rotacione em caso de vazamento). Esses são pré-requisitos para todo o resto. Em seguida, avance para autorização (Policy/Gate) e monitoramento de CVEs de dependências do Composer.
QO que é perigoso em publicar com APP_DEBUG=true?
Com o debug ligado, a página de exceção pode mostrar não só um stack trace, mas internos como valores de config, variáveis de ambiente e informações de conexão. Um atacante pode provocar erros de propósito para extraí-los. Em produção, defina APP_DEBUG=false e APP_ENV=production e fixe isso com config:cache. Também não exponha ferramentas de diagnóstico como Telescope ou Debugbar em produção.
QPor que env() retorna null depois de config:cache?
config:cache compila sua config em um único arquivo por desempenho, e depois disso env() chamado fora dos arquivos de config retorna null (só o .env do momento do cache é lido). A correção é usar env() apenas dentro de config/ e referenciar os valores no app via config('...'). Em produção, cachear config/route/view é a norma — faz as configurações se aplicarem de forma confiável e acelera o app.
QComo evito o 'logado significa permitido'?
Autenticação (login) e autorização (se a ação é permitida) são coisas diferentes. No Laravel, implemente Policy/Gate e use authorize() ou o middleware can para dar escopo a cada leitura/atualização/exclusão por proprietário ou permissão. Controle também o Mass Assignment declarando $fillable e evite atribuir em massa $request->all(). Sem isso, trocar um ID na URL alcança os dados de outro usuário (IDOR).
QComo gerencio vulnerabilidades de dependências do Composer?
Monitore CVEs conhecidos de forma automatizada com composer audit ou osv-scanner, julgue pela versão em execução e corrija rápido (decida com base no que está de fato instalado, não na declaração do composer.json). Mantenha também Laravel e PHP em versões suportadas e não deixe versões EOL no lugar. A atualidade das dependências é um fator mais realista nos incidentes do que ataques elaborados.