Sikre SQL Server: Pålogging, roller, kryptering og SQL-injeksjon

Databasen er der de verdifulle dataene ligger: kunderegistre, lønn, helseopplysninger og forretningshemmeligheter. Likevel er det fortsatt vanlig å finne SQL Server-instanser der applikasjonen logger inn som sa, der port 1433 er åpen mot internett, og der backupene ligger ukryptert på en filshare alle kan lese. Denne guiden går gjennom hvordan du sikrer SQL Server lag for lag: hvem som får logge inn, hva de får gjøre, hvordan data beskyttes underveis og på disk, og hvordan du stenger døren for SQL-injeksjon.

Kort fortalt
  • Bruk Windows-autentisering (eller Microsoft Entra ID) der det er mulig, og deaktiver sa.
  • Gi applikasjoner og brukere minst mulig tilgang – aldri sysadmin eller db_owner for en applikasjon.
  • Krypter trafikken med TLS og et gyldig sertifikat, og ikke eksponer SQL Server mot internett.
  • Bruk TDE eller kryptert backup for data på disk, og Always Encrypted for spesielt sensitive kolonner.
  • Bruk alltid parameteriserte spørringer. SQL-injeksjon er fortsatt en av de vanligste angrepsvektorene.

Pålogging: hvem slipper inn?

Windows-autentisering og SQL-pålogginger

SQL Server støtter to typer pålogging:

  • Windows-autentisering: Brukeren eller tjenesten logger inn med sin Windows- eller domenekonto via Kerberos eller NTLM. Passord, passordregler og sperring av kontoer håndteres i Active Directory, og ingen passord lagres i applikasjonens konfigurasjon.
  • SQL Server-autentisering: Brukernavn og passord lagret i SQL Server. Nødvendig for klienter som ikke er i domenet, men passordene må forvaltes og ligger ofte i klartekst i konfigurasjonsfiler.

Velg Windows-autentisering der du kan. En applikasjon som kjører i IIS kan logge inn som app pool-identiteten eller som en group Managed Service Account (gMSA), og connection stringen trenger da ikke passord: Server=sql01;Database=Salg;Trusted_Connection=True;. Fra SQL Server 2022 kan du også bruke Microsoft Entra ID (tidligere Azure AD) for lokale servere, via Azure Arc.

Ta hånd om sa

sa er et kjent kontonavn med full tilgang, og det første angripere prøver. Hvis du må ha Mixed Mode, deaktiver kontoen eller gi den et langt, tilfeldig passord som ingen bruker:

ALTER LOGIN sa DISABLE;

Slå også på logging av mislykkede pålogginger (i SSMS: serverens egenskaper, Security, Login auditing), eller bruk SQL Server Audit som beskrevet under. Mange mislykkede pålogginger på sa i feilloggen er et tydelig tegn på at noen prøver seg.

Pålogging og bruker er ikke det samme

SQL Server skiller mellom to nivåer:

  • En pålogging (login) finnes på servernivå og gir tilgang til instansen.
  • En bruker (user) finnes i hver database og knyttes til en pålogging. Det er brukeren som får rettigheter til tabeller og prosedyrer.

Når du gjenoppretter en database på en annen server, følger brukerne med, men SQL-påloggingene gjør det ikke. Brukerne blir «foreldreløse» (orphaned) fordi sikkerhetsidentifikatoren ikke matcher. Rett det med:

ALTER USER AppBruker WITH LOGIN = AppBruker;

Med contained database users lagres autentiseringen i selve databasen, og problemet forsvinner. Det er spesielt nyttig med availability groups.

Autorisasjon: minst mulig tilgang

Prinsippet om minste privilegium betyr at hver pålogging bare får de rettighetene den trenger. En applikasjon som har db_owner eller sysadmin, gir en angriper som finner en svakhet i applikasjonen, full kontroll over databasen – eller serveren.

Serverroller

sysadmin kan gjøre alt, inkludert å kjøre kommandoer i operativsystemet. Medlemskapet bør være begrenset til en AD-gruppe med databaseadministratorer. Sjekk hvem som har det:

SELECT p.name, p.type_desc
FROM sys.server_role_members AS rm
JOIN sys.server_principals AS r ON r.principal_id = rm.role_principal_id
JOIN sys.server_principals AS p ON p.principal_id = rm.member_principal_id
WHERE r.name = 'sysadmin';

Databaseroller og egne roller

De faste rollene db_datareader og db_datawriter gir lese- og skrivetilgang til alle tabeller. Det er enkelt, men ofte for bredt. Bedre er egne roller med rettigheter på skjemaer eller prosedyrer:

CREATE ROLE AppRolle;

