Divulgação responsável de vulnerabilidades

Todo software tem bug. A gente prefere que seja você a achar o nosso.

Este é o programa de divulgação de vulnerabilidades do diagnos. Não pagamos em dinheiro — hoje não temos como. Pagamos em gratidão pública, num lugar no hall da fama e na certeza de que o exame de alguém ficou mais seguro pela sua contribuição.

security.txt
curl https://diagnos.health/.well-known/security.txt Contact: mailto:[email protected]Contact: mailto:[email protected]Policy: https://diagnos.health/en/bounty/Preferred-Languages: pt-BR, en, es, it, frExpires: 2027-09-16T00:00:00Z

Se precisar de mais detalhes, o arquivo está no ar: /.well-known/security.txt

Acesso rápido

As dez seções desta página, para abrir direto a que você procura.

Hall da fama

Toda vulnerabilidade válida entra nesta lista, com o nome que você escolher — seu nome, seu apelido, seu @ ou nenhum deles.

#PesquisadorO que achouQuando
001 VOCÊ esta linha está reservada quando você quiser
002 — — —
003 — — —
004 — — —
005 — — —
Cartaz em pixel art de um homem de cartola apontando o dedo para quem lê

EU QUERO VOCÊ

PARA A SEGURANÇA DO DIAGNOS

Sim, está vazio. O programa nasceu junto com esta página, então alguém vai ter que ser o primeiro. Não é uma vaga concorrida ainda.

Postura de segurança

O que já está em produção, e as seis lacunas que ainda não fechamos.

Controles ativos em produção

  • A senha nunca chega até nós

    Login roda em OPAQUE (PAKE): o servidor nunca vê sua senha, nem durante o login. Guarda só um registration_record, que sozinho não abre nada.

  • O servidor nunca abre seu cofre

    As chaves nascem no seu dispositivo. O servidor só recebe texto cifrado — não existe uma linha de código do outro lado que abra uma KEK.

  • Repetir uma requisição não funciona

    Todo pedido sensível carrega nonce + timestamp, chave primária (scope_id, ts, nonce) no D1, tolerância de relógio de 120s e retenção de 300s varrida por cron.

  • Cada request relevante vira registro

    Gravamos um objeto por request relevante no R2. A escrita é cobrada e roda fora do caminho crítico da resposta — auditar não atrasa ninguém.

  • O domínio mais sensível é o mais trancado

    sign.diagnos.health tem CSP default-src 'none' de verdade — bloqueia, não só relata — e SRI calculado no build. Cookie de dispositivo __Host-, HttpOnly, Secure, SameSite=Strict.

  • O dado clínico sabe onde mora

    Laudo e imagem ficam num bucket R2 com jurisdição UE amarrada direto no binding — não é promessa em contrato, é configuração que a infraestrutura aplica.

Lacunas conhecidas

  • Nunca contratamos um teste de intrusão independente. Ninguém de fora auditou isto.
  • Não temos SOC 2 nem ISO 27001.
  • HIPAA: os requisitos técnicos estão cobertos, mas a cadeia de contratos com subprocessadores (BAA) está incompleta — só dois assinados, o resto em negociação.
  • A CSP do aplicativo ainda está em modo report-only: ela relata a violação, não bloqueia nada.
  • Varredura automatizada de vulnerabilidade ainda acontece de forma pontual, não como rotina contínua.
  • O disjuntor de rate limit é um chute conservador, nunca calibrado contra tráfego real.

A primeira lista é o que já construímos. A segunda é por que esta página existe. A gente não está pedindo a sua confiança — está pedindo a sua desconfiança, documentada num relatório.

Escopo do programa

Os alvos autorizados, os que estão fora e a regra da audiência interna.

Nove alvos possíveis. A etiqueta ao lado de cada um diz se ele está dentro, fora, ou dentro-mas-com-letra-miúda — leia antes de apontar qualquer ferramenta para um deles.

