Analýza úniků zdravotnických dat v USA: přibývá vzdálených útoků po síti

1. 12. 2018 21:53 (aktualizováno) Petr Kajzar

Před pár dny vyšel v americkém časopise Journal of Americal Medical Association (JAMA) třístránkový článek analyzující dostupné statistiky úniků dat ve zdravotnictví v USA. Celkem očekávatelně a logicky se ukazuje, že klesá počet úniků způsobených ztrátou či krádeží fyzického zařízení (počítače, flashky) či zcizením papírových záznamů a naopak stoupá počet úniků elektronických dat způsobených vzdáleným přístupem k serveru či e-mailové schránce.

Autoři Thomas H. McCoy Jr. a Roy H. Perlis využili systém povinného hlášení úniků dat ve zdravotnictví. Do něj musí ze zákona každý poskytovatel zdravotních služeb nebo firma operující se zdravotnickými údaji v USA hlásit každý únik nebo ohrožení citlivých dat pacientů, pokud se incident týká dat více než 500 lidí. Pokud jde tedy o únik menšího množství dat, incident se nehlásí.

Minimum uniklých záznamů je tedy 500, maximum je neuvěřitelných 78,8 milionů záznamů, o čemž jsem se onehdy zmiňoval v článku zde na Rootu. Medián pacientských záznamů zcizených při jednom incidentu je 2300.

Nejčastěji data unikla poskytovatelům zdravotních služeb (healthcare provider). Nejčastěji napadená zařízení bývaly laptopy nebo papírové záznamy (v roce 2010), avšak postupně byly na předních pozicích v počtu úniků dat vystřídány servery a e-mailem (v roce 2017). S tím souvisí posun od fyzických krádeží k hackerským útokům a neautorizovaným přístupům.

Otevřená analýza

Celá analýza je vlastně jednoduchá, nicméně i tak poskytuje velmi příjemný přehled o tom, co se ve zdravotnictví na poli bezpečnosti dat děje.

Pokud jste ovšem využili základní funkce hypertextového značkovacího jazyka a klikli jste na první hypertextový odkaz směřující na originální článek v uvedeném časopise, pak jste nejspíš narazili na jeho smutnou zbytečnost. Pokud totiž nemáte akademickou půdu pod nohama, pak nejspíš k textu tohoto krátkého článku nemáte přístup. U opravdových výzkumů nebo esejí to chápu, ale tohle je zběžná analýza otevřených dat a je to ohromná škoda – informační hodnota je hezká a grafy vydají za tisíce slov. Jenže koupě samostatného článku stojí $30, půjčení na 24 hodin $9.

Když už jsou daná surová data ze systému hlášení poskytována otevřeně, dovolte mi, abych nesměle podobnou analýzu provedl s otevřenějšími kartami v otevřenějším prostředí R. Ukážu vám tak alespoň ony tři grafy, které článek v JAMA obsahuje. Získáte tak lepší představu o tom, jaký je vývoji bezpečnosti dat ve zdravotnictví.

Nejsem žádný odborník, spíše si s eRkem jen tak hraju, proto se předem omlouvám pokročilejším uživatelům za nepříliš pohledný kód. :-)

Získání dat

Jak jsem psal výše, systém hlášení U.S. Department of Health and Human Services, Office for Civil Rights poskytuje data otevřeně na svém webu Breach Portal. Data si tedy stáhneme odtamtud.

Data jsou rozdělena do dvou sekcí: Under Investigation, tedy případy mladší než 24 měsíců, které jsou ve stadiu vyšetřování, a Archive, tj. archiv starších a uzavřených případů. Data si musíme stáhnout z obou z nich (web umožňuje export do CSV – viz červená šipka) a poté je přímo v prostředí R spojíme do jednoho datasetu.Screenshot webu Breach Portal

Načtení balíčků a dat

Na začátku si načtu potřebné balíčky a data. Mám z exportu dva soubory CSV, které nakonec spojím do jednoho datasetu.

library(tidyverse)
library(splitstackshape)

archive <- read_csv("archive.csv")
investigation <- read_csv("investigation.csv")

# sjednotime oba datasety
breaches <- rbind(archive,
                  investigation)

