Pular para o conteúdo
>_ITDITDPlataforma de Segurança Web

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.

Publicado 2026-07-02 Atualizado 2026-07-02 9 min de leitura

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

Proteja da fundação para cima: P0 (pré-requisito) → P1 (principal fonte de incidentes) → P2 (higiene operacional).
PrioridadeControleEspecificidades (Laravel)
P0Desligar o debug de produçãoAPP_DEBUG=false / APP_ENV=production, fixado com config:cache. Não vaze internos na página de erro
P0Segredos fora da superfície pública.env, backups, chaves fora de public/, permissões 600. storage/logs não público
P0Gerenciar a APP_KEY com segurançaSustenta criptografia, cookies assinados, sessões. Injete a partir do ambiente; rotacione em caso de vazamento
P1Autorização explícitaPolicy / Gate + middleware authorize() / can, com escopo por proprietário/permissão
P1Controlar o Mass AssignmentDeclare $fillable; evite atribuir em massa $request->all(), use validated()
P1Monitorar CVEs do Composercomposer audit / osv-scanner; julgue pela versão em execução, corrija rápido
P1Cache de produçãoconfig:cache route:cache view:cache para configurações confiáveis + velocidade
P2Segurança de sessão/cookieDefina secure http_only same_site; regenere a sessão no login
P2Validação de uploadsValide tipo/tamanho, armazene fora de public/, sem permissão de execução
P2HTTPS/cabeçalhos/limitação de taxaForç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 em public/. Mantenha segredos fora da raiz do app com permissões 600 (só do proprietário).
  • Não exponha storage/ ou storage/logs/ (logs podem conter segredos ou dados pessoais). Não faça commit do .env no repositório.
  • APP_KEY sustenta 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)

1

APP_DEBUG=false / APP_ENV=production

Deixe o debug desligado em produção. Ligado, a página de exceção vaza variáveis de ambiente e informações de conexão, extraíveis via erros deliberados.
2

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.
3

Não exponha ferramentas de diagnóstico em produção

Desative ou restrinja o acesso a Telescope / Horizon / Debugbar em produção. Mantenha erros detalhados e stack traces fora da superfície pública.

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_admin atribuí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 $fillable para 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::raw por 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 @csrf nos formulários e o tratamento de token adequado para SPAs (→ o que é CSRF).
  • Cookies/sessões: defina secure (HTTPS), http_only, same_site em config/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, use TrustProxies para 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 throttle ao login, às APIs e à redefinição de senha.

8. Dependências e versões (P1)

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.

1

Segredos não são acessíveis por URL

No seu próprio domínio, acesse /.env e /storage/logs/laravel.log e confirme que eles retornam 404 (se acessíveis, corrija imediatamente e rotacione as chaves).
2

Sem exposição de debug em produção

Provoque um erro (ex. uma rota inexistente) e confirme que aparece uma página de erro genérica — sem variáveis de ambiente nem stack traces.
3

A autorização se sustenta

Em um ambiente de teste, requisite o ID de recurso de outro usuário e confirme que é negado (nos caminhos de leitura, atualização e exclusão).
4

Cookies/sessões e dependências

Confirme que o cookie de sessão carrega Secure/HttpOnly/SameSite, e que o 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

FAQ

QO que devo fazer primeiro para proteger o Laravel?
A

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?
A

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?
A

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'?
A

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?
A

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.