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

Hvad er jeres sikkerhed i forbindelse med My Medicus?

medicus.global · 2026-05-05


Patientens stemme

"Alle informationer har jeg selv indført, og jeg er indforstået med at
redningsmandskab og læger kan læse dem — for at give dem den bedst
mulige forhåndsviden om min helt personlige situation, særligt i en
nødsituation. Min kærlighed til livet er større end landets regler
om datasikkerhed."

Det er den voksne, frivillige beslutning der ligger bag enhver oprettet My Medicus-profil. Vores opgave er at holde patientens valg i hævd: opbevare data forsvarligt, vise det kun til den der har korrekt PIN, lade patienten se hver scan, og lade patienten revoke kortet i sekundet det er mistet. Resten af dette dokument forklarer hvordan.


Spørgsmål

"Hvad er jeres sikkerhed i forbindelse med My Medicus?"

Svar — vores grundsyn

I en nødsituation er patientens største ønske at blive rask igen. Det er den vi tjener. Sikkerhed er midlet, ikke målet.

Tre principper står over alt andet:

  1. Patienten er afsenderen. Alle oplysninger på kortet er indgivet af patienten selv med samtykke. Vi importerer ikke fra andre databaser. Mindre er bedre.
  2. Sammenligningen er hverdagen, ikke en idealtilstand. En mistet pung indeholder CPR, sygesikringsbevis, donor-kort, kreditkort, fotos. Apoteket råber CPR over disken. Vores kort er bedre end den eksponering der allerede sker hver uge — krypteret, PIN-låst, audit-logget, revoke-bart.
  3. Vi gør alt det der er muligt, og er ærlige om hvad vi ikke kan. Når en paramedic legitimt scanner kortet, kan vedkommende tage et foto. Det kan vi ikke forhindre. Defense: patienten ser hver scan i sin "Min log" og kan revoke kortet på ét klik.

Hvad blev konkret testet

Vi har dokumenteret 19 forskellige angrebs-scenarier mod My Medicus og kørt hver enkelt mod produktions-systemet. Resultatet er beskrevet nedenfor — uden marketing-sprog, uden "industri-standard", uden "best practice". Bare hvad der konkret er testet.


Hvad blev testet

19 angrebs-scenarier mod to konti i den live database — én demo-konto og én ægte ny bruger. Værktøjer: direkte HTTP-requests, parallel-eksekvering, SQL-introspection af produktions-databasen, parsing af responses.

Resultat: 14 angreb mødte forsvar der holdt. 5 sårbarheder blev fundet og lukket samme dag.

De 14 forsvarslag der holdt

Angreb Hvorfor angrebet fejlede
Tyveri af hele databasen Allergier, medicin, CPR, NIE, passport, EHIC og forsikringsnumre er krypteret med AES-256-GCM. Nøglen ligger i en separat secret-store, aldrig i databasen. Stjælder du DB-filen, får du ulæselig tekst
Brute-force på 6-cifret PIN Progressive forsinkelser kicker ind ved 5. forkerte forsøg: 5 sek → 30 sek → 60 sek mellem hver
SQL-injection på login-formular Alle databaseforespørgsler bruger parameterized queries — fem forskellige injection-payloads blev afvist
Direkte API-kald uden login Alle beskyttede endpoints returnerer HTTP 401
Token-gæt Tokens er 32 hex-tegn afledt via SHA-256. Søgerum: 16^32. 50 tilfældige gæt → 0 treffere
Path-traversal til backups eller config /_db_backups/, /.env, /.git, /medicus.db, /wp-config.php returnerer alle 404
Email-enumeration via "glemt password" Konsistent generisk svar uanset om emailen findes — ingen info-leak
XSS i offentlige felter Server afviser malformed input, ingen reflektion af HTML/JS
Fysisk wallet-tyveri uden kortets PIN PIN-gate stopper alle ikke-korrekte forsøg
10 parallelle brute-force forsøg Rate-limit gælder per token, ikke per request
Sletning af audit-log via DELETE-endpoint Ingen DELETE-endpoints eksponeret
Gæt af admin-token (admin, 1234, letmein) Alle returnerer 401
Forsøg på at få server til at lække secrets via fejl-payloads Hverken krypteringsnøgle eller Stripe-secrets dukker op i error-output
Cross-origin abuse fra anden hjemmeside Browser blokerer pga. same-origin policy

De 5 sårbarheder der blev fundet og lukket

# Hvad Hvor alvorligt Hvad blev gjort
F1 Login svarede 200 ms langsommere når emailen var registreret end når den ikke var. En tyv kunne dermed afgøre om en konto findes 🔴 Kritisk Login kører nu Argon2id-verifikation altid (også mod ukendte emails, med en dummy-hash). Konstant svar-tid. Generisk fejl-tekst
F2 Ingen security-headers (HSTS, CSP, X-Frame, X-Content-Type, Referrer-Policy, Permissions-Policy) 🔴 Kritisk Alle 6 headers tilføjes nu på samtlige responses via middleware. CSP låser script/img/style/frame til hvidlistede sources
F3 Et stjålet kort har QR + PIN trykt direkte på det. Tyven får adgang indtil ejer revoker 🟠 Høj (1) Patient ser hver scan i sit dashboard ("Min log" — IP-prefix, land, tidspunkt). (2) Ejer kan på ét klik revoke kortet → alle gamle printede kort dør øjeblikkeligt + ny PIN genereres
F4 /admin returnerede SPA-HTML til alle, hvilket afslørede admin-panelets eksistens 🟡 Lav Returnerer nu samme 404 som ikke-eksisterende routes for ikke-autentificerede brugere
F5 Forgot-password kunne misbruges til at oversvømme et offers indbakke (1.000 reset-mails/time) — og samtidig skade vores egen sender-reputation 🟠 Høj Hvis brugeren har en gyldig reset-token (max 2 timer gammel), genbruges den i stedet for at sende ny mail. Plus per-email rate-limit på 2/min

Hvad vi bevidst IKKE har bygget — og hvorfor

Valg Begrundelse
Ingen MitID på paramedic-view Patienten ligger bevidstløs på golfbanen. Paramedicineren har ikke MitID, og selv hvis de havde, har vi ikke 90 sekunder til at logge dem ind. PIN-på-kort er det praktiske svar
Ikke "zero-knowledge" Serveren KAN dekryptere felterne — det er en betingelse for at paramedic kan se data. Vi kalder ikke noget "zero-knowledge" som ikke er det
Ingen automatisk data-import Hvert felt er valgt af brugeren. Ingen auto-import fra andre sundhedsplatforme

Hvad vi ikke kan beskytte mod

Hvis en paramedic legitimt scanner kortet med korrekt PIN, kan vedkommende fotografere skærmen. Vi kan ikke forhindre det — det er prisen for at data overhovedet kan vises i en nødsituation. Defense:

Det er samme sikkerheds-model som et fysisk medical-ID-armbånd hos diabetikere: data er synlig for redningsmandskab, vi accepterer at en lommetyv også kan se den. Forskellen er at vores model giver patienten kontrol over hvem der ser hvad og hvornår — ikke kun synlighed.

Hvad vi forpligter os til


Spørgsmål? Skriv til peter@medicus.global

medicus.global · security-my-medicus.md