Blog 24/7

SQL injection

TAB. 1Hasłopo angielsku
Po angielskuSQL injection
Którą formą pisaćpo angielsku Polski odpowiednik istnieje, ale w praktyce nikt tak nie pisze. Zostaw angielski, polski trzymaj jako synonim.
Inne formywstrzyknięcie SQL · wstrzyknięcie zapytania SQL · błędy wstrzyknięcia
KategoriaPodatności i klasy błędów

SQL injection to podatność, która pozwala wpleść własne polecenia w zapytanie do bazy danych i odczytać, zmienić lub usunąć dane, do których atakujący nie ma prawa. MITRE opisuje ją jako sytuację, w której program buduje całe polecenie SQL lub jego część z danych pochodzących z zewnątrz, ale nie neutralizuje znaków specjalnych, które mogą zmienić sens tego polecenia [1]. OWASP definiuje atak jako wstawienie, czyli „wstrzyknięcie”, zapytania SQL przez dane wejściowe przesłane od klienta do aplikacji [2]. W zestawieniu CWE Top 25 za 2025 rok słabość CWE-89 zajęła drugie miejsce [4].

Jak działa

Aplikacja internetowa często składa zapytanie do bazy z dwóch części: stałego szablonu napisanego przez programistę i wartości podanej przez użytkownika, na przykład numeru wpisu z adresu URL. Jeśli wartość zostanie wklejona do tekstu zapytania bez przygotowania, baza nie odróżni danych od kodu. Sekurak opisuje to tak, że atakujący wstrzykuje do aplikacji nieautoryzowany fragment zapytania SQL, a przyczyną jest brak odpowiedniej walidacji parametru przekazanego przez użytkownika [7].

Przebieg ataku na podatny parametr pokazuje schemat poniżej.

RYS. 1SQL injection w parametrze adresu

Mechanizm widać na przykładzie w PHP z klasą wpdb WordPressa. Pierwsze zapytanie jest podatne, drugie przekazuje wartość jako parametr.

// podatne: wartość wklejona do tekstu zapytania
$wpdb->get_results( "SELECT * FROM {$wpdb->posts} WHERE ID = " . $_GET['id'] );

// bezpieczne: placeholder %d i osobny argument
$wpdb->get_results( $wpdb->prepare(
    "SELECT * FROM {$wpdb->posts} WHERE ID = %d",
    $_GET['id']
) );

Odmiany

Odmiany różnią się tym, jak atakujący dowiaduje się o wyniku wstrzykniętego zapytania. PortSwigger zaznacza, że wiele przypadków SQL injection to podatności „ślepe”: aplikacja nie zwraca w odpowiedzi ani wyników zapytania, ani szczegółów błędów bazy [8].

OdmianaJak widać wynikUwagi
Z bezpośrednim wynikiemdane z innych tabel dołączone do odpowiedzi, np. przez UNION [8]wynik widać od razu
blind SQL injectionaplikacja nie zwraca wyniku ani błędów; wniosek z różnicy odpowiedzi lub opóźnienia [8]także przez połączenia poza pasmem [8]
Drugiego rzędudane zapisane w bazie, użyte później w niebezpiecznym zapytaniu [8]programista ufa danym już zapisanym [8]

Ładunek może trafić do aplikacji dowolnym kanałem: parametrem adresu, polem formularza, nagłówkiem HTTP albo ciasteczkiem. Liczy się to, czy wartość zostanie potem wklejona do tekstu zapytania.

W WordPressie

WordPress komunikuje się z bazą MySQL lub MariaDB przez obiekt $wpdb. Metoda wpdb::prepare() przygotowuje zapytanie do bezpiecznego wykonania w składni podobnej do sprintf(), z symbolami zastępczymi, które są poprawnie zabezpieczane i ujmowane w cudzysłowy [5]. Obsługuje symbole %d dla liczb całkowitych, %f dla liczb zmiennoprzecinkowych, %s dla tekstu oraz %i dla nazw tabel i kolumn; ten ostatni dodano w WordPressie 6.2.0 [5]. Dokumentacja zastrzega, że symboli zastępczych nie wolno ujmować w cudzysłowy w tekście zapytania i że każdy z nich musi mieć odpowiadający argument [5]. Przy zapytaniach LIKE znak procentu trzeba przekazać przez argument, a samą wartość przepuścić przez wpdb::esc_like() [5].

Podatność powstaje tam, gdzie wtyczka albo motyw buduje zapytanie ręcznie i dokleja do niego dane z żądania z pominięciem prepare(); zob. podatność we wtyczce. Typowe miejsca to własne tabele wtyczek, filtry wyszukiwania i punkty AJAX przyjmujące parametry sortowania. Zmieniony prefiks tabel nie usuwa podatności, a jedynie utrudnia zgadywanie nazw tabel.

