# Relatório de Segurança 05 — Padronização de validação de uploads

- Data: 2026-06-10
- Severidade: Média (defesa em profundidade contra polyglots/webshells)
- Status: Concluído

## 1. Risco

Alguns fluxos de upload autenticados validavam o arquivo apenas por extensão/MIME do Laravel (`mimes:`, `File::types()`), sem inspecionar o conteúdo real (magic bytes). Isso deixava espaço para arquivos "polyglot" (ex.: conteúdo PHP/executável com extensão e MIME aparentemente válidos). Embora o `.htaccess` (Relatório 01) impeça a execução em `public/`, a validação de conteúdo é uma camada adicional importante.

## 2. Novo recurso no helper

`app/Helpers/FileUploadHelper.php` — método `containsDangerousContent(UploadedFile $file): bool`:

- lê os primeiros bytes do arquivo;
- rejeita executáveis (assinaturas PE `MZ`, ELF, Mach-O);
- rejeita conteúdo com `<?php` / `<?=`;
- retorna `true` quando o arquivo deve ser rejeitado.

Indicado para fluxos com whitelist ampla (Office, ZIP), onde a validação estrita de magic bytes por extensão geraria falsos negativos.

## 3. Fluxos ajustados

| Fluxo | Arquivo | Abordagem |
|------|---------|-----------|
| Atas (PDF) | `app/Http/Controllers/AtaController.php` | `FileUploadHelper::validateFile($f, ['pdf'], ['application/pdf'])`; rejeita com `ValidationException` |
| Carta de Serviços (imagens) | `app/Http/Controllers/CartaServicos/CartaServicosController.php` (store e update de categoria) | `FileUploadHelper::validateFile($f, ['jpg','jpeg','png','webp'], ALLOWED_IMAGE_MIME_TYPES)`; rejeita com erro de formulário |
| Cronogramas (anexos) | `app/Http/Services/Accounts/Cronogramas/CronogramasService.php` | `FileUploadHelper::containsDangerousContent()` antes do `Storage::put`; rejeita com `ValidationException` |
| Linhas do Tempo (anexos) | `app/Http/Services/Accounts/LinhasDoTempo/LinhasDoTempoService.php` (`assertFileAllowed`) | extensão (já existente) + `FileUploadHelper::containsDangerousContent()` |

## 4. Decisões

- PDF e imagem usam `validateFile` (whitelist estrita de extensão + MIME + magic bytes), pois o tipo esperado é único e bem definido.
- Cronogramas e Linhas do Tempo (whitelist ampla de tipos Office/ZIP) usam `containsDangerousContent`, que bloqueia o que é perigoso sem rejeitar documentos legítimos cujos magic bytes variam.

## 5. Verificação

- `php -l` sem erros em todos os arquivos alterados.
- Recomendado em homologação: enviar um PDF/imagem/documento válido em cada módulo (deve funcionar) e um arquivo renomeado contendo `<?php` (deve ser rejeitado).

## 6. Arquivos alterados

- `app/Helpers/FileUploadHelper.php`
- `app/Http/Controllers/AtaController.php`
- `app/Http/Controllers/CartaServicos/CartaServicosController.php`
- `app/Http/Services/Accounts/Cronogramas/CronogramasService.php`
- `app/Http/Services/Accounts/LinhasDoTempo/LinhasDoTempoService.php`