-- Tilgang til alt i skjemaet app, men ingenting i skjemaet admin
GRANT SELECT, INSERT, UPDATE, DELETE ON SCHEMA::app TO AppRolle;
GRANT EXECUTE ON SCHEMA::app TO AppRolle;

CREATE USER [DOMENE\web01$] FOR LOGIN [DOMENE\web01$];
ALTER ROLE AppRolle ADD MEMBER [DOMENE\web01$];

Applikasjoner som bruker EF Core med migreringer, trenger rettigheter til å endre skjemaet bare når migreringene kjøres. Kjør dem fra deploy-pipelinen med en egen, mer privilegert konto, og la applikasjonen selv kjøre med en konto som bare kan lese og skrive data.

Radnivåsikkerhet og datamaskering

  • Row-Level Security filtrerer automatisk hvilke rader en bruker ser, for eksempel bare sin egen avdelings ordrer. Filteret håndheves av databasen, uansett hvordan spørringen er skrevet.
  • Dynamic Data Masking maskerer verdier som fødselsnummer eller e-post i spørringsresultater for brukere uten UNMASK-rettighet. Det er et praktisk hjelpemiddel, men ikke en sikkerhetsgrense: en bruker med lesetilgang kan ofte utlede de maskerte verdiene med lure WHERE-betingelser.

Nettverket

Ikke eksponer SQL Server mot internett

Port 1433 åpen mot internett blir funnet i løpet av minutter og utsatt for automatiserte passordangrep døgnet rundt. SQL Server skal bare være tilgjengelig fra applikasjonsserverne og administratorenes maskiner. Bruk brannmur, nettverkssegmentering og VPN eller en «jump host» for administrasjon.

Krypter trafikken med TLS

Uten kryptering går spørringer og resultater – og SQL-passord ved pålogging, bare lett tilslørt – i klartekst over nettverket. Installer et sertifikat utstedt av en sertifikatautoritet klientene stoler på, og slå på Force Encryption i SQL Server Configuration Manager. SQL Server 2022 introduserte strict encryption (TDS 8.0), der TLS-forhandlingen skjer før all annen SQL Server-kommunikasjon, på samme måte som HTTPS.

Moderne klientbiblioteker (Microsoft.Data.SqlClient 4 og nyere) krypterer som standard og validerer serverens sertifikat. Mange løser feilmeldingen om ugyldig sertifikat med TrustServerCertificate=True i connection stringen. Trafikken er da fortsatt kryptert, men klienten sjekker ikke hvem den snakker med, så et mellommannsangrep blir mulig. Det kan være et akseptabelt kompromiss på et lukket internt nett, men et gyldig sertifikat er den riktige løsningen.

Kryptering av lagrede data

TeknologiBeskytter motBeskytter ikke mot
Transparent Data Encryption (TDE)Tyveri av datafiler, loggfiler og backuperBrukere og administratorer med tilgang til databasen
Kryptert backupTyveri av backupfilerTilgang til den kjørende databasen
Always EncryptedDBA-er, skyleverandøren og alle som har tilgang til serveren – dataene dekrypteres bare i klientenApplikasjonen og brukerne som har nøkkelen
Kolonnekryptering (ENCRYPTBYKEY)Tilgang til enkeltkolonner uten nøkkelDen som har tilgang til nøklene i databasen

TDE krypterer hele databasen på disk og er usynlig for applikasjonen. Den har vært tilgjengelig i Standard siden SQL Server 2019. Husk å ta backup av sertifikatet – uten det kan verken databasen eller backupene gjenopprettes andre steder.

USE master;
CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'Et-langt-og-unikt-passord!';
CREATE CERTIFICATE TdeSertifikat WITH SUBJECT = 'TDE';

USE Salg;
CREATE DATABASE ENCRYPTION KEY
WITH ALGORITHM = AES_256
ENCRYPTION BY SERVER CERTIFICATE TdeSertifikat;
ALTER DATABASE Salg SET ENCRYPTION ON;

Always Encrypted krypterer utvalgte kolonner i klientdriveren, slik at SQL Server aldri ser klarteksten. Det er det sterkeste vernet for for eksempel fødselsnummer, men begrenser hva du kan gjøre med kolonnene i spørringer (med secure enclaves kan du likevel søke og sammenligne).

SQL-injeksjon

SQL-injeksjon oppstår når brukerinput limes direkte inn i SQL-tekst. En angriper kan da endre hva spørringen gjør – hente ut alle data, slette tabeller eller i verste fall kjøre kommandoer på serveren.

