# Hvad er en SQL-injektion?

SQL-injektioner udgør en betydelig trussel mod relationsdatabasemodeller og de følsomme oplysninger, de indeholder. Derfor er det absolut nødvendigt med en omfattende beskyttelse mod disse uautoriserede forsøg på ekstern adgang, som muliggøres af sikkerhedssvagheder.

## Hvad er en SQL-injektion?

En SQL-injektion er en type angreb, der udnytter en sikkerhedsfejl i relationsdatabasesystemer, der bruger [SQL-forespørgselssproget](https://www.ionos.com/da-dk/digitalguide/server/know-how/hvad-er-sql/) til at behandle brugerinput. Angriberen udnytter brugerinput, der **ikke** er **korrekt eskapet** og indeholder **specialtegn** såsom dobbelte bindestreger, anførselstegn eller semikoloner. Disse tegn har særlige funktioner for SQL-fortolkeren og gør det muligt at manipulere de kommandoer, der udføres, eksternt. SQL-injektioner er ofte forbundet med PHP- og ASP-applikationer, der er baseret på forældede grænseflader. I mange af disse tilfælde er inputtet ikke tilstrækkeligt renset, hvilket gør det til et oplagt mål for et angreb.

Ved strategisk at indsætte funktionstegn kan en uautoriseret bruger indsætte yderligere SQL-kommandoer og manipulere databaseposter for **at læse, ændre eller slette data**. I alvorlige tilfælde kan angribere endda få **adgang til systemets kommandolinje**, hvilket kan give dem mulighed for at overtage fuld kontrol over databaseserveren.

## Eksempel på SQL-injektion, der viser, hvordan et databaseangreb fungerer

Da sårbare databaseservere hurtigt kan identificeres, og SQL-injektionsangreb er relativt nemme at gennemføre, er denne metode fortsat en af de mest udbredte teknikker blandt cyberkriminelle verden over. Angribere anvender **forskellige strategier**, hvor de udnytter både nyopdagede og velkendte sikkerhedsfejl i de applikationer, der indgår i datahåndteringsprocessen. For bedre at forstå, hvordan SQL-injektion fungerer i praksis, skal vi se på to almindelige angrebsmetoder som eksempler.

### Eksempel 1: Adgang via brugerinput med utilstrækkelig eskaping

For at få adgang til en database skal brugerne som regel først godkende sig selv. Til dette formål bruges der ofte scripts til at vise en **login-formular**, der indeholder felter til brugernavn og adgangskode. Brugerne udfylder formularen, og **scriptet kontrollerer derefter**, om der findes matchende poster i databasen. Som standard kan databasen indeholde en tabel ved navn `users` med kolonnerne `username` og `password`. I en typisk webapplikation kan de relevante scriptlinjer til databaseadgang (ved hjælp af Python-lignende pseudokode) se således ud:

```python
uname = request.POST['username']
passwd = request.POST['password']
sql = "SELECT id FROM users WHERE username='" + uname + "' AND password='" + passwd + "'"
database.execute(sql)
```

En hacker kan nu **manipulere adgangskodefeltet ved hjælp af en SQL-injektion**, for eksempel ved at indtaste `password' OR 1='1`, hvilket resulterer i følgende SQL-forespørgsel:

```python
sql = "SELECT id FROM users WHERE username='' AND password='password' OR 1='1'"
```

Dette giver angriberen fuld adgang til hele brugertabellen i databasen, da **betingelsen vedrørende adgangskoden altid vurderes til at være sand** (`1='1'`). Hvis angriberen logger ind **som administrator**, kan vedkommende frit ændre alle poster i databasen. Alternativt kan **feltet for brugernavn** manipuleres på samme måde.

### Eksempel 2: Dataudtræk via manipulation af ID-numre

At hente oplysninger fra en database ved hjælp af et ID er en praktisk og udbredt metode, men åbner også mulighed for SQL-injektion. For eksempel ved en webserver via et ID, der er angivet i en URL, hvilke oplysninger den skal hente fra databasen. Det tilhørende **PHP-script** ser således ud:

```php
<?php
    $mysqli = new mysqli("localhost", "username", "password", "database");
    $id = intval($_GET['id']);
    $result = $mysqli->query("SELECT * FROM table WHERE id=$id");
    while ($row = $result->fetch_assoc()) {
        echo print_r($row, true);
    }
?>
```

Den forventede URL følger mønsteret `.../script.php?id=22`. I dette tilfælde vil den **tabelpost** med ID’et »22« blive hentet. Hvis en uautoriseret person har mulighed for at manipulere denne URL og i stedet sender en anmodning som `.../script.php?id=22+OR+1=1`, vil den resulterende forespørgsel medføre, at **alle rækker i tabellen** hentes:

```sql
SELECT * FROM table WHERE id=22 OR 1=1;
```

## Hvordan finder kriminelle sårbare databasesystemer?

I princippet kan enhver hjemmeside eller webapplikation, der bruger SQL-databaser uden forberedte forespørgsler (prepared statements) eller andre beskyttelsesforanstaltninger, være sårbar over for SQL-injektioner. Opdagede sårbarheder forbliver ikke skjulte længe på internettet. Der findes faktisk hjemmesider, der offentliggør opdaterede lister over kendte sikkerhedsfejl – og endda forklarer, hvordan angribere kan bruge Google-søgninger til at finde relevante webprojekter. Hvis et websted returnerer detaljerede SQL-fejlmeddelelser, kan cyberkriminelle bruge disse meddelelser til at identificere potentielle sårbarheder. For eksempel kan tilføjelsen af en apostrof i slutningen af en URL, der indeholder en ID-parameter, allerede afsløre en svaghed, som vist i følgende eksempel:

```none
[DomainName].com/news.php?id=5’
```

Et sårbart websted returnerer en fejlmeddelelse i følgende form:

`Query failed: You have an error in your SQL syntax…`

Lignende metoder kan også bruges til at udtrække antallet af kolonner, tabel- og kolonnenavne, SQL-versionen eller endda brugernavne og adgangskoder. Der findes desuden forskellige værktøjer, der kan **automatisere både opdagelsesprocessen og udførelsen af SQL-injektionsangreb**.

## Sådan beskytter du din database mod SQL-injektion

Der findes forskellige metoder, du kan anvende for at forhindre SQL-injektionsangreb på dit databasesystem. Du bør tage højde for alle de involverede komponenter – både serveren og de enkelte applikationer samt databasestyringssystemet.

### Trin 1: Overvåg automatiske indtastninger fra applikationer

Når man behandler indtastninger fra eksterne eller indbyggede applikationer, er det afgørende at validere og filtrere de indsendte værdier for at forhindre SQL-injektioner.

**1. Valider datatyper**

Hver indtastning skal svare til den forventede datatype. Hvis der f.eks. kræves en numerisk indtastning, kan en simpel validering i PHP se sådan ud:

```php
if (filter_var($input, FILTER_VALIDATE_INT) === false) {
    throw new InvalidArgumentException("Invalid input");
}
```

Der bør indføres tilsvarende kontroller for strengtyper, datoer eller andre specifikke formater.

**2. Filtrer specialtegn**

Særtegn kan udgøre en sikkerhedsrisiko, især i forbindelse med SQL eller HTML. En sikker fremgangsmåde er at anvende `htmlspecialchars()` til HTML-indtastninger og `PDO::quote()` til SQL-forespørgsler.

**3. Undgå at vise fejlmeddelelser**

Man bør undgå direkte fejlmeddelelser, der afslører tekniske detaljer om databasen eller systemet. Vis i stedet en generel meddelelse, f.eks.:

```php
echo "An error occurred. Please try again later.";
error_log("Unexpected error encountered. See system log for details.");
```

**4. Brug foruddefinerede sætninger**

En af de mest effektive måder at forhindre SQL-injektioner på er ved at bruge **forberedte sætninger**. Ved denne fremgangsmåde sendes SQL-kommandoer og parametre hver for sig, så ondsindet kode ikke kan udføres. Her er et eksempel på en implementering i PHP ved hjælp af PDO (PHP Data Objects):

```php
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = :id");
$stmt->bindParam(':id', $user_id, PDO::PARAM_INT);
$stmt->execute();
```

Databasestyringssystemet sikrer automatisk, at indtastningerne behandles sikkert.

### Trin 2: Sørg for omfattende serverbeskyttelse

Sikkerheden på den server, hvor dit databasestyringssystem kører, spiller også en afgørende rolle i forebyggelsen af SQL-injektion. En vigtig foranstaltning er at **styrke operativsystemets sikkerhed** ved at følge disse anbefalinger:

- Installer eller aktiver kun de programmer og tjenester, der er nødvendige for at køre databasen.
- Fjern alle ubrugte eller unødvendige brugerkonti.
- Sørg for, at alle relevante system- og softwareopdateringer installeres straks.
- Anvend princippet om mindst mulig adgang for at sikre, at brugere og tjenester kun tildeles de minimalt nødvendige tilladelser.

Afhængigt af sikkerhedskravene til dit webprojekt bør du overveje yderligere sikkerhedsforanstaltninger:

- **[Intrusion Detection Systems (IDS)](https://www.ionos.com/da-dk/digitalguide/server/sikkerhed/indtraengningsdetekteringssystem-ids/) og [Intrusion Prevention Systems (IPS)](https://www.ionos.com/da-dk/digitalguide/server/sikkerhed/intrusion-prevention-system-ips/)**: Disse systemer anvender forskellige detekteringsmetoder **til at identificere angreb på et tidligt tidspunkt**, udsende advarsler og – når der anvendes IPS – automatisk iværksætte modforanstaltninger.
- **Application Layer Gateway (ALG)**: En ALG overvåger og filtrerer trafikken mellem applikationer og webbrowsere direkte på applikationsniveau.
- **Web Application Firewall (WAF)**: En WAF beskytter specifikt webapplikationer mod SQL-injektion og Cross-Site Scripting (XSS) ved at blokere eller rense mistænkelige anmodninger.
- **Zero Trust-tilgang**: Denne moderne sikkerhedsmodel sikrer, at hvert eneste adgangsforsøg – uanset dets oprindelse – verificeres og autentificeres, før der gives adgang.
- **Firewall-regler og netværkssegmentering**: Disse er afgørende for at minimere angrebsfladen på lang sigt.
- **Regelmæssige IT-sikkerhedsrevisioner og [penetrationstests](https://www.ionos.com/da-dk/digitalguide/server/know-how/penetrationstest-den-komplette-netvaerksgennemgang/)**: Disse hjælper med at opdage og rette sårbarheder på et tidligt stadium.

### Trin 3: Sikkerhedsoptimer databasen og brug sikker kode

Ligesom dit operativsystem bør din database renses for alle unødvendige komponenter og holdes opdateret. Fjern alle gemte procedurer, du ikke har brug for, og deaktiver alle ubrugte tjenester og brugerkonti. Opret en **dedikeret databasekonto**, der udelukkende er beregnet til webadgang, og tildel den kun de absolut nødvendige rettigheder.

I tråd med brugen af forberedte sætninger anbefales det på det kraftigste **ikke at bruge** `mysql` PHP-modulet (som blev fjernet i PHP 7). Vælg i stedet `mysqli` eller PDO for at sikre bedre sikkerhed og kompatibilitet. En sikker `mysqli` kan se sådan ud:

```php
$mysqli = new mysqli("localhost", "username", "password", "database");
if ($mysqli->connect_error) die("Connection failed");
$stmt = $mysqli->prepare("SELECT password FROM users WHERE username = ?");
$stmt->bind_param("s", $_POST['username']);
$stmt->execute();
$stmt->bind_result($hashedPassword);
if ($stmt->fetch() && password_verify($_POST['password'], $hashedPassword)) {
    echo "Login successful";
} else {
    echo "Invalid login credentials";
}
$stmt->close();
$mysqli->close();
```

Adgangskoder bør aldrig gemmes direkte i en database eller hentes i klartekst. Brug i stedet en hashing-metode som `password_hash()` i kombination med `password_verify()` for at beskytte brugeroplysningerne sikkert. En sikker implementering kan se sådan ud:

```php
$mysqli = new mysqli("localhost", "username", "password", "database");
$stmt = $mysqli->prepare("SELECT password FROM users WHERE username = ?");
$stmt->bind_param("s", $_POST['username']);
$stmt->execute();
$result = $stmt->get_result();
$row = $result->fetch_assoc();
if ($row && password_verify($_POST['password'], $row['password'])) {
    echo "Login successful!";
} else {
    echo "Incorrect username or password.";
}
```

## Hvad har klapborde med SQL-injektion at gøre?

Hjemmesiden [bobby-tables.com](https://bobby-tables.com/ "Bobby Tables website") bruger en xkcd-webtegneserie til på humoristisk vis at illustrere farerne ved usikre **brugerindtastninger i databaser**. I tegneserien modtager en mor et opkald fra sin søns (kært kaldet Little Bobby Tables) skole. Den, der ringer, spørger, om hendes søn virkelig hedder `Robert'); DROP TABLE Students;--`, hvilket hun bekræfter. Årsagen til opkaldet bliver snart klar: et forsøg på at indtaste Robert i elevdatabasen medførte, **at hele elevtabellen blev slettet**. Moderen er ikke særlig forstående – hun håber blot, at skolen har lært sin lektie og fremover vil rense databaseindtastningerne.

Tegneserien illustrerer tydeligt de katastrofale konsekvenser, der kan opstå, hvis man undlader at validere og rense brugerinput korrekt i databaseapplikationer.


This is a markdown version of: [https://www.ionos.com/da-dk/digitalguide/server/sikkerhed/sql-injektion-grundlaeggende-principper-og-sikkerhedsforanstaltninger/](https://www.ionos.com/da-dk/digitalguide/server/sikkerhed/sql-injektion-grundlaeggende-principper-og-sikkerhedsforanstaltninger/) for AI/LLM consumption.