# Sprawdzanie bazy danych pod kątem wstrzykniętego kodu

> Sprawdzanie bazy danych pod kątem złośliwego kodu: jak znaleźć wstrzyknięte skrypty, obce adresy, wyzwalacze i konta zapytaniami tylko do odczytu.

Źródło: https://phpsos.de/pl/blog/datenbank-auf-schadcode-pruefen/  
Stan: 25.10.2026  
Dostawca: PHP SOS, Pomoc awaryjna PHP i bezpieczeństwo serwerów. Natychmiastowa pomoc przez WhatsApp: https://wa.me/491736494914?text=Dzie%C5%84%20dobry%2C%20PHP%20SOS%2C%20potrzebujemy%20pomocy%20z%20naszym%20serwerem%20PHP.%20Firma%3A%20%E2%80%A6%20Strona%20internetowa%3A%20%E2%80%A6

**Krótko:** Aby sprawdzić bazę danych pod kątem złośliwego kodu, przeszukują Państwo eksport lub kopię zapytaniami tylko do odczytu, szukając wstrzykniętych skryptów, obcych adresów i zaciemnionego kodu w treściach i ustawieniach. Należy też sprawdzić wyzwalacze, zaplanowane zdarzenia, procedury składowane i użytkowników bazy danych. Oczyszczać można dopiero po ocenie i nigdy przez ślepe wyszukiwanie i zamianę, ponieważ dane serializowane zostałyby uszkodzone.

## Martwy punkt wielu oczyszczeń

Po włamaniu większość operatorów sprawdza pliki. Wymieniają rdzeń CMS, usuwają podejrzane pliki PHP i instalują rozszerzenia od nowa. Strona wygląda potem czysto, a tydzień później znów przekierowuje na obce witryny. Przyczyna leży często w bazie danych, którą podczas oczyszczania przejęto bez zmian.

Dla atakujących baza danych jest atrakcyjną kryjówką. Skrypt w widżecie jest dostarczany na każdej stronie. Zmienione ustawienie adresu przekierowuje wszystkich odwiedzających. Dodatkowe konto administratora otwiera drzwi na później. Nic z tego nie wychodzi na jaw przy skanie plików.

