# Relatório de Segurança 01 — Hardening Emergencial (Apache)

- Data: 2026-06-10
- Incidente: queda da página do Boletim Oficial / comprometimento de arquivos em produção
- Ambiente: Apache (com `.htaccess` ativo)
- Severidade do incidente: Crítica
- Status: Concluído

## 1. Resumo do incidente

Em produção (Linux/Apache) foram identificados:

- `public/index.php` modificado (backdoor na porta de entrada do Laravel);
- diretório não rastreado `public/boletim-oficial/` (provável webshell/defacement servido como conteúdo estático).

A remoção emergencial já havia sido feita no servidor com:

```bash
git reset --hard origin/producao
git clean -fd
```

## 2. Reconstrução do vetor

```
Conta admin/permissão comprometida
  -> Página HTML salva (campo "code")
  -> Blade::render() compila o conteúdo como PHP/Blade  => RCE
  -> escrita em public/index.php (backdoor) e criação de public/boletim-oficial/
  -> Apache serve o diretório físico (RewriteCond %{REQUEST_FILENAME} !-d)
     em vez de encaminhar a URL ao Laravel  => "directory shadowing"
  -> página /boletim-oficial cai
```

Fatores que ampliaram a exposição:

1. `Blade::render($html->code)` em páginas HTML editáveis = execução de PHP arbitrário (RCE).
2. `public/.htaccess` bloqueava apenas `.php` (`RewriteRule ^.+\.php$`), deixando passar `.phtml`, `.phar`, `.pht`, `.php3-8`, `.phps`, `.inc`.
3. "Directory shadowing": diretório físico com o mesmo nome de uma rota sobrepõe a rota do Laravel.

## 3. Medidas aplicadas (nesta entrega)

### 3.1 Eliminação do RCE das Páginas HTML (P0)

Substituída a compilação Blade por saída de HTML cru (sem executar PHP/diretivas). As views já imprimem com `{!! ... !!}`.

- `app/Http/Controllers/PageController.php`
  - `details()`: `Blade::render($htmlPage->code ?? '')` -> `$htmlPage->code ?? ''` (removido try/catch que só existia por causa da compilação).
  - `paginasHTML()`: `Blade::render($html->code ?? '')` -> `$html->code ?? ''`.
  - Removido `use Illuminate\Support\Facades\Blade;` (ocioso).
- `app/Http/Controllers/HtmlController.php`
  - `preview()`: `Blade::render($data['code'] ?? '')` -> `$data['code'] ?? ''` (removido try/catch).
  - Removido `use Illuminate\Support\Facades\Blade;` (ocioso).

Impacto de comportamento (risco aceito): páginas que usavam diretivas Blade (`@php`, `@include`, `{{ route() }}`) deixam de processá-las e passam a exibir o conteúdo como HTML literal. Necessária verificação das páginas HTML em uso.

### 3.2 Hardening do `public/.htaccess` (P0)

- Regra de rewrite ampliada para bloquear todas as extensões executáveis:

```apache
RewriteRule ^index\.php$ - [L]
RewriteRule \.(?i:php\d?|phtml|phps|phar|pht|inc|cgi|pl|py|sh)$ - [F,L]
```

- Defesa adicional independente do `mod_rewrite` (autorização por arquivo), liberando apenas o front controller:

```apache
<FilesMatch "\.(?i:php\d?|phtml|phps|phar|pht|inc|cgi|pl|py|sh)$">
    Require all denied
</FilesMatch>
<Files "index.php">
    Require all granted
</Files>
```

O `.htaccess` da raiz `public/` é herdado pelos subdiretórios, inclusive o symlink `public/storage` (uploads), protegendo também os arquivos enviados.

### 3.3 Remoção de rota pública quebrada

- `routes/web.php`: removida a rota `GET usuarios_dados -> AccountController@usuarios_dados` (método inexistente, sem autenticação) e o import órfão de `AccountController`.

## 4. Verificação realizada

- `php -l` sem erros em `PageController.php`, `HtmlController.php`, `routes/web.php`.
- `php artisan route:list`: rota `usuarios_dados` removida; `boletim-oficial`, `servicos/{slug}` (paginasHTML) e `secretarias/{slug}` (details) permanecem registradas.
- `$htmlPageContent` inicializada como `''` antes do uso em `details()`; views imprimem o HTML cru.

## 5. Pendências operacionais (servidor de produção — time de infra)

- Permissões: usuário dono dos arquivos diferente do usuário do Apache/PHP-FPM; `public/` e `index.php` somente leitura para o PHP-FPM; escrita apenas em `storage/` e `bootstrap/cache/`.
- Varredura de artefatos remanescentes:
  ```bash
  find public -type f \( -name '*.ph*' -o -name '*.pht' -o -name '*.phar' -o -name '*.inc' \) ! -name 'index.php'
  ```
  e conferência do hash de `public/index.php` contra o Git.
- Revisar logs do Apache (POSTs incomuns, acessos a `/boletim-oficial/`, criação de páginas HTML), SSH e painel.
- Rotacionar credenciais: admin, SSH, banco, `.env`.
- Monitoramento de integridade em `public/` (AIDE/inotify) ou checagem de hash no deploy.
- Teste de `.htaccess` em ambiente Apache: requisitar `teste.phtml`/`teste.php` em `public/` e em `public/storage/` e confirmar **403**.

## 6. Arquivos alterados

- `app/Http/Controllers/PageController.php`
- `app/Http/Controllers/HtmlController.php`
- `public/.htaccess`
- `routes/web.php`
