# Relatório de Segurança 07 — Avaliação do vhost Apache (produção)

- Data: 2026-06-10
- Escopo: `sites-enabled/portal-le-ssl.conf` (vhost :443)
- Status: Avaliação / recomendações (config vive no servidor, fora do repositório)

## 1. Achado decisivo: `AllowOverride None`

Os dois blocos `<Directory>` usam `AllowOverride None`, então **o Apache ignora os arquivos `.htaccess`**.

Consequências:

- O `public/.htaccess` endurecido no Relatório 01 **não tem efeito em produção**; toda a proteção vem do vhost. (Mantê-lo no repositório ainda é útil como defesa em profundidade para ambientes com `AllowOverride On`, ex.: local/Laragon.)
- As regras anti-webshell precisam estar corretas **no vhost**.

## 2. Pontos positivos

- `DocumentRoot` em `public/` (não expõe a raiz do Laravel).
- `<FilesMatch>` negando `.php`/`.phtml`/`.php[0-9]` com exceção apenas para `index.php`, na ordem correta (o `<Files "index.php">` vem depois e sobrepõe).
- `Alias /storage` -> `storage/app/public` com o mesmo bloqueio de `.php`.
- `Options -ExecCGI -Indexes` (sem CGI, sem listagem de diretório).
- `allow_url_fopen off` (mitiga RFI via wrappers).
- Headers: `X-Content-Type-Options`, `X-Frame-Options`, `Referrer-Policy`.

## 3. Lacunas e riscos

### 3.1 (Alta) Regex do `<FilesMatch>` com as mesmas brechas do incidente
`\.(php|phtml|php[0-9])$` não cobre `.phar`, `.pht`, `.phps`, `.inc`, `.phtm`, e é **case-sensitive** (no Linux, `shell.PHP` pode escapar). Corrigir nos dois blocos:

```apache
<FilesMatch "(?i)\.(php[0-9]?|phtml|phtm|phps|phar|pht|inc|cgi|pl|py|sh)$">
    Require all denied
</FilesMatch>
```

(no bloco `public`, manter o `<Files "index.php">` logo após).

### 3.2 (Alta) Confirmar SAPI (mod_php x PHP-FPM)
As diretivas estão dentro de `<IfModule mod_php.c>`. Se o servidor usa **PHP-FPM**, elas são **silenciosamente ignoradas** — incluindo `allow_url_fopen off` e os limites de upload. Verificar:

```bash
apachectl -M | grep -E 'php|proxy_fcgi'
```

Se for FPM, mover as diretivas para o `php.ini`/pool do FPM.

### 3.3 (Alta) Permissões de `public/` (causa-raiz do directory shadowing)
Com `Options -Indexes`, um diretório `public/boletim-oficial/` criado pelo atacante retorna 403 (não lista), mas ainda sobrepõe a rota; um `index.html` plantado ali seria servido. A barreira real é o processo web **não poder escrever em `public/`**:

- dono dos arquivos != usuário do Apache/FPM;
- `public/` somente leitura para o processo web;
- escrita apenas em `storage/` e `bootstrap/cache/`.

### 3.4 (Média) Falta HSTS

```apache
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
```

(`; preload` apenas se for submeter à preload list).

### 3.5 (Média) Verificar vhost da porta 80
Garantir que o `:80` apenas **redireciona** para HTTPS e não serve o mesmo `DocumentRoot` sem o `<FilesMatch>` (evita bypass por HTTP).

### 3.6 (Média) Hardening de PHP (anti-webshell)

```apache
php_admin_flag expose_php off
php_admin_value open_basedir "/var/www/html/portal:/tmp"
php_admin_value disable_functions "exec,passthru,shell_exec,system,proc_open,popen,pcntl_exec,dl"
```

ATENÇÃO: `proc_open`/`exec` são usados por ferramentas do projeto (ex.: `spatie/pdf-to-text` -> binário `pdftotext`; comandos do MobiAngra). Aplicar no **pool FPM web** e validar que fluxos web não quebram, mantendo o **php.ini de CLI sem a restrição** (artisan/cron precisam dessas funções).

### 3.7 (Baixa/longo prazo) CSP muito permissiva
```
default-src 'self' https: data: blob: 'unsafe-inline' 'unsafe-eval';
```
`https:` libera qualquer origem HTTPS; `'unsafe-inline'` + `'unsafe-eval'` anulam a proteção da CSP contra XSS. Hoje a CSP é praticamente decorativa para XSS. Apertar é um trabalho à parte (portal usa muito inline/Bootstrap), idealmente com nonces/hashes.

### 3.8 (Baixa) Itens menores
- `X-XSS-Protection "1; mode=block"` está obsoleto; orientação atual é `0` ou remover.
- Log nomeado `...homolog.log` no vhost de produção — possível resíduo de cópia da homologação.
- Avaliar `SymLinksIfOwnerMatch` no lugar de `FollowSymLinks`.

## 4. Prioridade

1. Alta: regex `<FilesMatch>` (3.1); confirmar SAPI (3.2); permissões de `public/` (3.3).
2. Média: HSTS (3.4); vhost :80 (3.5); hardening PHP com cautela (3.6).
3. Baixa/longo prazo: CSP (3.7); itens menores (3.8).

## 5. Observação

Nenhuma alteração de servidor foi feita por este relatório (o vhost reside em `/etc/apache2/sites-enabled/`, fora do repositório). As recomendações devem ser aplicadas pela equipe de infraestrutura e seguidas de `apachectl configtest` + reload.