// FARLIG: input limes inn i SQL-teksten
var sql = "SELECT * FROM Kunde WHERE Navn = '" + navn + "'";
// navn = "' OR 1=1; DROP TABLE Kunde; --" gir en helt annen spørring

// TRYGT: parameterisert spørring
await using var cmd = new SqlCommand(
    "SELECT KundeId, Navn FROM Kunde WHERE Navn = @Navn", connection);
cmd.Parameters.Add("@Navn", SqlDbType.NVarChar, 100).Value = navn;

Entity Framework Core, Dapper og andre moderne verktøy parameteriserer automatisk så lenge du ikke bygger SQL med strengsammenslåing selv. Vær forsiktig med FromSqlRaw og ExecuteSqlRaw; bruk heller FromSql/FromSqlInterpolated, som gjør interpolerte verdier om til parametere.

Dynamisk SQL i lagrede prosedyrer har den samme risikoen. Bruk sp_executesql med parametere for verdier, og QUOTENAME for objektnavn som ikke kan parameteriseres:

DECLARE @sql nvarchar(max) =
    N'SELECT * FROM dbo.' + QUOTENAME(@Tabellnavn) + N' WHERE Opprettet >= @FraDato;';

EXEC sp_executesql @sql, N'@FraDato date', @FraDato = @FraDato;

Reduser angrepsflaten

  • Hold serveren oppdatert. Sikkerhetsrettinger kommer som GDR-er og i kumulative oppdateringer. Versjoner uten støtte får ingen rettinger.
  • Installer bare komponentene du trenger.
  • La xp_cmdshell være av. Den lar sysadmin kjøre kommandoer i operativsystemet, og er et yndet mål.
  • Kjør tjenestene med kontoer med minst mulig rettigheter – virtuelle kontoer eller gMSA, ikke en domeneadministrator.
  • Begrens tilgang til backupene. En backupfil er hele databasen.
  • Skill miljøene. Produksjonsdata hører ikke hjemme i test uten anonymisering.

Revisjon og sporbarhet

SQL Server Audit logger hvem som gjorde hva – pålogginger, endringer i rettigheter, lesing av sensitive tabeller – til fil eller Windows-hendelseslogg. Det er ofte et krav i regelverk som GDPR, og nyttig ved hendelser.

USE master;
CREATE SERVER AUDIT Revisjon TO FILE (FILEPATH = N'D:\Audit\');
ALTER SERVER AUDIT Revisjon WITH (STATE = ON);

CREATE SERVER AUDIT SPECIFICATION ServerRevisjon
FOR SERVER AUDIT Revisjon
ADD (FAILED_LOGIN_GROUP),
ADD (SERVER_ROLE_MEMBER_CHANGE_GROUP),
ADD (DATABASE_PERMISSION_CHANGE_GROUP)
WITH (STATE = ON);

Ledger (fra SQL Server 2022) gjør tabeller manipulasjonssikre med kryptografiske hasher, slik at du kan bevise at historikken ikke er endret i ettertid – nyttig for finansielle transaksjoner og logger.

Sjekkliste

  • sa er deaktivert, og ingen applikasjoner logger inn med sysadmin.
  • Applikasjonskontoer har bare rettighetene de trenger, gjerne via egne roller.
  • SQL Server er ikke tilgjengelig fra internett.
  • Trafikken er kryptert med et gyldig sertifikat.
  • Databaser med sensitive data har TDE, og backupene er kryptert.
  • Sertifikater og nøkler er sikkerhetskopiert separat.
  • Applikasjonene bruker parameteriserte spørringer.
  • Mislykkede pålogginger og rettighetsendringer logges.
  • Serveren har en støttet versjon og siste sikkerhetsrettinger.

Vanlige spørsmål

Er det greit å lagre passordet i appsettings.json?

Det er utbredt, men alle med tilgang til filen eller kildekoden får da tilgang til databasen. Bruk heller Windows-autentisering uten passord, eller en hemmelighetstjeneste som Azure Key Vault. Hvis passordet må ligge i en fil, sørg for at filen ikke er lesbar for flere enn nødvendig, og at kontoen bare har minimale rettigheter.

Beskytter TDE mot løsepengevirus?

Nei. TDE beskytter mot at noen stjeler filene og leser dem andre steder. Løsepengevirus krypterer filene på stedet – TDE-krypterte eller ikke. Mot løsepengevirus hjelper uforanderlige backuper utenfor serveren, se guiden om backup.

Hvordan ser jeg hvem som har tilgang til en database?

Spør sys.database_principals, sys.database_role_members og sys.database_permissions, eller bruk dbatools-kommandoen Get-DbaUserPermission, som lager en fullstendig rapport over rettigheter på server- og databasenivå.

Les også