programowanieProgramista web/aplikacji

Jakie podejścia można zastosować do bezpiecznego wykonywania dynamicznie formowanych zapytań SQL? Jak chronić się przed atakami SQL injection podczas programowania w SQL i pracy z zewnętrznymi parametrami?

Zdaj rozmowy kwalifikacyjne z asystentem AI Hintsage

Odpowiedź

Najpewniejszym sposobem jest zawsze stosowanie zapytania parametryzowanego lub przygotowanych wyrażeń (prepared statements), a NIE formułowanie zapytań poprzez prostą konkatenację ciągów z wartościami użytkownika.

W przypadku bardziej złożonych scenariuszy (dynamiczny SQL w procedurach) należy stosować specjalne mechanizmy eskalacji i whitelisting (ścisłe filtrowanie) parametrów.

Przykład:

  • Na poziomie aplikacji (Python, Java, C#):
cursor.execute('SELECT * FROM users WHERE login = %s', [login])
  • W SQL (PostgreSQL):
EXECUTE format('SELECT * FROM %I WHERE id = $1', tablename) USING id;

Tutaj %I bezpiecznie podstawia tylko nazwy tabel/kolumn.

Pytanie z pułapką

Czy następujące podejście jest bezpieczne przy wstawianiu liczby do ciągu?

EXECUTE 'SELECT * FROM users WHERE id = ' || user_input;

NIE! Nawet jeśli spodziewasz się liczby, napastnik może wprowadzić kod: 1; DROP TABLE users; — zapytanie zostanie wykonane. Dlatego zawsze używaj placeholderów i wyraźnego sprawdzenia typu wejściowych parametrów.

Przykłady rzeczywistych błędów spowodowanych niewiedzą na ten temat


Historia 1

Formularz wyszukiwania pracowników budował warunki WHERE poprzez konkatenację ciągów po stronie aplikacji. Napastnik wprowadził: ' OR 1=1 --, co spowodowało wyświetlenie danych wszystkich pracowników. Później przez podobne podejście usunięto sekcję danych. Wniosek: konkatenacja istotnych parametrów — zawsze ryzyko.


Historia 2

W administracyjnym interfejsie wyboru raportu nazwa tabeli pobierana była z pola użytkownika i wstawiana do zapytania SQL. Użytkownik mógł wprowadzić nieprawidłową nazwę i uzyskać dostęp do tabel systemowych. Po tym zezwolono tylko na ściśle określone nazwy (whitelisting).


Historia 3

W projekcie e-commerce podczas dynamicznego sortowania użytkownicy przekazywali nazwę pola przez parametr GET. Haker podstawił price; DELETE FROM orders; --, co doprowadziło do utraty wszystkich zamówień. Filtrowanie dozwolonych nazw kolumn i stosowanie zapytań parametryzowanych rozwiązało problem.