# Provjera baze podataka na ubačeni kod

> Provjera baze podataka na zlonamjerni kod: pronađite ubačene skripte, tuđe adrese, okidače i račune upitima koji samo čitaju, bez uništavanja podataka.

Izvor: https://phpsos.de/hr/blog/datenbank-auf-schadcode-pruefen/  
Stanje: 25.10.2026  
Pružatelj: PHP SOS, PHP hitna pomoć i sigurnost poslužitelja. Hitna pomoć putem WhatsAppa: https://wa.me/491736494914?text=Pozdrav%20PHP%20SOS%2C%20trebamo%20pomo%C4%87%20s%20na%C5%A1im%20PHP%20poslu%C5%BEiteljem.%20Tvrtka%3A%20%E2%80%A6%20Web-stranica%3A%20%E2%80%A6

**Ukratko:** Da biste bazu podataka provjerili na zlonamjerni kod, upitima koji samo čitaju pretražite izvoz ili kopiju u potrazi za ubačenim skriptama, tuđim adresama i prikrivenim kodom u sadržajima i postavkama. Provjerite i okidače, planirane događaje, pohranjene procedure i korisnike baze podataka. Čistite tek nakon procjene i nikad slijepim traženjem i zamjenom, jer se serijalizirani podaci tako raspadaju.

## Slijepa pjega mnogih čišćenja

Nakon provale većina operatera provjerava datoteke. Zamjenjuju jezgru CMS-a, brišu sumnjive PHP datoteke i ponovno instaliraju proširenja. Web-stranica nakon toga izgleda čisto, a tjedan dana kasnije ponovno preusmjerava na tuđe stranice. Uzrok je često u bazi podataka, koja je pri čišćenju preuzeta nepromijenjena.

Za napadače je baza podataka privlačno skrovište. Skripta u widgetu isporučuje se na svakoj stranici. Izmijenjena postavka adrese preusmjerava sve posjetitelje. Dodatni administratorski račun otvara vrata za kasnije. Ništa od toga ne upada u oči pri pretrazi datoteka.

