PDF-koks hos Forsvaret: Sådan endte 45.952 danskeres sundhedsdata på usikker webserver

8. oktober 2020 kl. 03:4536
PDF-koks hos Forsvaret: Sådan endte 45.952 danskeres sundhedsdata på usikker webserver
Illustration: Forsvaret.
Det var en fejl i forbindelse med generering af PDF-filer til print, der var skyld i, at mere end 45.000 danskeres helbredsskemaer fra sessioner endte på en usikker webserver. Fejlen har stået på siden 2014.
Artiklen er ældre end 30 dage
Manglende links i teksten kan sandsynligvis findes i bunden af artiklen.

For nylig kom det frem, at tusindvis af unge danskeres helbredsskemaer fra session hos Forsvaret har ligget tilgængelige på en usikker webserver, og nu viser det sig, at miseren skyldes en teknisk fejl i noget så enkelt som generering af PDF-filer.

Det fremgår af en redegørelse fra Forsvarsministeriets Personalestyrelse, som Version2 har fået aktindsigt i.

»Bruddet er formentlig sket ved databehandlerens ændring af kode i applikationen i forbindelse med implementering af PDF-genereringsfunktion til brug for print,« skriver styrelsen i sin redegørelse.

Log ind og læs videre
Du kan læse indholdet og deltage i debatten ved at logge ind eller oprette dig som ny bruger, helt gratis.
36 kommentarer.  Hop til debatten
Debatten
Log ind eller opret en bruger for at deltage i debatten.
settingsDebatindstillinger
36
12. oktober 2020 kl. 17:13

Ah... Det er nu ikke helt korrekt.</p>
<p>Webserveren kan sagtens fungere som proxy uden du kan spore det.</p>
<p>Den kan tage en inputstrem, der bliver genereret på en anden server og sende indholdet råt videre som dens egen outputstream.</p>
<p>Set fra klienten kan du ikke se om bytestreamen er genereret af webserveren eller andetsteds.

Jeg skriver ikke noget om at du kan se det i klienten :)

Min pointe var at webserveren bliver bedt om at serve en URL, og ud fra dét vælger hvordan den vil levere content – og at det content ikke behøver være fra en lokal fil, men kan reverse proxyes til en anden server (eller en hel masse andre muligheder, for den sags skyld – de fleste moderne httpd'er er ret fleksible).

Og det kunne i princippet sagtens være en proces der skriver til stdout, hvor stdout så er redirected, om det så er til en socket eller pipe eller andet.

35
9. oktober 2020 kl. 14:42

"fremtræder som en fil" er ikke nødvendigt – webserveren ser en URL, og den kan fx reverse-proxyes til PDF generatoren.

Ah... Det er nu ikke helt korrekt.

Webserveren kan sagtens fungere som proxy uden du kan spore det.

Den kan tage en inputstrem, der bliver genereret på en anden server og sende indholdet råt videre som dens egen outputstream.

Set fra klienten kan du ikke se om bytestreamen er genereret af webserveren eller andetsteds.

34
9. oktober 2020 kl. 13:49

men du kan sagtens serve PDF-requested ved at generere bytestream direkte, uden det rammer disk.

Det har jeg heller ikke sagt man ikke kunne, bare at det merdfører nogle andre implikationer - det er så helt op til hvordan man ellers har skruet sin side sammen hvad der er mest hensigtsmæssigt.

Og husk så lige, at mange som "designer" hjemmesider benytter en række standardværktøjer uden at kere sig så meget om hvordan PDF'er genereres.

Hvis man ser det fra pdf-generatorens side, er "sender direkte tilbage til browseren" ikke forkert :)

Det var "generere på stdout" jeg opponerede over!

Og ret beset behøver man jo ikke nødvendigvis en "webserver", man kunne ramme en applikationsserver direkte...

Tomat-tomat.

33
9. oktober 2020 kl. 13:12

Normalen er så fsva. PDF at der åbnes en ny url, hvor responset er en hel PDF fil - og dette kan altså ikke lige laves ved "at generere en PDF på stdout og sende det direkte til browseren"!

Du kan ikke(*) starte en eller anden baggrundsproces der sender tilbage til browseren når den er klar til det – men du kan sagtens serve PDF-requested ved at generere bytestream direkte, uden det rammer disk. Hvis man ser det fra pdf-generatorens side, er "sender direkte tilbage til browseren" ikke forkert :)

(...) eller ved at webserveren beder en tredjepart om at generere PFD filen on the fly, så det set fra webserverens side fremtræder som en fil (men der skal stadig en selvstændig url til) - men det giver så visse performance problemer som Klaus nævner.

"fremtræder som en fil" er ikke nødvendigt – webserveren ser en URL, og den kan fx reverse-proxyes til PDF generatoren.

