CONFIDENCIAL · avaliação de superfície pública · não destrutivo

Relatório técnico de verificação
Fortaleza Digital

ParviSentinel Pulse · L3 máximo · leitura e prova, sem alteração do sistema

Alvo. https://fortalezadigital.fortaleza.ce.gov.br
Data da corrida. 2026-08-25 (UTC)
Engajamento. eng_pulse_fortaleza
RoE. public-max · não destrutivo
Emitente. FriendlyAI.fi (FriendlyAI Oy)
Responsável técnico. Renata Baldissara-Kunnela

1. Introdução — escolha do ambiente, objetivo e propósito

Este documento é a versão técnica, em formato de relatório, da verificação executada em 25 de agosto de 2026 sobre o portal Fortaleza Digital da Prefeitura de Fortaleza (secretaria / serviços educacionais em Oracle ORDS + APEX). Foi utilizado, a título de demonstração e de teste primário, um sítio da prefeitura em superfície pública, no nível de exame aberto (sem conta autenticada da secretaria), no máximo de profundidade permitido sem dano (L3).

Objetivo. Mapear o que um examinador — humano ou enxame de agentes de IA com navegador e terminal — consegue observar e provar em modo leitura: borda (WAF), transporte (TLS), ativos estáticos (CORS), higiene de cabeçalhos, alcance do banco de dados a partir da superfície pública, e o que permanece incompleto quando a borda bloqueia o examinador.

Propósito. Entregar à equipe da prefeitura um mapa acionável (achados, evidência, remediação, validação) e deixar explícito o que este teste primário não cobre: ambiente autenticado, demais sistemas da secretaria, e camadas internas atrás do login.

O que não foi feito. Não houve exploração, flood, alteração de dados, quebra de senha, nem execução do cenário de enxame. O bloco “o que um enxame faria” é extrapolação ancorada no que foi lido, não prova de invasão.

2. Método

ComponenteUso nesta corridaNota
ParviClaw Core4 faixas paralelas (sessões F1–F4)spawn registado em folha hash-encadeada
ParviSightnavegador realdistinguiu a página de negação WAF que o HTTP cru mascarava como 200
Cadeia TLS / CORShandshake 443 + Origin arbitrária no host estáticoevidência f5.json
Solver de captchaem esperanenhum desafio visível na superfície alcançada

Stack observada: Oracle ORDS + APEX (cookie ORA_WWV_APP_152, URLs r/portal), reverse proxy + WAF, TLS DigiCert, host estático info.fortaleza.ce.gov.br.

3. Achados

MÉDIO FD-M1 — Certificado TLS expira em ≈ 2026-09-15

Emissor DigiCert (GeoTrust TLS RSA CA G1). notAfter: Sep 15 23:59:59 2026 GMT. Protocolo TLSv1.2, cifra ECDHE-RSA-AES128-GCM-SHA256. Sem indício de renovação ACME. Certificado vencido em portal gov = browsers bloqueiam o cidadão.

Onde. fortalezadigital.fortaleza.ce.gov.br:443