Nakon PHP2Shella, ranjivosti CVE-2026-109618 i CVE-2026-109619 s izvršavanjem koda bez prijave, baza podataka stoga spada u svaku provjeru. Tko na poslužitelju može izvršavati kod, u pravilu može iz konfiguracije pročitati pristupne podatke baze podataka i tamo upisivati što god želi. Kako aplikacija uopće komunicira s bazom podataka, objašnjava članak [PHP i baze podataka: PDO i mysqli](https://phpsos.de/hr/php/php-und-datenbanken/).

## Gdje se zlonamjerni kod skriva u bazi podataka

| Mjesto nalaza | Tipičan sadržaj | Učinak |
|---|---|---|
| Sadržaji (objave, stranice, proizvodi) | blokovi `<script>`, nevidljive poveznice, `<iframe>` | zlonamjerni kod ili spam za posjetitelje |
| Postavke i opcije | izmijenjena adresa web-stranice, tuđe skripte u widgetima ili opcijama teme | preusmjeravanja, skripte na svim stranicama |
| Korisničke tablice | dodatni administratori | trajni pristup |
| Okidači (triggeri) | kod koji pri svakom spremanju mijenja sadržaje | zlonamjerni kod vraća se nakon čišćenja |
| Planirani događaji | ponavljajući zadaci na poslužitelju baze podataka | izmjene bez web-pristupa |
| Korisnici baze podataka | dodatni računi sa širokim pravima | pristup mimo CMS-a |

Posljednja tri retka posebno se često previđaju jer se ne nalaze u tablicama CMS-a, nego u samom poslužitelju baze podataka.

Kod web-shopova jedno mjesto nalaza zaslužuje osobitu pažnju: postavke putem kojih se dodatne skripte uključuju u blagajnu i završetak narudžbe. Tuđa skripta na tom mjestu može čitati unose kupaca prije nego što se šifrirani pošalju pružatelju usluga plaćanja. Zato ciljano provjerite sva polja za kod zaglavlja i podnožja, uključivanja praćenja i postavke dizajna koje djeluju na stranicama blagajne.

Mislite i na druge baze podataka na istom poslužitelju. Testne i staging kopije, stara stanja projekata ili baze podataka drugih web-stranica često se nalaze pokraj i dostupne su istim pristupnim podacima. Što se nađe u živoj bazi podataka, treba provjeriti i tamo prije nego što kopija kasnije ponovno posluži kao osnova.

## Provjera baze podataka na zlonamjerni kod: sadržaji i postavke

Radite na izvozu. On je istodobno osiguranje dokaza i osnova za pretragu. Izvoz se može pretraživati kao tekstualna datoteka bez opterećenja pokrenute baze podataka:

```bash
# Izraditi konzistentan izvoz (pristupni podaci se traže)
mysqldump --single-transaction --routines --triggers --events -u BENUTZER -p DATENBANK > export.sql
sha256sum export.sql > export.sql.sha256

# Prebrojiti tipične obrasce u izvozu
grep -oiE '<script[^>]{0,80}' export.sql | sort | uniq -c | sort -rn | head -30
grep -oiE '(eval\(|base64_decode|fromCharCode|document\.write|atob\()' export.sql | sort | uniq -c
grep -oiE 'https?://[a-z0-9.-]+' export.sql | sort | uniq -c | sort -rn | head -50
```

Posljednji upit ispisuje sve domene koje se pojavljuju u bazi podataka, poredane po učestalosti. Tuđe domene koje nitko u timu ne poznaje najvažniji su kandidati. Za ciljane upite u samoj bazi podataka prikladne su SELECT naredbe. Primjer koristi tablice WordPressa; prefiks i nazivi tablica drugih sustava nalaze se u njihovoj dokumentaciji:

```sql
-- Postavke sa skriptama ili sumnjivim funkcijama
SELECT option_name, LENGTH(option_value) AS laenge
FROM wp_options
WHERE option_value LIKE '%<script%'
   OR option_value LIKE '%eval(%'
   OR option_value LIKE '%base64_decode%'
ORDER BY laenge DESC;
```

Unosi s vrlo velikim sadržajem zaslužuju osobitu pažnju. Pozadinu o skrovištima specifičnima za WordPress nudi vodič [Pronaći stražnja vrata u WordPressu](https://phpsos.de/hr/ratgeber/backdoor-wordpress-finden/).

## Okidači, događaji i računi baze podataka

Okidači i planirani događaji u mnogim web-aplikacijama uopće nisu predviđeni. Ako postoje, netko bi trebao moći objasniti zašto. Ovi upiti samo čitaju iz sistemskih tablica MySQL-a i MariaDB-a:

```sql
-- Okidači u svim bazama podataka
SELECT TRIGGER_SCHEMA, TRIGGER_NAME, EVENT_OBJECT_TABLE, CREATED
FROM information_schema.TRIGGERS;

-- Planirani događaji
SELECT EVENT_SCHEMA, EVENT_NAME, STATUS, CREATED, LAST_EXECUTED
FROM information_schema.EVENTS;

-- Pohranjene procedure i funkcije
SELECT ROUTINE_SCHEMA, ROUTINE_NAME, ROUTINE_TYPE, CREATED
FROM information_schema.ROUTINES
WHERE ROUTINE_SCHEMA NOT IN ('mysql', 'sys', 'information_schema', 'performance_schema');

-- Korisnici baze podataka
SELECT user, host FROM mysql.user ORDER BY user;
```

Ako Vaša aplikacija koristi PostgreSQL ili drugi sustav baze podataka, sistemske tablice i naredbe zovu se drukčije; načelo ostaje isto. Za analizu se preporučuje zaseban korisnik baze podataka koji smije samo čitati. Tako ni tipkarska pogreška u upitu ne može ništa promijeniti, a provjera ne ostavlja tragove u podacima.

Okidač koji pri spremanju objave dodaje kod objašnjava zašto se zlonamjerni kod vraća nakon svakog čišćenja. Nepoznati korisnici baze podataka pripadaju provjeri računa jednako kao administratorski računi u CMS-u; više o tome u članku [Pronaći tuđe administratorske račune u CMS-u i na poslužitelju](https://phpsos.de/hr/blog/fremde-admin-konten-finden/).

## Čisto očistiti bez uništavanja podataka

Čišćenje je najosjetljiviji dio. Ovaj se redoslijed pokazao dobrim:

1. **Procijeniti nalaze:** svaki se pogodak svrstava kao poznat, bezazleno objašnjiv ili tuđ. Kodovi za praćenje i karte često su legitimni.
2. **Zatvoriti ulaz:** PHP dovesti na ispravljeno stanje (8.5.12, 8.4.27, 8.3.36, 8.2.35 ili potvrđeni backport), ponovno pokrenuti sve workere, ažurirati aplikaciju.
3. **Ciljano ukloniti:** tuđe sadržaje čistiti putem aplikacije ili alatima koji ispravno obrađuju serijalizirane podatke. Tuđe okidače, događaje i račune izbrisati.
4. **Promijeniti pristupne podatke:** nova lozinka baze podataka, upisati je u konfiguraciju aplikacije, prava korisnika aplikacije ograničiti na vlastitu bazu podataka.
5. **Ponovno provjeriti:** upite za pretragu ponoviti nakon nekoliko dana.

> **Važno:**
> Ništa ne zamjenjujte traženjem i zamjenom u SQL izvozu. Serijalizirani PHP podaci zajedno s nizom spremaju i njegovu duljinu. Ako se duljina promijeni, postavka postaje nečitljiva i web-stranica može prestati raditi.

Preusmjeravanja koja se javljaju unatoč čistoj bazi podataka imaju uzrok u drugom sloju. Pri sužavanju pomaže članak [Web-stranica preusmjerava na tuđe stranice](https://phpsos.de/hr/blog/website-leitet-um/).

## Kako PHP SOS konkretno pomaže?

- Bazu podataka osiguravamo s kontrolnim zbrojem, a izvoz pretražujemo na skripte, tuđe domene i prikriveni kod.
- Provjeravamo okidače, događaje, procedure i korisnike baze podataka koji se nalaze izvan CMS-a.
- Nalaze čistimo u sklopu [uklanjanja zlonamjernog softvera](https://phpsos.de/hr/leistungen/malware-entfernung/), bez oštećivanja serijaliziranih podataka.
- Ograničavamo prava korisnika aplikacije i ponavljamo provjeru nakon čišćenja.


## Česta pitanja

**Može li zlonamjerni kod biti u bazi podataka?**  
Može. Napadači upisuju JavaScript u objave, opise proizvoda ili widgete, mijenjaju postavke adresa radi preusmjeravanja ili stvaraju administratorske račune. U MySQL-u i MariaDB-u dodatno okidači (triggeri) i planirani događaji mogu mijenjati podatke. Pretraga datoteka ništa od toga ne pronalazi.

**Kako pretražiti bazu podataka a da ništa ne pokvarim?**  
Radite na izvozu ili kopiji i koristite samo SELECT upite. Izvoz se uz to može kao tekstualna datoteka pretraživati naredbom grep. Izmjene tek kad je svaki nalaz procijenjen i postoji sigurnosna kopija.

**Zašto nalaze ne bih trebao čistiti traženjem i zamjenom u izvozu?**  
Mnogi CMS-ovi postavke spremaju kao serijalizirane PHP podatke u kojima je duljina svakog niza znakova spremljena zajedno s njim. Zamjena mijenja duljinu, ali ne i navedenu vrijednost, pa postavka postaje nečitljiva. Čistite putem aplikacije ili alatima koji razumiju serijalizirane podatke.

**Je li svaka skripta u bazi podataka sumnjiva?**  
Nije. I kodovi za praćenje, karte, videozapisi ili chat widgeti spremaju se kao skripta. Odlučujuće je poznaje li netko u timu unos i odredišnu adresu.

## Izvori

- [OWASP Top 10](https://owasp.org/www-project-top-ten/)
- [OWASP Cheat Sheets](https://cheatsheetseries.owasp.org/)
- [php.net: sigurnosne obavijesti](https://www.php.net/)