Og ret beset behøver man jo ikke nødvendigvis en "webserver", man kunne ramme en applikationsserver direkte...

30
9. oktober 2020 kl. 09:45

Christian Nobel nitpicker vist over at man ikke sender til browseren, men at browseren henter fra serveren...</p>
<p>Hvilket virker lidt fjollet, for naturligvis sender serveren en datastrøm til browseren, selvom det er browseren der initierer request/reply kommunikationen.</p>
<p>Men måske er der en eller anden semantisk grund, som Christian kan uddybe, til hans "Man sender ikke noget til browseren!" udsagn?

Jeg vil faktisk mene at det er ret så vigtigt at være helt klar over at HHTP er stateless og request-response baseret, for al initiativ skal foretages af klienten.

Endvidere skal man holde sig for øje, at det response der kommer er enten i form af en hel side, eller delvist, hvis man skal have noget data inde i en side, eksempelvis vha. et Ajax kald.

Normalen er så fsva. PDF at der åbnes en ny url, hvor responset er en hel PDF fil - og dette kan altså ikke lige laves ved "at generere en PDF på stdout og sende det direkte til browseren"!

Serveren skal lave det der set fra browserens side er en færdig PDF fil, og det kan enten gøres ved at webserveren henter en færdiggenereret fil fra disk (et eller andet sted efter forgodtbefindende, eksempelvis /tmp, og dermed en defineret url), eller ved at webserveren beder en tredjepart om at generere PFD filen on the fly, så det set fra webserverens side fremtræder som en fil (men der skal stadig en selvstændig url til) - men det giver så visse performance problemer som Klaus nævner.

Jeg kan godt se det besnærende i jsPDF som Thor er inde på, men jeg kan være bekymret om hvorvidt kvaliteten er høj nok crossplatform, så i bund og grund er det mest stabile at generere PDF filen, men sørge for at den slettes umiddelbart efter brug, og i hvert fald som følge af et løbende oprydningsjob.

Og så savner jeg stadig svar på det spørgsmål Peter O. Gram stillede, nemlig hvad menes med en usikker webserver.

29
9. oktober 2020 kl. 07:33

Det er rigtig godt, I følger op på dette, V2.

Jeg synes, det er så grel en sag. Man forpligter et meget stort antal unge mennesker til at aflevere deres dybt private helbredsoplysninger til Forsvaret, og så omgås man det med så stor lemfældighed.

Se helbredsskemaet her (7 sider):

https://karriere.forsvaret.dk/globalassets/pdf/helbredssporgsskema-pdf-jul-2020.pdf

Det er meget private oplysninger, der skal afgives. Jeg synes, det er alvorligt.

Er vi i øvrigt sikre på, at denne lemfældighed ”kun” omfatter knapt 46.000 personers intimdata?

Da sagen kom frem, mener jeg, det forlød, at det gjaldt for de aktuelle helbredsskemaer for i år. Men måske husker jeg galt.

46.000 – stemmer det overens med det antal unge mænd, der har været indkaldt til session siden 2014, i løbet af 6 år?

Og er alle data så slettet nu?

28
9. oktober 2020 kl. 01:59

Det er browseren der skal printe ud, så den skal have PDF filen.

Christian Nobel nitpicker vist over at man ikke sender til browseren, men at browseren henter fra serveren...

Hvilket virker lidt fjollet, for naturligvis sender serveren en datastrøm til browseren, selvom det er browseren der initierer request/reply kommunikationen.

Men måske er der en eller anden semantisk grund, som Christian kan uddybe, til hans "Man sender ikke noget til browseren!" udsagn?

24
8. oktober 2020 kl. 17:22

Hvordan vil du lige gøre det?

Uden at gå helt i detaljer, så ville jeg nok udvilkle et javascript til at håndterer indputtet i formularen og så benytte et bibliotek som jsPDF til at genererer selve pdf'en ud fra dataen.

22
8. oktober 2020 kl. 16:08

Eller hvorfor ikke lave en webforular og så generere pdf'en på clientsiden.

21
8. oktober 2020 kl. 15:00

Man sender ikke noget til browseren!

Man genererer en datastrøm og afleverer den i et HTTP response uden at datastrømmen nogensinde har set et filnavn eller en disk (med paging som mulig undtagelse)?

19
8. oktober 2020 kl. 14:20

Det er altså ikke noget problem at trække data fra en database og generere en PDF på stdout og sende det direkte til browseren.

Hvis altså det tool man bruger understøtter denne naturlige mulighed!

18
8. oktober 2020 kl. 14:04

Nu tænker jeg en smule naivt her, men hvis slutproduktet alligevel er en PDF, hvorfor så ikke lade borgeren downloade en forudfyldt PDF formular, som borgeren skal så udfylde med de relevante personlige oplysninger.