Dataset má nyní 2164 záznamů (hlášení) s 9 proměnnými:

  • Name of Covered Entity - jméno subjektu, který zaznamenal incident,
  • State - stát USA,
  • Covered Entity Type - typ subjektu, může jít o Health Plan, Healthcare Provider, Healthcare Clearing House či Business Associate,
  • Individuals Affected - počet uniklých záznamů (počet pacientů/klientů, kterých se incident dotýká),
  • Breach Submission Date - datum hlášení incidentu,
  • Type of Breach - typ úniku dat, může jít o: Hacking/IT Incident, Improper Disposal, Loss, Theft, Unauthorized Access/Disclosure, Unknown, Other; přičemž každý incident může spadat do více uvedených kategorií,
  • Location of Breached Information - jakého média se incident týká, může jít o Desktop Computer, Electronic Medical Record, Email, Laptop, Network Server, Other Portable Electronic Device, Paper/Films, Other; přičemž opět každý incident může postihnout více médií najednou,
  • Business Associate Present,
  • Web Description.

Samozřejmě si chci zobrazit takovou tu statistiku o počtu poškozených klientů za jeden incident:

breaches %>%
    select(`Individuals Affected`) %>%
    summary()
Individuals Affected
Min. 1st Qu. Median Mean 3rd Qu. Max.
500 980 2 300 120 810 7 727 78 800 000

Základní úprava dat

Autoři originálního článku vytvořili grafy s počty incidentů (tj. počet úniků, nikoli počet postižených klientů či pacientů!) za daný rok. Nebudu se v tom rýpat a použiji stejný postup.

Převedu tedy sloupec Breach Submission Date na pouhý rok a z něj vyberu jen roky 2010–2017 (data se sbírají od roku 2009 dosud, ale rok 2009 a 2018 nejsou ve statistikách kompletní).

breaches$`Breach Submission Date` <- as.numeric(
                                         format(
                                             as.Date(x      = breaches$`Breach Submission Date`,
                                                     format = "%m/%d/%Y"),
                                             "%Y"))

breaches <- breaches %>%
                filter(`Breach Submission Date` > 2009 & `Breach Submission Date` < 2018)

Zpracování dat pro grafy

V originálním článku jsou tři grafy: vývoj počtu incidentů v letech 2010 až 2017 rozdělený podle:

  • typu organizace, tedy Covered Entity Type, přičemž ale vynechali Healthcare Clearing House, která se v hlášeních prakticky neobjevuje (má jen 4 incidenty) a v dnešní době se již nepoužívá (jde o organizace transformující data, vyměňovaná mezi různými poskytovateli, do standardních formátů),
  • typu média, tedy Location of Breached Information, ale s ohledem na to, že každý incident se může týkat více médií, tak každý únik započítali pro každé zmíněné médium; např. únik dat 500 klientů týkající se laptopů a e-mailů znamená, že autoři článku připočetli 500 klientů pod laptopy i pod e-maily,
  • typu úniku, tedy Type of Breach, přitom i zde platí, že každý únik může být zakategorizován do více skupin, proto autoři přičítali klienty ke každé skupině uvedené v hlášení.

Na tyhle tři grafy si proto připravím data. Kategorie jako Other, Unknown a další autoři originálního článku vyřadili – proto to tak udělám i já, i když by se s těmi daty dalo pracovat lépe.

Autoři článku ještě vytvářeli tabulky s kumulativním součtem poškozených klientů, což v eRku není problém, ale zase nechci z tohohle blogového příspěvku dělat pirátskou otevřenou kopii článku… rozumíte. :-)

# data pro graf uniku podle HIPAA entit
entities <- breaches %>%
                drop_na(`Covered Entity Type`) %>%
                filter(`Covered Entity Type` != "Healthcare Clearing House") %>%
                group_by(`Breach Submission Date`, `Covered Entity Type`) %>%
                count()

# data pro graf uniku podle postizeneho media,
# sloupec ale obsahuje u nekterych pozorovani vice moznosti
# oddelenych carkou - proto je rozdelim a zkopiruju cele radky
# pomoci funkce cSplit z balicku splitstackshape
location <- breaches %>%
                cSplit(splitCols = "Location of Breached Information",
                       direction = "long") %>%
                drop_na(`Location of Breached Information`) %>%
                filter(!(`Location of Breached Information` %in% c("Other", "Unknown", "Other Portable Electronic Device"))) %>%
                group_by(`Breach Submission Date`, `Location of Breached Information`) %>%
                count()

