← Tilbage til My Medicus
Sprog · Language
🇩🇰 DK🇬🇧 EN🇪🇸 ES🇩🇪 DE🇫🇷 FR🇮🇹 IT🇵🇹 PT🇹🇷 TR

Qual é a vossa segurança em relação ao My Medicus?

medicus.global · 2026-05-05


A voz da paciente

"Todas as informações fui eu que as introduzi, e consinto que o
pessoal de socorro e os médicos as possam ler — para lhes dar o
melhor conhecimento prévio possível da minha situação pessoal,
especialmente numa emergência. O meu amor pela vida é maior do
que as regras do país sobre proteção de dados."

Essa é a decisão adulta e voluntária por trás de cada perfil My Medicus criado. A nossa tarefa é honrar a escolha da paciente: guardar os dados em segurança, mostrá-los apenas a quem tem o PIN correto, deixar a paciente ver cada leitura, e permitir que a paciente revogue o cartão no segundo em que é perdido. O resto deste documento explica como.


Pergunta

"Qual é a vossa segurança em relação ao My Medicus?"

Resposta — o nosso ponto de vista

Numa emergência, o maior desejo da paciente é recuperar. É a quem servimos. A segurança é o meio, não o fim.

Três princípios estão acima de tudo:

  1. A paciente é a remetente. Toda a informação no cartão é introduzida pela própria paciente com consentimento. Não importamos de outras bases de dados. Menos é melhor.
  2. A comparação é o quotidiano, não um estado ideal. Uma carteira perdida contém número de identidade, cartão de saúde, cartão de doador, cartões de crédito, fotos. A farmácia grita o número de identidade por cima do balcão. O nosso cartão é melhor que a exposição que já acontece todas as semanas — cifrado, bloqueado por PIN, com registo de auditoria, revogável.
  3. Fazemos tudo o que é possível e somos honestos sobre o que não podemos. Quando um paramédico lê legitimamente o cartão, pode tirar uma foto. Não podemos evitá-lo. Defesa: a paciente vê cada leitura no seu "Meu registo" e pode revogar o cartão com um clique.

O que foi concretamente testado

Documentámos 19 cenários de ataque diferentes contra o My Medicus e executámos cada um contra o sistema de produção. O resultado está descrito abaixo — sem linguagem de marketing, sem "padrão da indústria", sem "best practice". Apenas o que foi concretamente testado.


O que foi testado

19 cenários de ataque contra duas contas na base de dados em produção — uma conta demo e um novo utilizador real. Ferramentas: pedidos HTTP diretos, execução paralela, introspeção SQL da base de dados de produção, parsing de respostas.

Resultado: 14 ataques encontraram defesas que aguentaram. 5 vulnerabilidades foram encontradas e fechadas no mesmo dia.

As 14 camadas de defesa que aguentaram

Ataque Por que falhou o ataque
Roubo de toda a base de dados Alergias, medicação, identificadores nacionais, passaporte, CESD e números de seguro estão cifrados com AES-256-GCM. A chave vive numa loja de segredos separada, nunca na base de dados. Se roubares o ficheiro DB, obténs texto ilegível
Força bruta sobre PIN de 6 dígitos Atrasos progressivos ativam-se à 5ª tentativa errada: 5 seg → 30 seg → 60 seg entre cada
Injeção SQL no formulário de login Todas as consultas à base de dados usam consultas parametrizadas — cinco payloads de injeção diferentes foram rejeitados
Chamadas API diretas sem login Todos os endpoints protegidos devolvem HTTP 401
Adivinhar tokens Os tokens são 32 caracteres hex derivados via SHA-256. Espaço de procura: 16^32. 50 tentativas aleatórias → 0 acertos
Path-traversal a backups ou config /_db_backups/, /.env, /.git, /medicus.db, /wp-config.php devolvem todos 404
Enumeração de emails via "esqueci-me da senha" Resposta genérica consistente independentemente de o email existir — sem fuga de informação
XSS em campos públicos Servidor rejeita entrada malformada, sem reflexão de HTML/JS
Roubo físico de carteira sem PIN do cartão Bloqueio PIN para todas as tentativas incorretas
10 tentativas paralelas de força bruta Rate-limit aplica-se por token, não por pedido
Eliminação do registo de auditoria via endpoint DELETE Nenhum endpoint DELETE exposto
Adivinhar admin-token (admin, 1234, letmein) Todos devolvem 401
Tentar fazer o servidor vazar segredos via payloads de erro Nem chave de cifragem nem segredos Stripe aparecem na saída de erro
Abuso cross-origin de outro site Browser bloqueia por same-origin policy

As 5 vulnerabilidades encontradas e fechadas

# O quê Severidade O que foi feito
F1 Login respondia 200 ms mais lentamente quando o email estava registado do que quando não estava. Um atacante podia determinar se uma conta existe 🔴 Crítico Login agora executa verificação Argon2id sempre (também contra emails desconhecidos, com hash dummy). Tempo de resposta constante. Mensagem de erro genérica
F2 Sem cabeçalhos de segurança (HSTS, CSP, X-Frame, X-Content-Type, Referrer-Policy, Permissions-Policy) 🔴 Crítico Todos os 6 cabeçalhos são agora adicionados em todas as respostas via middleware. CSP bloqueia script/img/style/frame em sources em whitelist
F3 Um cartão roubado tem QR + PIN impressos diretamente. O ladrão tem acesso até o dono revogar 🟠 Alto (1) Paciente vê cada leitura no seu painel ("Meu registo" — prefixo IP, país, hora). (2) Dono pode revogar o cartão com um clique → todos os cartões impressos morrem instantaneamente + novo PIN gerado
F4 /admin devolvia SPA-HTML a todos, revelando a existência do painel admin 🟡 Baixo Devolve agora o mesmo 404 que rotas inexistentes para utilizadores não autenticados
F5 Esqueci-me da senha podia ser abusado para inundar a caixa de uma vítima (1.000 mails/hora) — e simultaneamente prejudicar a nossa reputação de remetente 🟠 Alto Se o utilizador tem um token reset válido (máx 2 horas), é reutilizado em vez de enviar novo mail. Mais rate-limit por email de 2/min

O que conscientemente NÃO construímos — e porquê

Escolha Justificação
Sem autenticação nacional na vista paramédico A paciente está inconsciente no campo de golfe. O paramédico não tem autenticação nacional, e mesmo que tivesse, não temos 90 segundos para os autenticar. PIN-no-cartão é a resposta prática
Não "zero-knowledge" O servidor PODE decifrar os campos — é condição para que o paramédico possa ver os dados. Não chamamos "zero-knowledge" ao que não é
Sem importação automática de dados Cada campo é escolhido pelo utilizador. Sem auto-import de outras plataformas de saúde

Contra o que não podemos proteger

Se um paramédico ler legitimamente o cartão com o PIN correto, pode fotografar o ecrã. Não podemos impedi-lo — é o preço de os dados sequer poderem ser mostrados numa emergência. Defesa:

É o mesmo modelo de segurança que uma pulseira de identificação médica física para diabéticos: os dados são visíveis ao pessoal de socorro, aceitamos que um carteirista também os possa ver. A diferença é que o nosso modelo dá à paciente controlo sobre quem vê o quê e quando — não apenas visibilidade.

A que nos comprometemos


Perguntas? Escreve para peter@medicus.global

medicus.global · security-my-medicus-pt.md