Driftshemmelighed
en nøgle eller adgangskode, et program skal bruge
Hvad det er
En driftshemmelighed er en værdi, der lader software, eller den person, der driver den, handle på et system, og som giver enhver anden, der læser den, den samme magt. Adgangskoden til en databaseforbindelse, et API-token, den private halvdel af et SSH-nøglepar og den adgangsfrase, der krypterer en backup, er alle driftshemmeligheder. Til daglig siger man bare hemmeligheder, eller secrets på engelsk, og arbejdet med at oprette, opbevare, rotere og destruere dem kaldes secrets management.
To ting adskiller dem fra koden omkring dem. Den første er læseren. En brugers adgangskode sidder i et menneskes hukommelse og tastes ved en prompt, mens en driftshemmelighed læses af et program, et udrulningsscript eller et planlagt job, og ingen behøver at huske den. OWASP’s Secrets Management Cheat Sheet giver den derfor sin egen livscyklus: oprettet med de mindste rettigheder, den har brug for, roteret efter en plan, tilbagekaldt, når den kan være lækket, og sat til at udløbe, hvor platformen tillader det, med levetider fra minutter til år. Brugeres adgangskoder står uden for den faste rotation. Den anden er grænsen mellem en hemmelighed og den konfiguration, der peger på den. Et værtsnavn eller stien til et backuplager siger, hvor noget er. Hemmeligheden er den del, der lukker indehaveren ind, og den del, hvis kopier skal tælles.
Hemmeligheder ligger også i lag. Det lager, der rummer dem, har brug for sin egen hemmelighed, og cheat sheetet bemærker, at den primære hemmelighed, for eksempel en cloududbyders root-adgangsoplysninger, som regel må opbevares et andet sted.
Hvorfor det betyder noget
En hemmelighed virker for den, der viser den frem. Et token bærer ingen oplysning om, hvem der skulle have det, så hver kopi udvider kredsen af mennesker og programmer, der kan bruge det. Et repository med kildekode er det værste sted, en kan havne: hver klon bærer hele historikken, så en værdi, der er committet én gang, rejser ud til hver laptop, hver build-runner og hvert spejl, der henter, og den bliver i historikken, efter at linjen med den er slettet.
Standarderne gør det til krav. OWASP Application Security Verification Standard beder om en løsning til hemmelighedshåndtering, for eksempel en key vault, der opretter, opbevarer, styrer adgangen til og destruerer backend-hemmeligheder, og fastslår, at hemmeligheder ikke må indgå i applikationens kildekode eller i byggeartefakter. Den beder om mindste rettigheder for adgangen til dem og på sit højeste niveau om, at de udløber og roteres. NIST SP 800-53 tilføjer kontroludvidelsen IA-5(7): ukrypterede statiske autentifikatorer må ikke indlejres i applikationer eller andet statisk lager. Vejledningen lukker også et smuthul, for en værdi, der bruges præcis, som den er gemt, regnes for ukrypteret, uanset hvilken fil den ligger i.
Afvejningerne er reelle. Et centralt lager er endnu et system, der skal være oppe, når der er mest brug for det, og cheat sheetet påpeger, at folk under en hændelse forventer hurtigt at få nye adgangsoplysninger. At dele én hemmelighed mellem flere tjenester sparer arbejde og koster sporbarhed, for efter et læk er der ingen måde at se, hvilken indehaver der mistede den. Manuel håndtering vokser med hver hemmelighed, og derfor foretrækker cheat sheetet automatisk rotation og advarer om, at en genstart af programmet lader en stjålet adgangsoplysning virke videre. Kun en tilbagekaldelse stopper den.
Sådan ser det ud i praksis
Sitet skriver sin regel på siden om, hvordan virksomheden arbejder sikkert: hemmeligheder holdes ude af kodebasen. Adgangsoplysninger ligger i en hemmelighedstjeneste eller i udrulningslaget, uden for kildekoden og uden for alt, et build producerer, og en automatisk scanning kører ved hvert commit og standser committet, når den gør et fund.
Udviklingsnoterne for kodebasen udfylder resten. Scanneren er gitleaks, som kører over arbejdstræet ved hvert commit og igen i det fulde kvalitetstjek, og et fund er et hårdt stop, som ingen skal snige sig forbi med en undtagelse. Mappen med afhængigheder og de genererede output-træer er undtaget, fordi de er kopier, der bygges forfra. Noterne beskriver også en stille fejl: når en fil forsvinder midt i scanningen, skriver gitleaks en fejllinje og afslutter alligevel med succes, så den opgave, der kører scanneren, fejler på enhver fejllinje. Selve sitet er statisk og har ingen applikationshemmeligheder, og det udrulles over SSH med nøgler, som ejeren har.
Når hemmeligheder holdes ude af kodebasen, flytter de et sted hen, som kodebasens tjek ikke når, og et preflight-play for hemmeligheder tager sig af det hul. Driftshemmelighederne var lige blevet delt op pr. vært, og koden var korrekt, men operatørens krypterede vault, der bor på operatørens egen maskine og uden for kvalitetsgatens synsfelt, rummede stadig den gamle værdi fra tiden med én vært. Det første converge nåede den levende vært, kørte otte tasks og afviste på den niende, efter at det allerede havde skrevet swap-indstillinger til produktion. Svaret blev et play, der hverken kontakter en vært eller indsamler facts, men kører de samme to task-filer som det rigtige converge mod vaulten, på omkring et sekund og før provisioneringen gør noget andet. Når koden genbruges i stedet for at reglen gentages, kan tjekket og converge-kørslen ikke glide fra hinanden. En forkert hemmelighed koster nu en afvisning på to sekunder på en laptop.
Selve opdelingen er skiftet til én værdi pr. vært for hver driftshemmelighed. Platformen havde én vært og skulle snart have to, og flere hemmeligheder var skrevet som enkeltværdier, blandt dem backup-repositoriet, dets adgangsfrase og en alarmswitch. Hver blev en tabel med inventarets værtsnavn som nøgle, og to begrundelser står ved siden af konfigurationen. En dead man’s switch, som to værter deler, forbliver grøn, så længe den ene stadig melder sig, så den anden vært skjuler, at den første er død. Og fordi adgangsfrasen udgør hele backuppens kryptering, har to værter, der deler den, ét lager mellem sig, uanset hvad stierne siger. Den eksisterende vært står i alle fire tabeller med sit lager og begge switches uden værdi, og det siger, at koblingen findes, mens operatøren stadig skal levere værdien.
Hvor det går galt
En hemmelighed havner i et commit. En scanner markerer en værdi i en diff, eller nogen opdager et token i en pushet fil, fordi det lå i en konfigurationsfil eller en testfixture, da committet blev lavet. OWASP’s cheat sheet giver rækkefølgen for oprydningen: tilbagekald den lækkede værdi først, roter den så, og fjern den først derefter fra koden eller loggene. At omskrive historikken for at fjerne committet ændrer alle senere commits og bryder links til dem, så det kræver planlægning. Opdagelsen hører hjemme før committet, i en pre-commit-hook eller i editoren, hvor et fund intet koster.
Scanningen går hen over filer, den aldrig læste. En kørsel ender grøn, mens en del af træet aldrig blev undersøgt: en fil forsvandt undervejs, en undtagelse blev for bred, eller hemmeligheden har ingen genkendelig form. Mønsterregler fanger tokens med et fast format og overser en adgangskode, et menneske har fundet på, og derfor foreslår cheat sheetet mere end ét værktøj. Behandl enhver fejl fra scanneren som en fejlet kørsel, og begræns undtagelserne til kopier, som et build genskaber.
Én hemmelighed har mange indehavere. To værter, to tjenester eller et helt team bruger den samme værdi. Når den lækker, kan loggene ikke sige, hvilken kopi der slap ud, og en udskiftning kræver, at alle indehavere røres på én gang. SP 800-53 beder om, at autentifikatorer til gruppe- og rollekonti skiftes, hver gang medlemskabet ændrer sig, og med én hemmelighed pr. indehaver bliver det én udskiftning i stedet for en koordineret.
Hemmeligheden følger med buildet eller havner i en log. Et container-image, et bundtet script eller en debuglinje bærer værdien ud af det sted, den skulle blive. ASVS nævner byggeartefakter ved siden af kildekode, og cheat sheetet beder om, at hemmeligheder holdes ude af logge og maskeres, hvor en linje er nødt til at henvise til en. Scan det, buildet producerer, og ikke kun kodebasen.
Læs mere
- OWASP Secrets Management Cheat Sheet — en hemmeligheds livscyklus, opdagelse før committet og rækkefølgen for oprydning efter et læk.
- OWASP Application Security Verification Standard — kravene til hemmelighedshåndtering i gruppe 13.3: en vault, mindste rettigheder og rotation.
- NIST SP 800-53 Rev. 5 — håndtering af autentifikatorer i IA-5, med IA-5(7) mod indlejrede statiske autentifikatorer.
- Gitleaks — den scanner, sitet kører over sit arbejdstræ ved hvert commit.