# data pro graf uniku podle mechanismu uniku dat,
# sloupec ale obsahuje u nekterych pozorovani vice moznosti
# oddelenych carkou - proto je rozdelim a zkopiruju cele radky
# pomoci funkce cSplit z balicku splitstackshape
breach.type <- breaches %>%
                cSplit(splitCols = "Type of Breach",
                       direction = "long") %>%
                drop_na(`Type of Breach`) %>%
                filter(!(`Type of Breach` %in% c("Other", "Unknown"))) %>%
                group_by(`Breach Submission Date`, `Type of Breach`) %>%
                count()

Grafy

Tak jsme zdárně dospěli ke kýženým grafům. Vlastně si nechám jen zobrazit data, která jsem si vypreparoval v předchozí sekci. Přidám nějaké ty popisky a barvičky a je to.

# graf uniku podle HIPAA entit
ggplot(entities,
       aes(x     = `Breach Submission Date`,
           y     = n,
           group = `Covered Entity Type`,
           col   = `Covered Entity Type`)) +
    labs(x      = "Rok",
         y      = "Pocet nahlasenych incidentu",
         title  = "Pocet nahlasenych incidentu u ruznych typu organizaci",
         colour = "Organizace") +
    geom_line() +
    geom_point()

# graf uniku podle postizeneho media
ggplot(location,
       aes(x     = `Breach Submission Date`,
           y     = n,
           group = `Location of Breached Information`,
           col   = `Location of Breached Information`)) +
    labs(x      = "Rok",
         y      = "Pocet nahlasenych incidentu",
         title  = "Pocet nahlasenych incidentu u ruznych typu medii",
         colour = "Typ media") +
    geom_line() +
    geom_point()

# graf uniku podle mechanismu uniku dat
ggplot(breach.type,
       aes(x     = `Breach Submission Date`,
           y     = n,
           group = `Type of Breach`,
           col   = `Type of Breach`)) +
    labs(x      = "Rok",
         y      = "Pocet nahlasenych incidentu",
         title  = "Pocet nahlasenych incidentu podle typu uniku dat",
         colour = "Typ uniku dat") +
    geom_line() +
    geom_point()

Grafy úniků dat v USA v letech 2010-2017

Grafy úniků dat v USA v letech 2010-2017

Grafy úniků dat v USA v letech 2010-2017

Závěr

Vidíte, že i s otevřenými nástroji si můžeme udělat analýzu otevřených dat. Samozřejmě autoři poskytli i hezký text a nějaké další tabulky.

Ale hlavně: důležitější je zpráva, kterou tahle data nesou mezi řádky. Pokud budou data z elektronické zdravotní dokumentace unikat ven, tak se budou pacienti i v budoucnu zuby nehty bránit elektronickému ukládání dat nebo nedejbože nějakému sdílení dat mezi poskytovateli. Přitom jde o záležitosti, které dokáží poskytovanou zdravotní péči (při správném použití) velmi zrychlit a zkvalitnit!

Existují dokonce práce, které zmiňují ještě jeden nebezpečný fakt: pacienti, kteří se bojí úniku citlivých dat, tato data raději vůbec lékařům nesdělují (nebo žádají, aby v dokumentaci zadána nebyla). Dovedete si asi sami představit, že jde hlavně o psychická onemocnění, zneužívání návykových látek, infekce HIV, některé genetické vady apod.  Veškeré zatajování, nesdílení a neposkytování údajů má ale v medicíně dopad na kvalitu poskytované péče tomu danému konkrétnímu pacientovi.

Není to ale chyba pacienta, že se bojí zneužití svých citlivých dat. Musíme zkrátka na zabezpečení dat pacientů i klientů neustále pracovat.

Použitá literatura

  • McCoy TH, Perlis RH. Temporal Trends and Characteristics of Reportable Health Data Breaches, 2010–2017. JAMA. 2018;320(12):1282–1284. doi:10.1001/jama.2018.9222
  • Blumenthal D, McGraw D. Keeping Personal Health Information SafeThe Importance of Good Data Hygiene. JAMA. 2015;313(14):1424. doi:10.1001/jama.2015.2746

Použitý software

Sdílet