# Privilegium

## Hvad det er

Et privilegium er lov til at gøre noget, som et system ellers forbyder, og det
tilhører en person eller et kørende program, fordi en myndighed har besluttet
det: at læse andre brugeres filer, at lytte på en port under 1024, at oprette
konti eller at kalde en databasefunktion. I praksis taler man oftest om
privilegier i flertal, fordi en bruger sjældent har kun ét, og om »privilegerede«
og »uprivilegerede« konti og processer for at sige, hvilken side af grænsen de
står på. NIST's ordliste tilføjer den del, der er nem at glemme: privilegier
beskriver, hvad et subjekt har tilladelse til, og de fastlægges af en myndighed
og skrives ned i en politik eller i regler.

Ordet står tæt på to andre. Adgangskontrol er selve afgørelsen af hver
anmodning, og et privilegium er en af de oplysninger om den, der spørger, som
afgørelsen slår op i. En tilladelse er som regel det samme set fra ressourcens
side: filen siger, hvem der må læse den, og læseren har retten til det.

På Linux har ordet en præcis betydning. Manualsiden capabilities(7) beskriver den
klassiske Unix-opdeling: privilegerede processer, hvis effektive bruger-id er 0,
og som kaldes root, går uden om alle kernens tjek af tilladelser, mens alle andre
processer bliver tjekket mod deres legitimationsoplysninger. Siden Linux 2.2 har
kernen delt roots magt op i separate enheder, kaldet capabilities, som kan slås
til og fra hver for sig. Et program, der kun skal lytte på en lav port, kan
derfor få `CAP_NET_BIND_SERVICE` og intet andet. Siden credentials(7) forklarer,
hvis identitet der bliver tjekket: det reelle bruger-id siger, hvem der ejer
processen, det effektive bruger-id er det, kernen sammenligner med
tilladelserne, og det gemte set-user-ID lader et program lægge en hævet identitet
fra sig og tage den op igen senere.

Databaser og organisationer bruger samme ord om deres egne tildelinger. En
databaserolle har privilegier på skemaer, tabeller og funktioner, og en
administratorkonto har privilegier, som en almindelig medarbejderkonto ikke har.
Tanken er den samme på alle niveauer: en ret, givet med vilje, til at krydse en
grænse, der ellers er lukket.

## Hvorfor det betyder noget

De privilegier, et program har, bestemmer, hvor stor skaden bliver, den dag noget
går i stykker. Det er det erklærede formål med capabilities: et kompromitteret
program gør mindre skade med et smalt sæt rettigheder end det samme program,
der kører som root. En webserver med en fejl, der tillader kodekørsel, og med
root-rettigheder giver hele maskinen til den, der fandt fejlen. Den samme fejl i
en proces, der kun kan læse sin egen mappe og lytte på én port, når meget kort.

NIST kalder princippet mindste privilegium. Kontrol AC-6 i SP 800-53 beder en
organisation om kun at tillade de adgange, som brugere og de processer, der
handler på deres vegne, har brug for til deres opgaver. Udvidelserne gør det til
daglig rutine: administratorer bruger en almindelig konto til hverdagsopgaver som
mail, privilegerede konti forbeholdes dem, der har brug for dem, brugen af
privilegerede funktioner logges, og privilegier gennemgås og fjernes, når
behovet ikke længere kan dokumenteres.

Standardindstillingerne begynder sjældent der. I systemd kører en systemtjeneste
uden en `User=`-linje som root, og `NoNewPrivileges=`, indstillingen, der
forhindrer en tjeneste og dens underprocesser i at få flere rettigheder via
`execve()`, er slået fra, indtil nogen slår den til. Databaseværktøjer forbinder
ofte som ejer af alle tabeller, fordi det var sådan, skemaet blev oprettet. Nye
medarbejdere bliver ofte kopieret fra en kollegas konto med alle rettigheder.
Hver standard er bekvem den første dag og dyr den dag, nogen bryder ind.

Afvejningen er reel. Det tager tid at indsnævre privilegier, fordi nogen skal
finde ud af, hvad et program faktisk gør, og et sæt, der er for smalt, går i
stykker under kørslen og ikke ved installationen. Beslutningen handler som regel
om, hvor tiden skal bruges først: på alt, der vender ud mod internettet, på alt,
der rummer data, folk vil savne, og på de konti, der kan ændre andre konti. For en
køber eller en revisor er det nyttige spørgsmål enkelt: hvem og hvad har
administratorrettigheder her, og hvorfor?

## Sådan ser det ud i praksis