Alvo Situação O que é
vault.diagnos.health Dentro do escopo O servidor principal do produto — o "cofre". Sessão, destravamento via OPAQUE, ledger, URLs assinadas do R2, Agentes de IA, MCP e OAuth passam todos por aqui.
api.diagnos.health Dentro do escopo O mesmo servidor, com o outro nome que o produto usa para ele. Hoje as duas entradas convivem no código — as duas valem.
/api/internal/v1/* Dentro, com ressalva Prefixo dentro da própria API, reservado ao aplicativo oficial — exige headers que um curl solto não produz sozinho. Leia o aviso logo abaixo antes de testar esta linha.
sign.diagnos.health Dentro do escopo A cerimônia de assinatura do laudo — WebAuthn/passkey, aberta por link ou QR code. É o domínio mais sensível do produto.
app.diagnos.health Dentro do escopo O aplicativo web do diagnos.
diagnos.health Dentro do escopo Este site, o que você está lendo agora. Está no escopo mesmo sendo marketing estático — mas ajuste a expectativa: o pior que tem por aqui é um redirecionamento aberto.
SDK · CLI · API Apache-2.0 Dentro do escopo SDK, CLI e API em Python, licença Apache-2.0. O código vai para um repositório público em breve — ler o código é bem-vindo.
*.diagnos.health Fora do escopo Qualquer *.diagnos.health que não está nesta lista está fora do escopo e fora do porto seguro. É o padrão que o GitHub consagrou: só podemos autorizar pesquisa em sistema que é nosso.
cloudflare · google · modal · sentry · … Fora do escopo Cloudflare, Google/Firebase, Modal, Sentry e afins. Reporte a eles, não a nós — a menos que o problema esteja claramente na nossa integração.

Sobre a linha "internal" (e por que o curl sozinho não chega lá)

Headers exigidos

Os cinco headers que o aplicativo oficial emite sozinho.

A audiência internal exige, todos ao mesmo tempo:

  • Authorization: Bearer <Firebase ID token>
  • X-AppCheck-Token
  • X-Signature-Hmac
  • X-Signature-Nonce
  • X-Signature-Timestamp

O que não existe

Dois boatos internos que este parágrafo mata.
  • Não existe X-Device-Challenge. O nome circulou internamente, mas nunca existiu uma linha de código com ele.
  • Não existe bloqueio automático de workspace. Nenhuma chamada errada tranca uma conta sozinha — isso também circulou, e também é falso.

O que existe de fato

Rate limit, antirreplay, freio de força bruta e telemetria revisada por gente.

O que existe de verdade, e dá o mesmo recado:

  • Limite de requisições por rota, e um disjuntor por escopo: 600 requisições por janela.
  • Antirreplay de verdade: chave primária (scope_id, ts, nonce) — nonce repetido devolve 409, não 401.
  • Freio de força bruta no login: 10 tentativas em 15 minutos por conta, melhor esforço.
  • Todo 4xx/5xx vira sinal de segurança anônimo; os de severidade alta abrem uma exceção que uma pessoa revisa antes de qualquer bloqueio.

Teste a audiência internal pelo aplicativo web, com a sua própria conta: os headers nascem sozinhos, e tudo o que você fizer ali está dentro do escopo e do porto seguro. Martelar /api/internal/v1/* direto no curl não prova nada além de uma coleção de 401 — e ainda gera ruído que uma pessoa vai ter que triar à mão.

Dados de paciente

A única regra sem exceção: pare no primeiro registro real.

O que não fazer

  • Não abra o exame.
  • Não role a página.
  • Não tire print.
  • Não copie o ID "para conferir depois".

O que fazer

  • Reporte na hora, com o mínimo necessário para provarmos que o problema existe.
  • A prova de conceito demonstra o acesso, nunca o conteúdo — por exemplo: "consegui listar registros de outros workspaces pelo endpoint X trocando o parâmetro Y", sem colar o laudo.
  • Apague toda cópia local: cache, captura de tela, histórico do Burp, log de proxy.
  • Nunca exfiltre, baixe, compartilhe, publique ou tente monetizar dado de paciente — nem para provar impacto.

Não é burocracia. É que do outro lado desse JSON tem um resultado de biópsia com nome e sobrenome.

Regras de engajamento

O que pode durante o teste, uso de IA, prazo de resposta e divulgação.

Durante o teste

Contas de teste, ferramentas automatizadas, e pare no primeiro dado real.
Pode
  • Testar com contas de teste próprias, ou contas que você mesmo criou.
  • Rodar ferramenta automatizada — scanner, fuzzer — com bom senso.
  • Parar no primeiro sinal de dado de paciente real e reportar.
Não pode
  • Acessar, ou tentar acessar, a conta de outra pessoa.
  • Fazer DoS volumétrico, ou apontar um scanner cuspindo milhares de requisições por minuto contra produção — despejo de tráfego não é pesquisa, é abuso.
  • Usar engenharia social contra nossa equipe, nossos pacientes ou nossos parceiros.
  • Fazer ataque físico.

Parar não é sugestão — é a regra mais importante desta página. Detalhe completo em Dados de paciente.

Uso de IA em relatórios

Pode usar. Cada afirmação técnica do relatório continua sendo sua.
  • Pode usar IA para explorar ou escrever — não vamos fingir que isso não existe. Mas você responde por cada palavra e cada afirmação técnica do relatório, gerada por IA ou não.
  • Diga explicitamente se uma ferramenta de IA ajudou.
  • Todo relatório precisa de prova de conceito que funcione de verdade, reproduzida por você. Saída de scanner ou de LLM sem confirmação manual não é vulnerabilidade — é hipótese, e hipótese sem verificação é fechada como inválida.

Relatório fabricado, exagerado ou com PoC que não reproduz é fechado sem resposta detalhada. Reincidência resulta em banimento do programa.

curl — jan. 2026

Em janeiro de 2026, o projeto curl encerrou o programa de bug bounty inteiro depois que relatório gerado por IA passou a superar de longe o relatório válido. Em anos de monitoramento, nenhum relatório produzido só por IA, sem verificação humana, encontrou uma vulnerabilidade real.

Não queremos chegar lá.

Prazos de atendimento

Confirmação em até 5 dias úteis, depois triagem, correção e aviso.
  1. Confirmação

    Confirmamos o recebimento do seu relatório em até 5 dias úteis.

  2. Triagem

    Avaliamos a severidade e te dizemos o encaminhamento.

  3. Correção

    Trabalhamos na correção com prioridade proporcional à severidade.

  4. Aviso

    Avisamos quando a correção for publicada.

  5. Reconhecimento

    Oferecemos crédito público opcional — e não retaliamos pesquisa de boa-fé.

A régua completa de severidade e prioridade está na seção Classificação de severidade.

São objetivos de atendimento, não garantia contratual de SLA — mas é o padrão que a gente se cobra.

Divulgação pública

Pedimos 90 dias corridos antes de qualquer publicação.

Pedimos 90 dias corridos contados da confirmação do problema — não do envio, que é uma data que só você controla — antes de qualquer publicação.

Se a correção sair antes disso, dá para combinar uma data conjunta mais cedo.

Se o problema estiver sendo explorado por terceiros agora, o prazo encolhe — nos avise na hora.

E nunca publique dado de paciente, credencial real ou qualquer coisa que aumente o risco, mesmo depois do prazo.

Porto seguro jurídico

Por que esta política é a autorização expressa que o art. 154-A exige.

Na prática, nos comprometemos a:

  • Não mover nem apoiar ação civil, notícia-crime ou denúncia contra você pela pesquisa que você fez dentro desta política — inclusive pelas medidas técnicas usadas para acessar um sistema em escopo.
  • Se um terceiro ameaçar ou abrir ação contra você por essa pesquisa, declarar pública e formalmente que sua conduta foi autorizada e de boa-fé.

E isso tem limite — tão visível quanto a promessa:

  • Vale só para os sistemas listados em Escopo. A gente não pode autorizar pesquisa em sistema de terceiro, mesmo que dê para chegar nele a partir do nosso.
  • Não cobre conduta fora do escopo ou fora das regras desta política.
  • Não cobre levar dado embora. Acessar para testar é uma coisa; extrair é outra — ver Dados de paciente e o §4º do art. 154-A, que aumenta a pena justamente por isso. E a autorização daqui não dispensa a obrigação de proteção de dados: o dever de segurança por trás deste programa vem da Lei Geral de Proteção de Dados (LGPD) e do Regulamento Geral de Proteção de Dados (GDPR) ao mesmo tempo — é perante os dois regimes que você responde se sair daqui com dado de paciente.
  • Não vale para pesquisa feita para extorquir ou coagir ninguém, nem para quem está excluído em Reconhecimento.

Na dúvida se um teste específico cabe nesta política, pergunte antes. Fale com a gente em [email protected].

Fundamento legal no Brasil

No Brasil não existem "CFAA" nem "DMCA". São leis americanas, e colar essa sigla numa política brasileira não protege ninguém aqui — só denuncia que o texto foi traduzido, não pensado.

O que se aplica é o art. 154-A do Código Penal (Lei nº 12.737/2012, alterada pela Lei nº 14.155/2021). Ele torna crime invadir dispositivo informático alheio "sem autorização expressa ou tácita" de quem usa aquele dispositivo.

Tem um detalhe que muda tudo. A redação de 2012 só valia quando a invasão acontecia "mediante violação indevida de mecanismo de segurança" — era preciso quebrar uma trava. A Lei nº 14.155/2021 tirou essa exigência do texto. Hoje o crime não depende mais de quebrar nada: depende só de agir sem autorização. A autorização virou o elemento que decide tudo, sozinha.

É por isso que esta página é a autorização expressa de que a lei fala. E isso é mais forte do que prometer não te processar: com autorização, o crime nem chega a existir — não é uma defesa depois do fato, é a ausência de um elemento do próprio tipo penal. Conduta autorizada nunca vira crime.

Achados não elegíveis

Os casos que encerramos sem análise, agrupados por categoria.

Não é que a gente não se importe — é que sem impacto demonstrado não dá para distinguir de ruído.

Configuração e cabeçalhos

Cabeçalho ausente, SPF/DKIM/DMARC, versão exposta.
  • Cabeçalho de segurança ausente (CSP, HSTS, X-Frame-Options) sem PoC de exploração real.
  • Registro SPF, DKIM ou DMARC ausente ou mal configurado.
  • Versão de software exposta em banner, header ou changelog público, sem exploração associada.
  • Ausência de certificate pinning em app mobile.

Interface e interação

Clickjacking sem ação sensível, self-XSS, redirect aberto.
  • Clickjacking em página que não executa nenhuma ação sensível.
  • Self-XSS — a vítima precisa colar o próprio payload.
  • Redirecionamento aberto sem impacto adicional demonstrado.

Enumeração e limites de taxa

Enumeração de usuário, rate limit sem prova de brute-force.
  • Enumeração de usuário ou e-mail — descobrir se um cadastro existe.
  • Ausência de rate limit sem prova de brute-force viável.
  • CSV injection sem execução comprovada no ambiente da vítima.

Infraestrutura e disponibilidade

DoS volumétrico e interceptação sem falha nossa.
  • Negação de serviço volumétrica, ou que dependa de gerar tráfego massivo.
  • Ataque que exige interceptar tráfego de outra pessoa, sem uma falha nossa que viabilize isso.

Terceiros e dependências

Falha em biblioteca ou serviço que não operamos.
  • Falha em biblioteca de terceiro, sem PoC de exploração específica no nosso ambiente.
  • Falha em serviço ou infraestrutura que não operamos.

Qualidade do relatório

Saída de scanner ou de IA sem verificação humana.
  • Saída de scanner sem PoC manual e sem confirmação de exploração real.
  • Relatório gerado por IA sem verificação humana e sem PoC reprodutível.

Fora do modelo de ameaça

Engenharia social, ataque físico, navegador obsoleto.
  • Engenharia social contra nossa equipe, nossos parceiros ou nossos pacientes.
  • Ataque físico contra escritório, funcionário ou dispositivo.
  • Bug que só se manifesta em navegador ou sistema obsoleto, sem suporte do fabricante.
  • Ataque que depende de você seguir instrução do próprio atacante — colar comando, instalar extensão.

Acha que o seu caso é a exceção? Mande assim mesmo e explique por quê. Esta lista é um filtro, não um muro.

Classificação de severidade

Crítica, alta, média e baixa, com exemplos concretos do produto.

A severidade decide uma coisa: a ordem da fila de correção. Mais nada.

Severidade Critério geral Exemplos no diagnos
Crítica Compromete a confidencialidade de mais de um paciente, ou quebra a garantia central do fim-a-fim — sem precisar que a vítima clique em nada.
  • Decifrar o laudo de alguém sem ter a chave — a quebra do próprio modelo de ponta-a-ponta
  • Bypass de autenticação que atravessa workspaces
  • Extração de material de chave do nosso backend
  • Execução remota de código no servidor que processa os exames
  • IDOR que cruza workspaces diferentes
Alta Compromete dados de um workspace só, ou dá privilégio de administrador dentro dele — ainda sem interação da vítima.
  • IDOR dentro do mesmo workspace
  • Escalada para administrador de um workspace
  • XSS armazenado numa área autenticada
  • Bypass pontual do WebAuthn
Média Tem impacto real, mas limitado: precisa de um clique da vítima, ou expõe metadado em vez do conteúdo do laudo.
  • XSS refletido que precisa de um clique da vítima
  • CSRF numa ação que não é clínica
  • Vazamento de metadado que confirma que um exame existe, sem revelar o conteúdo
Baixa Impacto mínimo, exige condições raras acontecendo juntas, ou é só informação — sem caminho claro até um dado de paciente.
  • Erro verboso que não expõe segredo nenhum
  • Versão de biblioteca exposta, sem CVE explorável

A classificação final é nossa — mas a gente explica o raciocínio. Se você discordar, discorde: a gente reavalia.

Reconhecimento e elegibilidade

Não há pagamento em dinheiro. O que existe, e quem pode receber.

Quatro coisas, nesta ordem — a primeira dói um pouco.

  1. Dinheiro: zero.

    Sem "no momento estamos avaliando". Zero, mesmo. Somos uma empresa pequena, e o dinheiro que existe paga servidor e gente. Se isso mudar um dia, esta página muda junto — e você vai ser dos primeiros a saber.

  2. Crédito de produto, talvez.

    Podemos — a nosso critério e sem nenhuma obrigação — oferecer crédito de uso da plataforma. Sem valor combinado, sem garantia, não é negociável. Não é pagamento: é gratidão com nota fiscal em volta.

  3. Um lugar no hall da fama.

    Toda vulnerabilidade válida entra — com o nome que você escolher: nome de verdade, apelido, @ de rede social ou anônimo.

    Ver o hall da fama
  4. A gratidão de quem você nem vai conhecer.

    Do outro lado tem médico e paciente que nunca vão saber seu nome. É pouco. A gente sabe que é pouco. Mas é verdade.

E pedimos uma coisa de volta: licença pra citar seu relatório — técnico, sem dado de paciente — no nosso changelog de segurança, quando a correção sair.

Quem pode participar

Qualquer pessoa pode reportar, e a gente corrige do mesmo jeito. O que muda é o crédito — sem reconhecimento público nem crédito de produto para:

  • Quem trabalha ou trabalhou na MedDeck nos últimos seis meses — prestadores de serviço incluídos.
  • Familiar direto de quem tem informação privilegiada sobre o sistema testado.
  • Pessoa ou entidade em lista de sanções (OFAC/SDN, União Europeia) ou em país sob embargo abrangente.
  • Quem chegou até a falha por quebra de contrato ou vazamento interno, e não por pesquisa independente.

Como enviar um relatório

Os dois canais, criptografia e o que o relatório precisa conter.

A maioria dos relatórios entra pela caixa padrão. A outra existe para quando esperar custaria caro de verdade.

O canal padrão

[email protected]

Todo relatório entra por aqui — é a caixa que a gente lê primeiro, sempre.

Enviar relatório

Só quando esperar custa caro

[email protected]

Exploração ativa acontecendo agora. Dado de paciente já exposto publicamente. Credencial vazada. Esta caixa é para isso — e só para isso.

Usar esta caixa para avisar que falta um cabeçalho de segurança é puxar o freio de emergência para descer no ponto certo: funciona, mas todo mundo no vagão vai olhar para você.

Isto não pode esperar

O que o relatório precisa conter

  • Passos de reprodução numerados, na ordem em que você realmente fez.
  • O impacto real — o que um atacante consegue FAZER, não só "eu consegui X".
  • Ambiente, navegador e conta que você usou.
  • Uma prova de conceito mínima e não destrutiva.

Não precisa ser em inglês, nem formatado como CVE. Clareza vale mais que formalidade.

Mantenha tudo no canal privado com a gente até combinarmos juntos a divulgação pública.

O arquivo que faz esse trabalho por você. Ele já está no ar, e é por ele que uma ferramenta automática nos acha antes de qualquer humano ler isto aqui: /.well-known/security.txt

Relatório cifrado

Ainda não publicamos uma chave PGP. Quer cifrar o relatório mesmo assim? Peça por e-mail que a gente manda uma forma de fazer isso.

Perguntas frequentes

Oito respostas diretas, do pagamento ao prazo de divulgação.

Vocês pagam mesmo nada?

Nada. Nem em dinheiro, nem em cripto, nem em camiseta. Podemos oferecer crédito de produto quando fizer sentido, sem qualquer garantia — é gratidão com limite, não um preço disfarçado.

Posso testar com a minha conta de verdade?

Pode, e é o jeito recomendado para quem é da audiência interna — veja a seção "Escopo". O que nunca pode, em hipótese nenhuma, é testar com a conta de outra pessoa.

Achei dado de paciente. E agora?

Pare. Não abra o exame, não role, não copie o ID "para confirmar depois". Reporte o achado sem colar o conteúdo do laudo — a seção "Dados de paciente" tem o passo a passo, e não é burocracia: é a diferença entre pesquisa de segurança e crime.

Quanto tempo até alguém me responder?

Confirmamos o recebimento em até 5 dias úteis; depois, você recebe uma posição sobre severidade e encaminhamento. É a meta de atendimento que nos cobramos, não uma cláusula de SLA contratual.

Posso publicar o que eu achei?

Sim — 90 dias corridos depois da confirmação do problema, ou antes se combinarmos uma data junto. Nunca com dado de paciente dentro, mesmo depois do prazo.

Usei IA para achar isso. Tem problema?

Nenhum, desde que você tenha verificado e reproduzido o problema sozinho, num ambiente real. Saída de IA sem essa checagem não é vulnerabilidade, é hipótese — a seção "Regras" explica por quê.

Vocês vão me processar?

Não, se você seguiu esta política. A seção "Porto seguro" é, em uma frase, a autorização expressa que o art. 154-A do Código Penal exige para o que você está prestes a fazer não ser crime — não é retórica, é o texto da lei.

Já reportei e não teve resposta.

Reenvie mencionando a data do primeiro envio — e-mail se perde. Se for urgente de verdade, use a caixa de urgência. Não é desdém: somos uma equipe pequena, não um centro de operações de segurança 24 horas.

É isso. Pode começar.

Se você leu até aqui, já se importa com os dados desses pacientes mais do que muita gente que trabalha com eles todo dia. Obrigado — e boa caçada.

Reportar uma falha