Prova (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

Remediação. Automatizar renovação (ACME ou agenda no provedor). Alerta 30 / 14 / 7 dias. Validação. Repetir o comando: notAfter > 60 dias à frente.

Evidência. evidence/f5.json · SHA-256 b7c2e6919fbbaccc3dabb864f9c38890504bd0f92e24ff478436e62970d6261a

MÉDIO FD-M2 — Host estático devolve Access-Control-Allow-Origin: *

info.fortaleza.ce.gov.br reflete ACAO * inclusive para origem arbitrária. Hoje serve CSS/imagens. Qualquer endpoint sensível nesse host fica legível cross-origin.

Prova.

curl -sSI 'https://info.fortaleza.ce.gov.br/css/style.css' -H 'Origin: https://evil.example' | grep -i access-control

Remediação. Restringir ACAO às origens da prefeitura. Validação. O mesmo pedido não deve devolver * para origem arbitrária.

INFO FD-I2 — Higiene de cabeçalhos da aplicação

Remediação. Referrer-Policy strict-origin-when-cross-origin; CSP mínima; SameSite=Lax se compatível.

4. Controles que funcionaram

5. O que um enxame de agentes faria (não executado)

Extrapolação do que foi provado em leitura. Nenhum destes passos foi desferido contra o portal.

6. Limitações desta corrida

O WAF bloqueou o IP do examinador a meio da onda. Reflexão de parâmetros e superfícies de login ficaram incompletas: “zero achado” nessas faixas significa não testável neste run, não “seguro”. Login: HTTP 200 sem formulário no HTML estático (JS não alcançado). Captcha: nenhum visível nas superfícies alcançadas.

7. Ordem de correção (apontamos; a equipe fecha)

#ItemSeveridadeEsforço típico
1Renovar TLS e automatizar (FD-M1)Médio1–2 h
2Referrer-Policy + CSP (FD-I2)Info~1 h
3Restringir ACAO no estático (FD-M2)Médio~30 min

ParviSentinel verifica. Não instala correção. Não substitui o firewall nem a equipe.

8. Conclusão — o que este teste primário exige a seguir

A conclusão deste relatório não é o resultado da corrida de 25 de agosto. A conclusão é a necessidade de um exame completo, mais profundo, no ambiente da secretaria, em várias camadas:

Só assim se pode afirmar, com o mesmo rigor desta corrida, se o dado sensível está ao alcance de um examinador — humano ou enxame — para além da porta que o WAF já demonstrou saber fechar.

9. ParviGov — o livro dos passos, AWP e descarga

ParviGov é o produto de governança: o livro encadeado do que os agentes fizeram (LAG), a prova criptográfica para abrir esse livro (AWP) e, se precisarem de recibo emitido, o emissor (PayBotFin). Não é um “log de aplicativo” solto.

Guia de leitura (página e PDF). Como o cliente abre cada ficheiro, sem programa: página · PDF do guia.

Nesta corrida, cada passo de agente foi escrito em folha encadeada por hash. Quatro folhas correspondem ao arranque das quatro sessões (F1 ORDS, F2 sessão, F3 reflexão, F4 navegador). Os recortes de prova HTTP/TLS estão em cinco JSON. Os arquivos não ficam dentro deste PDF: cada botão Abrir mostra o texto no browser, sem precisar de programa. f1 a f5 são JSON (um bloco só). Só o livro é JSONL (4 linhas). JSONL o telemóvel e o Bloco de notas muitas vezes não abrem. Por isso o botão do livro abre a versão em texto, folha a folha.

FicheiroO que éSHA-256Abrir
parvigov-leaves.jsonl Livro das 4 folhas (laboratório) c5d541b0b1e9ea713d446aab9fb2cde6fca1406be6328812b46d0339e4124222 Abrir
f1.json Prova faixa 1 (ORDS) c62170b8902b1792bac3a58b42ef605113c2366449635c63597e4dc50fa17c30 Abrir
f2.json Prova faixa 2 (sessão) 2fedf1ea33ae76b727bcb9d0109dac5c028d1df83fac7255835fff235eb54fe1 Abrir
f3.json Prova faixa 3 (reflexão) 3afd9436da6ee6578f0a23588f74870cabc33207f2cce66258e860115b8b0913 Abrir
f4.json Recorte do navegador da faixa 4. Não é recibo AWP. 74a40b1a8b83e1f0b1e8195dc7d79c9bd708403b4405748f0f19a3c87e4a3522 Abrir
f5.json Prova TLS / CORS b7c2e6919fbbaccc3dabb864f9c38890504bd0f92e24ff478436e62970d6261a Abrir
pacote .tar.gz Tudo junto + este leia-me 1fa1a026734d123e103c17702e5c783e21caab22de6097bb7157ff3c3b782edb Baixar tudo

O que o cliente vê quando abre cada ficheiro

Isto não é o AWP a “passar”. É a leitura do recorte, no browser ou num editor. Guia no mesmo endereço da pasta: https://chefe-read.pages.dev/fortaleza-evidence-2026-08-25/

FicheiroO que o examinador leuO que isso quer dizer
f1.jsonLista de caminhos ORDS/APEX e o código HTTP de cada um. Um deles é o padrão de teste que a porta de segurança cortou (página de ~705 bytes).Mapa da superfície pública. A porta viu o padrão e bloqueou.
f2.jsonTrês amostras de sessão (cookie de 32 caracteres, SameSite=None). Telas de login sem formulário no HTML estático.Sessão existe e muda. Login autenticado ficou incompleto nesta corrida.
f3.jsonParâmetros (area, sessão, versão) injetados. Nenhum veio refletido de volta.Nesta corrida a reflexão não se confirmou. “Não refletiu” ≠ “seguro”: a porta já tinha cortado o examinador.
f4.jsonURL da página Resultado (educação), título, 40 controlos, 8 campos, captcha não visível.Foto do navegador. Não é recibo. Não se aponta o AWP neste ficheiro.
f5.jsonCadeado até 15/09/2026. Host estático aceita leitura de qualquer origem. Porta disparada na faixa 1.É o achado médio do cadeado e do arquivo estático.
parvigov-leaves.jsonlQuatro linhas: arranque das faixas F1 a F4, com hora e hash. Campo witness_mode = laboratório.Livro dos passos. Encadeado. Sem recibo de produção.

A chave que falta no f4.json não é o AWP.

O npm i agent-witness-protocol baixa a ferramenta (o leitor). Não baixa a chave. A chave pública tem de vir dentro de um recibo assinado (receipt.json), ou ser passada à parte. O f4.json é um recorte do navegador (URL, título “Resultado”, 40 controlos). Não tem chave dentro. Por isso o comando npx awp verify f4.json para e diz: no public key (falta chave pública). Não é senha. Não é o pacote npm.

Como o cliente confere o f4 hoje: abre o JSON e lê o recorte; bate o SHA-256 com a tabela acima. O AWP em PASS só entra quando existir recibo emitido (PayBotFin). Nesta corrida o testemunho das folhas é laboratório (local_awp_dev). Não afirmamos PASS de recibo de produção.

O que o AWP faz, quando houver recibo. Abre o recibo. Cadeia e assinatura íntegras = PASS. Um byte mudou = FAIL. Não prova identidade humana nem que “tudo o que aconteceu no mundo” foi gravado.

npm i agent-witness-protocol
npx awp verify receipt.json

Para ver o AWP funcionar sem o recibo desta corrida, o próprio pacote traz um exemplo: npx awp verify node_modules/agent-witness-protocol/samples/receipt.json → PASS.

Responsável técnico

Renata Baldissara-Kunnela
FriendlyAI.fi · FriendlyAI Oy
Y-tunnus / VAT: FI32402899
Kallioniementie 732, 44480 Niinilahti, Finland
Tel. +358 40 182 9008
renata.baldissara-kunnela@friendlyai.fi

Assinatura da emitente deste relatório. ParviSentinel aponta. A equipe do cliente fecha.