Min erfaring med at udfylde en pdf-formular er ikke særligt gode (bruger som regel Ubuntu). Ofte er formateringen af formularen ikke særlig god, eller den tekst man indtaster bliver svær at se fordi den ikke står præcist i feltet, eller fordi feltet ikke udvider sig hvis der er flere linjer.

Indrømmet --- det er efterhånden nogen tid siden jeg har prøvet.

17
8. oktober 2020 kl. 12:45

Nu tænker jeg en smule naivt her, men hvis slutproduktet alligevel er en PDF, hvorfor så ikke lade borgeren downloade en forudfyldt PDF formular, som borgeren skal så udfylde med de relevante personlige oplysninger.

Hvis gjort rigtigt, vil serveren i så fald i worst case indeholde en generisk PDF, som kan ikke tilbageføres til en specifik borger.

Resten af arbejdet med at udfylde formular og udskrivning af PDF foregår på borgerens egen computer.

Det må om noget kunne begrænse skade ved et eventuelt hackerangreb.

16
8. oktober 2020 kl. 12:28

Men jeg kan stadig ikke se at det skulle gøre den store forskel at bruge /tmp i stedet for et andet directory

Jeg har aldrig sagt der var en forskel - jeg skrev netop ovenover at hvis man kører andre services på maskinen bør man bruge et dedikeret til brugeren webservicen kører som, men jeg foreslog bare at de brugte /tmp - da de allerede BURDE have styr på sletning af filer der i :) - og det iøvrigt er standarden i de fleste stykker software der laver den slags temporære filer -at placere dem i /tmp.

Jeg kunne godt forestille mig at de faktisk netop placerede filer i /tmp - og de så bare ikke har det oprydningsscript :)

15
8. oktober 2020 kl. 12:19

øhh? du er klar over at jeg ikke argumenterer for at det er hverken nemt eller en god idé at genere pdf i memory og streame fra memory - men jeg pointerer at det er decideret en skidt idé hvad angår performance

Så udtrykte du dig ikke specielt klart.

For jeg tror faktisk vi er enige om at det performancemæssigt er væsentligt mere krævende at streame end "bare" at levere filen.

Men jeg kan stadig ikke se at det skulle gøre den store forskel at bruge /tmp i stedet for et andet directory, hvis man ellers sørger for der bliver ryddet op - det er da vist en diskussion om kejserens skæg.

14
8. oktober 2020 kl. 12:03

og lige for at pointere det åbenlyse - det job sletter selvfølgelig kun ældre, ikke-åbne filer - så aktiv brug af /tmp ikke generes :)

13
8. oktober 2020 kl. 12:02

Husk nu igen på at vi taler om at der skal kunne udskrives en PDF fil fra en browser, da udskrift pga. browsere's generelle gummisturktur ikke kan gøres direkte af en side.

øhh? du er klar over at jeg ikke argumenterer for at det er hverken nemt eller en god idé at genere pdf i memory og streame fra memory - men jeg pointerer at det er decideret en skidt idé hvad angår performance - (fordi browseren og serveren har et netværk imellem sig - og så vil opgaven optage alt for mange ressourcer på serveren i al den tid det tager den at hente data (hvilket er 99% af tiden en sådan request tager som oftest).

11
8. oktober 2020 kl. 11:57

Så du vil lade www-data have snablen ned i /tmp - det lyder ikke rigtig som en løsning.

Normalt har man en dedikeret web-server der ikke kører andre ting - så JA - det giver god mening. Det er også tendensen med virtualisering/docker at man netop isolerer opgaver - så /tmp alligevel KUN vil blive brugt af www-data :)

Kører man "alt muligt forskelligt" på samme server (gammeltdags, rodet og sikkerhedsmæssigt risikabelt - da angreb på en service så giver adgang til resten) - så vil man typisk lave en dedikeret tmp folder til www-data - men det ændrer ikke rigtigt på det jeg siger.

10
8. oktober 2020 kl. 11:50

Så ville de kunne have gjort som man plejer og standard håndteringen af /tmp (som de forhåbentlig har på plads) ville have løst det for dem. Der ligger også mange andre ting i /tmp - så den skal de have på plads :)

Så du vil lade www-data have snablen ned i /tmp - det lyder ikke rigtig som en løsning.

Derudover vil det ikke ændre på problemet at gøre det på den måde, eller et vilkårligt andet directory, filerne vil blive liggende til de slettes, f.eks. vha. et cronjob.

Kan de omskrive "PDF udskriv" biblioteket (som forhåbentlig/formodentlig er noget Open Source), så den slet ikke behøver at skrive en fil i /tmp er det selvfølgelig fint

Det er ikke nødvendigvis helt trivielt.