Po PHP2Shell, czyli lukach CVE-2026-109618 i CVE-2026-109619 umożliwiających wykonanie kodu bez logowania, baza danych należy więc do każdej kontroli. Kto może wykonać kod na serwerze, zazwyczaj może odczytać z konfiguracji dane dostępowe do bazy i dowolnie w niej zapisywać. Jak aplikacja w ogóle komunikuje się z bazą danych, wyjaśnia artykuł [PHP i bazy danych: PDO i mysqli](https://phpsos.de/pl/php/php-und-datenbanken/).

## Gdzie złośliwy kod ukrywa się w bazie danych

| Miejsce | Typowa zawartość | Skutek |
|---|---|---|
| Treści (wpisy, strony, produkty) | bloki `<script>`, niewidoczne linki, `<iframe>` | złośliwy kod lub spam dla odwiedzających |
| Ustawienia i opcje | zmieniony adres strony, obce skrypty w widżetach lub opcjach motywu | przekierowania, skrypty na wszystkich stronach |
| Tabele użytkowników | dodatkowi administratorzy | trwały dostęp |
| Wyzwalacze | kod, który przy każdym zapisie zmienia treści | złośliwy kod wraca po oczyszczeniu |
| Zaplanowane zdarzenia | cykliczne zadania na serwerze bazy danych | zmiany bez dostępu przez sieć WWW |
| Użytkownicy bazy danych | dodatkowe konta z szerokimi uprawnieniami | dostęp z pominięciem CMS |

Ostatnie trzy wiersze są szczególnie często pomijane, ponieważ nie leżą w tabelach CMS, lecz w samym serwerze bazy danych.

W sklepach internetowych jedno miejsce zasługuje na szczególną uwagę: ustawienia, za pomocą których do kasy i finalizacji zamówienia dołączane są dodatkowe skrypty. Obcy skrypt w tym miejscu może podejrzeć dane wpisywane przez klientów, zanim zostaną zaszyfrowane i przekazane do operatora płatności. Dlatego proszę celowo sprawdzić wszystkie pola na kod nagłówka i stopki, osadzenia śledzące oraz ustawienia projektu graficznego, które działają na stronach kasy.

Proszę też pamiętać o innych bazach danych na tym samym serwerze. Kopie testowe i stagingowe, stare wersje projektów lub bazy innych stron leżą często obok i są osiągalne tymi samymi danymi dostępowymi. To, co znajdzie się w bazie produkcyjnej, należy sprawdzić także tam, zanim kopia posłuży później znowu jako podstawa.

## Sprawdzanie bazy danych pod kątem złośliwego kodu: treści i ustawienia

Proszę pracować na eksporcie. Jest on zarazem zabezpieczeniem dowodów i podstawą wyszukiwania. Eksport można przeszukać jako plik tekstowy bez obciążania działającej bazy danych:

```bash
# Utworzyć spójny eksport (dane dostępowe zostaną zapytane)
mysqldump --single-transaction --routines --triggers --events -u BENUTZER -p DATENBANK > export.sql
sha256sum export.sql > export.sql.sha256

# Zliczyć typowe wzorce w eksporcie
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
```

Ostatnie zapytanie wypisuje według częstotliwości wszystkie domeny występujące w bazie danych. Obce domeny, których nikt w zespole nie zna, są najważniejszymi kandydatami. Do celowanych zapytań w samej bazie danych nadają się polecenia SELECT. Przykład używa tabel WordPress; prefiks i nazwy tabel innych systemów podano w ich dokumentacji:

```sql
-- Ustawienia ze skryptami lub podejrzanymi funkcjami
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;
```

Wpisy o bardzo dużej zawartości zasługują na szczególną uwagę. Tło dotyczące kryjówek specyficznych dla WordPress przedstawia poradnik [Wyszukiwanie backdoorów w WordPress](https://phpsos.de/pl/ratgeber/backdoor-wordpress-finden/).

## Wyzwalacze, zdarzenia i konta bazy danych

Wyzwalacze i zaplanowane zdarzenia nie są w wielu aplikacjach internetowych w ogóle przewidziane. Jeśli istnieją, ktoś powinien umieć wyjaśnić, dlaczego. Poniższe zapytania odczytują dane wyłącznie z tabel systemowych MySQL i MariaDB:

```sql
-- Wyzwalacze we wszystkich bazach danych
SELECT TRIGGER_SCHEMA, TRIGGER_NAME, EVENT_OBJECT_TABLE, CREATED
FROM information_schema.TRIGGERS;

-- Zaplanowane zdarzenia
SELECT EVENT_SCHEMA, EVENT_NAME, STATUS, CREATED, LAST_EXECUTED
FROM information_schema.EVENTS;

-- Procedury i funkcje składowane
SELECT ROUTINE_SCHEMA, ROUTINE_NAME, ROUTINE_TYPE, CREATED
FROM information_schema.ROUTINES
WHERE ROUTINE_SCHEMA NOT IN ('mysql', 'sys', 'information_schema', 'performance_schema');

-- Użytkownicy bazy danych
SELECT user, host FROM mysql.user ORDER BY user;
```

Jeśli aplikacja używa PostgreSQL lub innego systemu baz danych, tabele systemowe i polecenia nazywają się inaczej; zasada pozostaje ta sama. Do analizy zaleca się osobnego użytkownika bazy danych, który może tylko czytać. Dzięki temu nawet literówka w zapytaniu niczego nie zmieni, a kontrola nie zostawia śladów w danych.

Wyzwalacz, który przy zapisie wpisu dołącza kod, wyjaśnia, dlaczego złośliwy kod wraca po każdym oczyszczeniu. Nieznani użytkownicy bazy danych należą do kontroli kont tak samo jak konta administratorów w CMS; więcej w artykule [Wyszukiwanie obcych kont administratorów w CMS i na serwerze](https://phpsos.de/pl/blog/fremde-admin-konten-finden/).

## Czyste oczyszczanie bez niszczenia danych

Oczyszczanie jest najbardziej delikatną częścią. Sprawdziła się następująca kolejność:

1. **Ocenić znaleziska:** każde trafienie klasyfikuje się jako znane, nieszkodliwe i możliwe do wyjaśnienia lub obce. Kody śledzące i map są często uzasadnione.
2. **Zamknąć furtkę:** doprowadzić PHP do naprawionej wersji (8.5.12, 8.4.27, 8.3.36, 8.2.35 lub potwierdzony backport), zrestartować wszystkie procesy robocze, zaktualizować aplikację.
3. **Usunąć celowo:** obce treści oczyszczać przez aplikację lub narzędziami, które poprawnie traktują dane serializowane. Obce wyzwalacze, zdarzenia i konta usunąć.
4. **Zmienić dane dostępowe:** nowe hasło do bazy danych wpisać w konfiguracji aplikacji, ograniczyć uprawnienia użytkownika aplikacji do własnej bazy danych.
5. **Sprawdzić ponownie:** powtórzyć zapytania wyszukujące po kilku dniach.

> **Ważne:**
> Niczego nie należy zastępować przez wyszukiwanie i zamianę w eksporcie SQL. Serializowane dane PHP zapisują długość każdego ciągu znaków. Jeśli długość się zmieni, ustawienie staje się nieczytelne, a strona może przestać działać.

Przekierowania, które występują mimo czystej bazy danych, mają przyczynę w innej warstwie. Przy zawężaniu pomoże artykuł [Strona przekierowuje na obce witryny](https://phpsos.de/pl/blog/website-leitet-um/).

## Jak konkretnie pomaga PHP SOS?

- Zabezpieczamy bazę danych z sumą kontrolną i przeszukujemy eksport pod kątem skryptów, obcych domen i zaciemnionego kodu.
- Sprawdzamy wyzwalacze, zdarzenia, procedury i użytkowników bazy danych, którzy leżą poza CMS.
- Oczyszczamy znaleziska w ramach [usuwania malware](https://phpsos.de/pl/leistungen/malware-entfernung/), nie uszkadzając danych serializowanych.
- Ograniczamy uprawnienia użytkownika aplikacji i powtarzamy kontrolę po oczyszczeniu.


## Częste pytania

**Czy złośliwy kod może siedzieć w bazie danych?**  
Tak. Atakujący wpisują JavaScript do wpisów, opisów produktów lub widżetów, zmieniają ustawienia adresów na potrzeby przekierowań albo zakładają konta administratorów. W MySQL i MariaDB dodatkowo wyzwalacze (triggery) i zaplanowane zdarzenia mogą zmieniać dane. Skan plików niczego z tego nie znajdzie.

**Jak przeszukać bazę danych, niczego nie psując?**  
Proszę pracować na eksporcie lub kopii i używać wyłącznie zapytań SELECT. Eksport można ponadto przeszukać jako plik tekstowy za pomocą grep. Zmiany wprowadza się dopiero po ocenie każdego znaleziska i wykonaniu kopii zapasowej.

**Dlaczego nie powinienem oczyszczać znalezisk przez wyszukiwanie i zamianę w eksporcie?**  
Wiele systemów CMS zapisuje ustawienia jako serializowane dane PHP, w których zapisywana jest też długość każdego ciągu znaków. Zamiana zmienia długość, ale nie zmienia zapisanej wartości, i ustawienie staje się nieczytelne. Oczyszczać należy przez aplikację lub narzędziami rozumiejącymi dane serializowane.

**Czy każdy skrypt w bazie danych jest podejrzany?**  
Nie. Kody śledzące, mapy, filmy czy widżety czatu także są zapisywane jako skrypt. Decydujące jest, czy ktoś w zespole zna ten wpis i adres docelowy.

## Źródła

- [OWASP Top 10](https://owasp.org/www-project-top-ten/)
- [OWASP Cheat Sheets](https://cheatsheetseries.owasp.org/)
- [php.net: komunikaty bezpieczeństwa](https://www.php.net/)