Zagrożenia i skutki

MITRE wymienia jako skutki wykonanie nieautoryzowanego kodu lub poleceń, odczyt danych aplikacji, przejęcie uprawnień lub tożsamości, obejście mechanizmów ochrony oraz modyfikację danych [1]. OWASP dodaje, że atak może pozwolić na podszycie się pod innego użytkownika, manipulację danymi, pełne ujawnienie wszystkich danych w systemie, ich zniszczenie, a nawet przejęcie roli administratora serwera bazy [2].

Na stronie WordPress oznacza to przede wszystkim:

Jak się bronić

OWASP jako główne zabezpieczenia wymienia zapytania przygotowane z parametrami, poprawnie zbudowane procedury składowane i walidację wejścia z listą dozwolonych wartości [3]. Ręczne zabezpieczanie znaków w całym wejściu użytkownika uznaje za podejście kruche i zdecydowanie odradzane [3]. W WordPressie odpowiednikiem zapytania parametryzowanego jest wpdb::prepare().

Dodatkowe warstwy to:

  • Sanityzacja danych wejściowych i rzutowanie typów, na przykład numer wpisu jako liczba całkowita.
  • Zasada najmniejszych uprawnień dla konta bazy. OWASP zaleca ograniczenie uprawnień każdego konta bazodanowego i przestrzega przed nadawaniem kontom aplikacji uprawnień administratora bazy [3].
  • Zapora aplikacyjna, czyli WAF, którą MITRE wymienia jako jedną z warstw ochrony [1]. Nie zastępuje ona poprawnego kodu.

Historia i przykłady

SQL injection należy do najstarszych i najlepiej opisanych klas błędów. Sekurak w 2013 roku zwracał uwagę, że błąd ten należał wtedy do pierwszej kategorii, A1, w zestawieniu OWASP Top 10 [7]. W klasyfikacji CWE ma numer 89 [1].

W WordPressie głośnym przypadkiem była funkcja $wpdb->prepare(). 31 października 2017 roku WordPress wydał wersję 4.8.3, bo w pewnych warunkach funkcja ta mogła tworzyć nieoczekiwane i niebezpieczne zapytania prowadzące do SQL injection [6]. Błąd zgłosił Anthony Ferrara [6]. Według ogłoszenia sam rdzeń nie był bezpośrednio podatny, ale poprawka utwardzała funkcję, by wtyczki i motywy nie tworzyły luki przypadkiem; zmieniło się też działanie funkcji esc_sql() [6].

TAB. 2

Przypisy

8
  1. [1] CWE-89: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection') · MITRE
  2. [2] SQL Injection · OWASP
  3. [3] SQL Injection Prevention Cheat Sheet · OWASP
  4. [4] 2025 CWE Top 25 Most Dangerous Software Weaknesses · MITRE
  5. [5] wpdb::prepare() — Class Method · WordPress.org
  6. [6] WordPress 4.8.3 Security Release · WordPress.org
  7. [7] Czym jest SQL injection? · Sekurak
  8. [8] SQL injection — Web Security Academy · PortSwigger
TAB. 3

Hasła w tym artykule

14
TAB. 4

Linkują tutaj

42

Wszystkie kategorie → · Hasło w słowniku →

Blog 24/7
05.11CISA i FBI wzywają do zabezpieczenia sterowników chłodzenia po atakach w Europietherecord.media05.11Midnight Blizzard atakowała iPhone'y i Androidy przez zainfekowane strony w Europie i USAsecurityweek.com05.11APT29 kradła dane z iPhone'ów i Androidów przez przejęte i podrobione stronytherecord.media05.11Grupa APT29 przejęła skrypt Plerdy i atakowała niezałatane iPhone'y i Androidythehackernews.com05.11Microsoft wykrył 7,3 mld wiadomości phishingowych w III kwartale 2026microsoft.com05.11DigiCert ujawnia wyciek danych klientów i skanów dokumentów tożsamościbleepingcomputer.com05.11CWPdoor podmienia serwer cwpsrv w Control Web Panel i otwiera tylne wejście do Linuksableepingcomputer.com05.11Brytyjskie NCSC ostrzega, że narzędzia AI zwiększyły liczbę wykrywanych luk zero-daythehackernews.com05.11Skaner RootEvidence sprawdza starą lukę w Cisco IOS i dodaje nagłówki Opt-Outisc.sans.edu05.11Włamanie do portalu grantowego Norad, zagrożone dane 20 614 użytkownikówhelpnetsecurity.com