men i og med at den største tid vil blive brugt på at levere data (pdf'en) til klienten der skal printe, så vil det være dyrt for performance, ikke at levere den til klienten via en fil (for filer kan leveres af en frontend webserver, så det slet ikke rører den hukommelses og ressource tunge backend, efter PDF'en er generet og leveret til lokal disk.

Husk nu igen på at vi taler om at der skal kunne udskrives en PDF fil fra en browser, da udskrift pga. browsere's generelle gummisturktur ikke kan gøres direkte af en side.

Så enten skal der hentes en fil (PDF) fra en given url, eller også så skal url'en genereres on the fly og bitstreames som en PDF fil, hvilket kan gøres men det er ikke helt trivielt.

9
8. oktober 2020 kl. 11:41

og så ALTID have et automatisk job der rydder temp dagligt, som minimum.

Så ville de kunne have gjort som man plejer og standard håndteringen af /tmp (som de forhåbentlig har på plads) ville have løst det for dem. Der ligger også mange andre ting i /tmp - så den skal de have på plads :)

Kan de omskrive "PDF udskriv" biblioteket (som forhåbentlig/formodentlig er noget Open Source), så den slet ikke behøver at skrive en fil i /tmp er det selvfølgelig fint - men i og med at den største tid vil blive brugt på at levere data (pdf'en) til klienten der skal printe, så vil det være dyrt for performance, ikke at levere den til klienten via en fil (for filer kan leveres af en frontend webserver, så det slet ikke rører den hukommelses og ressource tunge backend, efter PDF'en er generet og leveret til lokal disk.

8
8. oktober 2020 kl. 11:09

I artiklen fremgår det, at data lå på en usikker webserver. Hvordan var/er den usikker, eller er det blot en generel karakteristik af en server, der leverer data til Internettet? Er der i øvrigt nogen indikationer på, at data er blevet lækket? Ikke at jeg skal forsvare det skete, jeg savner blot at tingene bliver proportioneret i forhold til risikoen/skaden.

7
8. oktober 2020 kl. 10:28

Men hvordan vil du tilsikre at browseren kan hente PDF'en specifikt fra en RAM disk?

Ja hvordan sikrer du dig at broeseren henter en specifik file fra en disk?

Der er da ingen forskel fra browseren om den skal hente en url eller en anden, udover at at den skal ha en anden url.

Generatoren skal åbenbart gemme filen et eller anden sted. Det kan da ikke være raketvidenskab at ændre stedet den gemmer filen.

Optimalt burde outputtet pipes direkte til outputet på serveren, så der slet ikke er behov for at cached filen på disk. Men det kan deres system åbenbart ikke klare.

6
8. oktober 2020 kl. 10:21

Om filerne ligger på en disk i 10 sekunder eller 10 år gør ingen forskel. De har ligget et sted hvor de ikke skal ligge, færdig.

Et eller andet sted skal PDF'erne jo ligge, så de kan skrives ud - men problemets kerne er selvfølgelig at de har ligget på en åben webserver.

Men mon ikke rigtig mange løsninger som tilbyder PDF'er til udskrift via browser er bygget op på samme måde?

Jeg har svært ved at se at SSl skulle ændre dette forhold, data er stadig tilgængelige offentligt.

4
8. oktober 2020 kl. 09:59

Om filerne ligger på en disk i 10 sekunder eller 10 år gør ingen forskel. De har ligget et sted hvor de ikke skal ligge, færdig.

Hvad der gør sagen værre er, at data er en del af session. Hvis man ikke møder op bliver man hentet af politiet. Derfor har man ekstra stor forpligtelse til at dette er i orden.

3
8. oktober 2020 kl. 09:14

Men en RAM disk kan sagens leve i flere år!

2
8. oktober 2020 kl. 08:50

Jeg spurgte for et år eller to siden Forsvaret efter hvor længe de opbevarer data fra sessioner for det virker ærlig talt som temmeligt følsomme data på temmeligt mange mænd, og fik kontakt med en fjendtlig dame som i bedste kancellisprog gjorde alt for ikke at svare på spørgsmålet, men henviste til at de fulgte værnepligtsloven og at man ikke kunne få sine data slettet da de opbevarede data som de vurderede at de havde pligt til at opbevare for at kunne opfylde værnepligtsloven.

Jeg kunne så indsende mit personnummer og spørge efter mine egne data for det er de jo pisket til at skulle gøre - men så ville de jo netop blive databehandlet! Hun ville ikke svare på noget generelt.

Baseret på det skulle det ikke undre mig om mine egne data på et tidspunkt bliver hacket og lækket.

1
8. oktober 2020 kl. 07:44

hvis det rører disken er det svært at slippe af med. ideelt bør det foregå i applikationens hukommelse (via PDF library der renderer og sender til printer). Men man kunne til nód ogaå bruge en RAM disk hvis det ikke kan lade sig gøre fordi det skal over browseren. Print spooler til disk skal slås fra eller sættes til RAM disk. Swapper filen skal også disables.