# Mis on SQL-süst?

SQL-süstid kujutavad endast suurt ohtu relatsioonilistele andmebaasimudelitele ja nendes sisalduvale tundlikule teabele. Seetõttu on hädavajalik tagada põhjalik kaitse selliste volitamata väliste juurdepääsukatse vastu, mis on võimalikud turvaaukude tõttu.

## Mis on SQL-süst?

SQL-süst on rünnakutüüp, mis kasutab ära turvaauku relatsioonilistes andmebaasisüsteemides, mis töötlevad kasutaja sisestusi [SQL-päringukeele](https://www.ionos.com/et-ee/digitalguide/server/oskusteave/mis-on-sql/) abil. Ründaja kasutab ära kasutaja sisestusi, mis **ei** ole **nõuetekohaselt puhastatud** ja sisaldavad **erimärke**, nagu topeltkriipsud, jutumärgid või semikoolonid. Nendel märkidel on SQL-tõlke jaoks erifunktsioonid ning need võimaldavad väliselt manipuleerida täidetavaid käske. SQL-injektsioone seostatakse sageli PHP- ja ASP-rakendustega, mis tuginevad vananenud liidestele. Paljudel juhtudel ei ole sisestusi piisavalt puhastatud, mistõttu on need rünnakute peamine sihtmärk.

Funktsioonimärkide strateegilise sisestamise abil võib volitamata kasutaja lisada täiendavaid SQL-käsklusi ja manipuleerida andmebaasi kirjetega, et **andmeid lugeda, muuta või kustutada**. Raskematel juhtudel võivad ründajad saada **juurdepääsu** isegi **süsteemi käsureale**, mis võib võimaldada neil võtta andmebaasi serveri täielikult oma kontrolli alla.

## SQL-süstimise näide, mis illustreerib andmebaasi ründe toimimist

Kuna haavatavaid andmebaasiserverid on võimalik kiiresti tuvastada ja SQL-süstimisrünnakuid on suhteliselt lihtne teostada, on see meetod endiselt üks küberkurjategijate seas kogu maailmas enim kasutatavaid tehnikaid. Ründajad kasutavad **erinevaid strateegiaid**, ärakasutades nii äsja avastatud kui ka juba ammu teadaolevaid turvaauke andmehaldusprotsessis osalevates rakendustes. Et paremini mõista, kuidas SQL-süstimine praktikas toimib, vaatame näidetena kahte levinud rünnakumeetodit.

### Näide 1: Juurdepääs halvasti puhastatud kasutaja sisestuse kaudu

Andmebaasile juurdepääsuks peavad kasutajad tavaliselt esmalt end autentima. Selleks kasutatakse sageli skripte, mis kuvavad **sisselogimisvormi**, kus on kasutajanime ja parooli väljad. Kasutajad täidavad vormi ja **skript kontrollib seejärel**, kas andmebaasis on vastavaid kirjeid. Vaikimisi võib andmebaas sisaldada tabelit nimega `users`, millel on veerud `username` ja `password`. Tüüpilises veebirakenduses võivad andmebaasile juurdepääsu jaoks vajalikud skripti read (kasutades Python-laadset pseudokoodi) välja näha järgmiselt:

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

Ründaja saab nüüd **SQL-süsti abil paroolivälja manipuleerida**, näiteks sisestades sinna `password' OR 1='1`, mis tekitab järgmise SQL-päringu:

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

See annab ründajale täieliku juurdepääsu andmebaasi kogu kasutajate tabelile, kuna **paroolitingimus annab alati tulemuseks „tõene“** (`1='1'`). Kui ründaja logib sisse **administraatorina**, saab ta vabalt muuta kõiki andmebaasi kirjeid. Samamoodi on võimalik manipuleerida ka **kasutajanime väljaga**.

### Näide 2: Andmete väljavõtmine ID-de muutmise teel

Andmete päring andmebaasist ID järgi on praktiline ja levinud meetod, kuid see avab ka võimaluse SQL-süstimiseks. Näiteks teab veebiserver URL-is edastatud ID andmete põhjal, millised andmed ta andmebaasist välja peab otsima. Vastav **PHP-skript** näeb välja järgmine:

```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);
    }
?>
```

Oodatav URL järgib mustrit `.../script.php?id=22`. Sel juhul kuvataks **tabeli kirje** ID-ga „22”. Kui volitamata isikul on võimalus seda URL-i muuta ja ta saadab selle asemel päringu nagu `.../script.php?id=22+OR+1=1`, põhjustab see päring **tabeli kõigi ridade** kuvamise:

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

## Kuidas kurjategijad leiavad haavatavaid andmebaasisüsteeme?

Põhimõtteliselt võib iga veebisait või veebirakendus, mis kasutab SQL-andmebaase ilma ettevalmistatud päringuteta (prepared statements) või muude kaitsemeetmeteta, olla haavatav SQL-süstide suhtes. Avastatud turvaaugud ei jää veebis kauaks varjatuks. Tegelikult on olemas veebisaite, mis avaldavad ajakohaseid nimekirju teadaolevatest turvaprobleemidest – ja selgitavad isegi, kuidas ründajad saavad Google’i otsingute abil leida sobivaid veebiprojekte. Kui veebisait kuvab üksikasjalikke SQL-veateateid, saavad küberkurjategijad neid kasutada potentsiaalsete haavatavuste tuvastamiseks. Näiteks võib ID-parameetrit sisaldava URL-i lõppu apostroofi lisamine juba paljastada nõrkuse, nagu on näidatud järgmises näites:

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

Haavatav veebisait saadab tagasi järgmise vormis veateate:

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

Sarnaseid meetodeid saab kasutada ka veergude arvu, tabelite ja veergude nimede, SQL-versiooni või isegi kasutajanimede ja paroolide väljaselgitamiseks. Lisaks on olemas mitmesuguseid tööriistu, millega saab **automatiseerida nii andmete väljaselgitamise protsessi kui ka SQL-süstimisrünnakute läbiviimise**.

## Kuidas kaitsta oma andmebaasi SQL-süstide eest

Andmebaasisüsteemi SQL-süstimisrünnakute ärahoidmiseks on olemas mitmesuguseid meetodeid. Tuleb tegeleda kõigi asjaomaste komponentidega – nii serveri ja üksikute rakenduste kui ka andmebaasi haldussüsteemiga.

### 1. samm: Rakendustest tulevate automaatsete sisestuste jälgimine

Välistest või sisseehitatud rakendustest saadud sisendite töötlemisel on SQL-süstide vältimiseks hädavajalik esitatud väärtusi kontrollida ja filtreerida.

**1. Andmetüüpide kontrollimine**

Iga sisend peab vastama oodatavale andmetüübile. Näiteks kui nõutakse numbrilist sisendit, võiks lihtne valideerimine PHP-s välja näha järgmine:

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

Sarnaseid kontrolle tuleks rakendada ka stringide, kuupäevade või muude spetsiifiliste vormingute puhul.

**2. Erimärkide filtreerimine**

Erimärgid võivad tekitada turvaauke, eriti SQL- või HTML-kontekstis. Turvaline lähenemisviis on kasutada HTML-sisestuse puhul `htmlspecialchars()` ja SQL-päringute puhul `PDO::quote()`.

**3. Vältige veateadete kuvamist**

Tuleks vältida otseseid veateateid, mis paljastavad andmebaasi või süsteemi tehnilisi üksikasju. Selle asemel tuleks kuvada üldine teade, näiteks:

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

**4. Kasutage eelvalmistatud päringuid**

Üks tõhusamaid viise SQL-süstide vältimiseks on **valmislaaditud päringute** kasutamine. Selle meetodi puhul saadetakse SQL-käskud ja parameetrid eraldi, mistõttu pahatahtlikku koodi ei ole võimalik käivitada. Siin on näide rakendamisest PHP-s, kasutades PDO-d (PHP Data Objects):

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

Andmebaasi haldussüsteem tagab automaatselt, et sisestatud andmed töödeldakse turvaliselt.

### 2. samm: Tagage serveri igakülgne kaitse

SQL-süstide ennetamisel on oluline roll ka selle serveri turvalisusel, kus teie andmebaasihaldussüsteem töötab. Üks peamisi meetmeid on **operatsioonisüsteemi turvalisuse tugevdamine**, järgides järgmisi parimaid tavasid:

- Paigaldage või aktiveerige ainult need rakendused ja teenused, mis on andmebaasi töötamiseks hädavajalikud.
- Kustutage kõik kasutamata või mittevajalikud kasutajakontod.
- Veenduge, et kõik asjakohased süsteemi- ja tarkvarauuendused paigaldatakse viivitamatult.
- Rakendage minimaalse õiguse põhimõtet, et tagada, et kasutajatele ja teenustele antakse ainult minimaalsed vajalikud õigused.

Sõltuvalt veebiprojekti turvanõuetest peaksite kaaluma täiendavate kaitsemeetmete rakendamist:

- **[Sissetungijate tuvastamise süsteemid (IDS)](https://www.ionos.com/et-ee/digitalguide/server/turvalisus/sissetungijate-tuvastamise-suesteem-ids/) ja [sissetungijate tõkestamise süsteemid (IPS)](https://www.ionos.com/et-ee/digitalguide/server/turvalisus/sissetungide-tokestamise-suesteem-ips/)**: Need süsteemid kasutavad erinevaid tuvastusmeetodeid, **et rünnakuid varakult avastada**, hoiatusi edastada ja – IPS-i kasutamisel – automaatselt vastumeetmeid rakendada.
- **Rakenduskihi värav (ALG)**: ALG jälgib ja filtreerib liiklust rakenduste ja veebibrauserite vahel otse rakenduste tasandil.
- **Veebirakenduste tulemüür (WAF)**: WAF kaitseb veebirakendusi spetsiaalselt SQL-süstide ja ristveebiskriptimise (XSS) eest, blokeerides või puhastades kahtlased päringud.
- **Zero Trust lähenemine**: see kaasaegne turvalisusmudel tagab, et iga juurdepääsukatse – olenemata selle päritolust – kontrollitakse ja autentitakse enne juurdepääsu lubamist.
- **Tulemüüri reeglid ja võrgu segmentatsioon**: need on olulised rünnakupinna pikaajaliseks minimeerimiseks.
- **Regulaarsed IT-turbeauditid ja [sissetungitestid](https://www.ionos.com/et-ee/digitalguide/server/oskusteave/sissetungitest-vorgu-pohjalik-kontroll/)**: need aitavad avastada ja parandada haavatavusi varases staadiumis.

### 3. samm: Andmebaasi turvalisemaks muutmine ja turvalise koodi kasutamine

Nii nagu operatsioonisüsteem, peaks ka andmebaas olema vabastatud kõigist mittevajalikest komponentidest ja ajakohasena hoitud. Kustutage kõik mittevajalikud salvestatud protseduurid ning lülitage välja kõik kasutamata teenused ja kasutajakontod. Looge **spetsiaalne andmebaasi konto**, mis on mõeldud ainult veebipõhiseks juurdepääsuks, ning määrake sellele vaid minimaalsed vajalikud õigused.

Valmisküsimuste kasutamisega kooskõlas soovitatakse tungivalt **mitte kasutada** `mysql` PHP-moodulit (mis eemaldati PHP 7-st). Valige selle asemel `mysqli` või PDO, et tagada parem turvalisus ja ühilduvus. Turvaline `mysqli` päring võiks välja näha järgmine:

```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();
```

Paroolid ei tohi kunagi salvestada otse andmebaasi ega edastada tavatekstina. Kasutage selle asemel paroolide turvaliseks kaitsmiseks hash-meetodit, näiteks `password_hash()` koos `password_verify()`. Turvaline rakendus võiks välja näha järgmine:

```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.";
}
```

## Mis seos on bobby-laudadel SQL-süstimisega?

Veebisait [bobby-tables.com](https://bobby-tables.com/ "Bobby Tables website") kasutab xkcd-veebikoomiksit, et illustreerida humoorikalt **andmebaasides** ebaturvalise **kasutajasisestuse** ohtusid. Koomiksis saab ema kõne oma poja (keda hellitavalt kutsutakse Little Bobby Tablesiks) koolist. Helistaja küsib, kas poja nimi on tõesti `Robert'); DROP TABLE Students;--`, millele ema vastab jaatavalt. Kõne põhjus selgub peagi: katse sisestada Robert õpilaste andmebaasi põhjustas **kogu õpilaste tabeli kustutamise**. Ema ei ole eriti kaastundlik – ta loodab lihtsalt, et kool on õppinud oma õppetundi ja puhastab edaspidi andmebaasi sisestusi.

Koomiks toob selgelt esile katastroofilised tagajärjed, mis võivad tekkida, kui andmebaasirakendustes ei kontrollita ega puhastata kasutaja sisestatud andmeid nõuetekohaselt.


This is a markdown version of: [https://www.ionos.com/et-ee/digitalguide/server/turvalisus/sql-suest-pohitoed-ja-kaitsemeetmed/](https://www.ionos.com/et-ee/digitalguide/server/turvalisus/sql-suest-pohitoed-ja-kaitsemeetmed/) for AI/LLM consumption.