Avaliação de superfície pública — Fortaleza Digital
Portal de serviços educacionais sobre Oracle ORDS + APEX (Prefeitura de Fortaleza). Borda robusta (WAF), mas certificado TLS a expirar e exposição CORS no host estático.
Resumo executivo
Porque agir agora
Estes achados não são teóricos — o certificado TLS expira em ~21 dias e a renovação não está automatizada. Sem ação, o portal fica bloqueado nos browsers modernos na primeira quinzena de setembro, no meio do calendário escolar.
Corrida L3 max em https://fortalezadigital.fortaleza.ce.gov.br/ords/fortaleza-digital/r/portal/resultado?area=educacao. Executada com ParviClaw Core (4 lanes paralelas) + ParviSight (olho de navegador real) + auditoria TLS/CORS. O WAF do portal detectou o primeiro padrão ofensivo e bloqueou o IP do scanner por >15 minutos — comportamento correto de uma borda bem configurada.
Stack nesta corrida
| Componente | Detecção | Nota |
|---|---|---|
| Oracle ORDS + APEX 19+ | cookie ORA_WWV_APP_152 · friendly-URLs r/portal | app id 152 |
| Reverse proxy + WAF | negação 705B com support ID, HTTP 200 disfarçado | bloqueio persistente >15 min |
| TLS (DigiCert) | TLSv1.2 · ECDHE-RSA-AES128-GCM-SHA256 | expira em 21 dias |
| Host estático | info.fortaleza.ce.gov.br | CORS * |
Achados
Certificado TLS expira em ~21 dias (≈2026-09-15)
MÉDIOO certificado do portal (emissor DigiCert) vence em aproximadamente 21 dias a partir da corrida (2026-08-25). Não há indício de renovação automatizada (ACME). Certificado vencido = browsers bloqueiam o portal inteiro para o cidadão.
https://fortalezadigital.fortaleza.ce.gov.br — handshake TLS 443
- Humano: cidadão perde acesso ao portal (tela de aviso vermelho do browser).
- Agente (LLM+ferramentas): n/a — falha de disponibilidade e confiança.
Fortaleza Digital — infra/segurança de rede (renovação de certificados)
Read-only. Não altera o sistema.
openssl s_client -connect fortalezadigital.fortaleza.ce.gov.br:443 -servername fortalezadigital.fortaleza.ce.gov.br 2>/dev/null | openssl x509 -noout -enddate
Automatizar renovação (ACME/Let's Encrypt ou renovação agendada no provedor). Monitorar expiração com alerta a 30/14/7 dias.
Repetir o comando PoC após renovação: notAfter deve mostrar >60 dias à frente.
Host estático responde Access-Control-Allow-Origin: * para qualquer origem
INFOinfo.fortaleza.ce.gov.br devolve ACAO * inclusive para Origens arbitrárias (testado com Origin: https://evil.example). Hoje o host serve apenas assets estáticos (CSS/imagens/logo). O risco é de trajetória: qualquer endpoint sensível adicionado nesse host fica legível por qualquer site.
https://info.fortaleza.ce.gov.br/css/style.css
- Humano: n/a hoje (assets públicos).
- Agente: leitura cross-origin automatizada se conteúdo sensível migrar para esse host.
Prefeitura de Fortaleza — web/estático
Read-only. Não altera o sistema.
curl -sSI 'https://info.fortaleza.ce.gov.br/css/style.css' -H 'Origin: https://evil.example' | grep -i access-control
Restringir ACAO às origens *.fortaleza.ce.gov.br. Se assets forem públicos por design, servir com ACAO apenas nos tipos seguros ou sem CORS.
O mesmo curl não deve mais retornar Access-Control-Allow-Origin: * para origem arbitrária.
Higiene de headers na aplicação (Referrer-Policy unsafe-url, CSP ausente, SameSite=None)
INFOO caminho da app envia Referrer-Policy: unsafe-url (URL completa — incluindo query strings do cidadão — vaza para sites de terceiros), não envia Content-Security-Policy nem Permissions-Policy, e o cookie de sessão ORA_WWV_APP_152 usa SameSite=None (porta residual para CSRF).
/ords/fortaleza-digital/... (todas as respostas da app)
- Humano: rastreamento de navegação do cidadão por terceiros.
- Agente: superfície de CSRF/Clickjacking residual em futuras features.
Fortaleza Digital — time APEX/proxy
Read-only. Não altera o sistema.
curl -sSI 'https://fortalezadigital.fortaleza.ce.gov.br/ords/fortaleza-digital/r/portal/resultado?area=educacao' | grep -iE 'referrer|content-security|permissions'
Referrer-Policy: strict-origin-when-cross-origin (ou strict-origin); CSP mínima (default-src self + domínios aprovados); Permissions-Policy básica; SameSite=Lax no cookie se compatível com integrações.
Headers devem mostrar as três políticas; cookie deve carregar SameSite=Lax (ou justificativa documentada).
Controles funcionando (achados positivos)
WAF ativo e bem calibrado. Tripou no primeiro payload com padrão XSS (F1), respondeu com página de negação de 705 bytes ("Sua solicitação foi negada" + support ID) disfarçada de HTTP 200, e manteve o bloqueio de IP por mais de 15 minutos. Neutralizou as lanes de reflexão de parâmetros.
Sessões com entropia adequada. 3/3 amostras únicas, 32 caracteres.
Headers básicos presentes. HSTS (186 dias, includeSubDomains), X-Frame-Options SAMEORIGIN, X-Content-Type-Options nosniff, Cache-Control: no-store na app.
Limitações honestas
O WAF bloqueou o IP do scanner no meio da corrida. Os testes de reflexão de parâmetros e superfícies de login ficaram incompletos — “nenhum achado” nessas lanes significa não-testável neste run, não “seguro”. Recomendação: re-teste em 24–48h com IP limpo, ou janela de allowlist combinada.
Ordem de correção para o time
| # | Achado | Severidade | Esforço |
|---|---|---|---|
| 1 | Renovar TLS + automatizar (FD-M1) | MÉDIO | 1–2h |
| 2 | Referrer-Policy + CSP (FD-I2) | INFO | 1h |
| 3 | Restringir ACAO no host estático (FD-M2) | INFO | 30min |