Tretten unit-filer på virksomhedens egen server
[kørte med de privilegier, som supervisoren giver som standard](/da/portfolio/cut-systemd-sandbox-exposure-across-every-unit-119/),
og det er de fleste. Hver unit-skabelon fik et privilegieloft fastsat til
unittens eget, et filter for systemkald, begrænsede adressefamilier og
hukommelse, der kan være skrivbar eller eksekverbar, men aldrig begge dele.
Hardening-scoren for dødmandsknappen faldt fra 9,6 til 1,5, git-forgen fra 8,3
til 1,5 og de to backup-units fra 9,6 til 2,3 og 2,5. Et direktiv viste sig at
være stavet forkert i tre skabeloner, og supervisoren havde logget en ukendt
nøgle og startet unitten alligevel. Derfor kører hver unit nu gennem
supervisorens egen verifikator ved hver konvergering. Siden skriver også, hvad scoren
lader ude: et direktiv, der ødelægger en unit, gør det under kørslen.

På en applikationsplatform
[logger API'et ind i databasen som en rolle med mindste privilegium](/da/portfolio/hardened-the-application-with-nonce-based-csp-hsts-77/),
der kun kan køre EXECUTE på applikationens funktioner, som kører som SECURITY
DEFINER med parametriserede databaseforespørgsler. Rettigheder som
abonnementsniveau, rolle, organisation og skibstilknytning tjekkes igen på
serveren ved hver anmodning, og spærringerne i brugerfladen regnes kun for UX.

I en hel organisation blev
[identiteter og adgange samlet på tværs af M365, 1Password, Red Hat SSO og OKTA SSO](/da/portfolio/prevented-security-breaches-by-leading-access-management-initiatives-21/),
mindste privilegium blev håndhævet, og on- og offboarding blev standardiseret,
så adgang blev trukket tilbage med det samme i stedet for at blive hængende, når
nogen skiftede job.

## Hvor det går galt

**En tjeneste kører som root, fordi dens unit er tavs om brugeren.**
Supervisorens standard for en systemtjeneste er root, så en unit uden en
`User=`-linje har alle maskinens privilegier. Giv hver tjeneste sin egen bruger,
eller lad systemd tildele en med `DynamicUser=`, som opretter en bruger, når
unitten starter, og frigiver den, når den stopper.

**Én capability viser sig at være det meste af root.** `CAP_SYS_ADMIN` dækker så
mange operationer, at dens egen manual kalder den overlæsset og »the new root«.
Et team, der giver den for at låse én funktion op, har givet det meste af root.
Find den specifikke capability, programmet har brug for, og hold bounding-sættet
til den liste:

```ini
[Service]
User=web
NoNewPrivileges=yes
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_BIND_SERVICE
```

De indstillinger lader en tjeneste, der kører som almindelig bruger, lytte på
port 80, og alle andre capabilities fjernes fra dens bounding-sæt.

**En proces kravler op over sit udgangspunkt.** Et program, der kører som
almindelig bruger, kan stadig køre en set-user-ID-fil eller en fil med
capabilities tilknyttet, og så hæver kernen dens privilegier under kørslen.
Forsvarere genkender det som en proces, hvis effektive bruger-id er et andet end
det reelle. `NoNewPrivileges=yes` lukker den vej for en tjeneste og alle de
processer, den starter.

**Rettigheder hober sig op, når folk skifter job.** En medarbejder skifter team
og beholder den gamle adgang ved siden af den nye, og efter nogle år rummer
kontoen summen af alle de roller, personen nogensinde har haft. AC-6 svarer med
periodisk gennemgang og AC-2 med kontostyring, der er knyttet til flytninger og
fratrædelser, så et nyt job også betyder ny adgang.

**Applikationens eget login kan alt.** Når et API forbinder som ejer af
skemaet, når en enkelt injektionsfejl alle tabeller. En login-rolle, der kun kan
kalde de funktioner, applikationen bruger, gør den samme fejl til et langt
mindre problem.

## Læs mere

- [Privilege i NIST CSRC's ordliste](https://csrc.nist.gov/glossary/term/privilege)
  — definitionen fra CNSSI 4009, med noten om, at en myndighed fastlægger
  privilegier.
- [capabilities(7)](https://man7.org/linux/man-pages/man7/capabilities.7.html)
  — hvordan Linux deler root op i capabilities, og hvordan tråde bærer dem.
- [credentials(7)](https://man7.org/linux/man-pages/man7/credentials.7.html)
  — reelle, effektive, gemte og filsystem-bruger-id'er, og hvad hvert af dem
  afgør.
- [systemd.exec(5)](https://man7.org/linux/man-pages/man5/systemd.exec.5.html)
  — `User=`, `DynamicUser=`, `NoNewPrivileges=` og indstillingerne for
  capabilities.
- [NIST SP 800-53 Rev. 5](https://csrc.nist.gov/pubs/sp/800/53/r5/upd1/final)
  — kontrol AC-6, mindste privilegium, og udvidelserne, der gør det til rutine.

<https://engineer.company/da/glossary/privilege/>
