Pozostałe odpowiedzi już obejmują to, co musisz wiedzieć. Ale może pomoże to wyjaśnić trochę więcej:
Są dwie rzeczy, które trzeba zrobić:
1. Sprawdź poprawność danych formularza.
Jak jasno pokazuje odpowiedź Jonathana Hobbsa , wybór elementu HTML do danych wejściowych formularza nie zapewnia żadnego niezawodnego filtrowania.
Walidacja jest zwykle przeprowadzana w sposób, który nie zmienia danych, ale pokazuje ponownie formularz, z polami oznaczonymi jako „Popraw to”.
Większość frameworków i systemów CMS ma konstruktory formularzy, które pomagają w tym zadaniu. I nie tylko to, pomagają również przeciwko CSRF (lub „XSRF”), który jest inną formą ataku.
2. Oczyść zmienne / ucieczki w instrukcjach SQL.
.. lub pozwól, aby przygotowane zestawienia zrobiły to za Ciebie.
Jeśli tworzysz (My) instrukcję SQL z dowolnymi zmiennymi, podanymi lub nie przez użytkownika, musisz zmienić znaczenie i zacytować te zmienne.
Ogólnie rzecz biorąc, każda taka zmienna, którą wstawisz do instrukcji MySQL, powinna być albo ciągiem znaków, albo czymś, co PHP może niezawodnie przekształcić w ciąg, który MySQL może przetrawić. Takich jak liczby.
W przypadku łańcuchów musisz wybrać jedną z kilku metod zmiany znaczenia ciągu, co oznacza zastąpienie wszelkich znaków, które miałyby skutki uboczne w MySQL.
- W starej szkole MySQL + PHP, mysql_real_escape_string () wykonuje zadanie. Problem polega na tym, że zbyt łatwo o tym zapomnieć, dlatego bezwzględnie należy używać przygotowanych instrukcji lub konstruktorów zapytań.
- W MySQLi możesz korzystać z przygotowanych wyciągów.
- Większość platform i systemów CMS udostępnia narzędzia do tworzenia zapytań, które pomagają w tym zadaniu.
Jeśli masz do czynienia z liczbą, możesz pominąć ucieczki i cudzysłowy (dlatego przygotowane instrukcje pozwalają określić typ).
Ważne jest, aby zwrócić uwagę, że zmieniasz znaczenie zmiennych dla instrukcji SQL, a NIE dla samej bazy danych . Baza danych będzie przechowywać oryginalny ciąg, ale instrukcja wymaga wersji z ucieczką.
Co się stanie, jeśli pominiesz jedną z nich?
Jeśli nie korzystasz z weryfikacji formularza , ale oczyszczasz dane wejściowe SQL, możesz zobaczyć różne rodzaje złych rzeczy, ale nie zobaczysz iniekcji SQL! (*)
Po pierwsze, może spowodować, że Twoja aplikacja wejdzie w stan, którego nie planowałeś. Np. Jeśli chcesz obliczyć średni wiek wszystkich użytkowników, ale jeden użytkownik podał „aljkdfaqer” jako wiek, obliczenia nie powiodą się.
Po drugie, może istnieć wiele innych ataków typu injection, które należy wziąć pod uwagę: np. Dane wejściowe użytkownika mogą zawierać kod JavaScript lub inne elementy.
Nadal mogą występować problemy z bazą danych: np. Jeśli pole (kolumna tabeli bazy danych) jest ograniczone do 255 znaków, a łańcuch jest dłuższy. Lub jeśli pole akceptuje tylko liczby, a zamiast tego spróbujesz zapisać ciąg nienumeryczny. Ale to nie jest „wstrzyknięcie”, to po prostu „zawieszenie aplikacji”.
Ale nawet jeśli masz wolne pole tekstowe, w którym zezwalasz na dowolne dane wejściowe bez żadnej walidacji, nadal możesz zapisać to w bazie danych po prostu w ten sposób, jeśli odpowiednio zmienisz jego znaczenie, gdy przechodzi do instrukcji bazy danych. Problem pojawia się, gdy chcesz gdzieś użyć tego ciągu.
(*) albo byłoby to coś naprawdę egzotycznego.
Jeśli nie zmienisz znaczenia zmiennych dla instrukcji SQL , ale sprawdziłeś poprawność danych wejściowych formularza, nadal możesz zobaczyć, że dzieje się źle.
Po pierwsze, ryzykujesz, że kiedy zapiszesz dane do bazy danych i załadujesz je ponownie, nie będą to już te same dane, „zagubione w tłumaczeniu”.
Po drugie, może spowodować nieprawidłowe instrukcje SQL, a tym samym spowodować awarię aplikacji. Np. Jeśli jakakolwiek zmienna zawiera cudzysłów lub znak podwójnego cudzysłowu, w zależności od tego, jakiego typu cudzysłowu używasz, otrzymasz nieprawidłowe wyrażenie MySQL.
Po trzecie, nadal może powodować wstrzykiwanie SQL.
Jeśli dane wejściowe użytkownika z formularzy są już przefiltrowane / zatwierdzone, celowe wstrzyknięcie SQl może być mniej prawdopodobne, JEŚLI dane wejściowe zostaną zredukowane do zakodowanej na stałe listy opcji lub jeśli są ograniczone do liczb. Ale do wstrzyknięcia SQL można użyć dowolnego wpisanego tekstu, jeśli nie zmienisz odpowiednio zmiennych w instrukcjach SQL.
I nawet jeśli w ogóle nie masz danych wejściowych do formularza, nadal możesz mieć ciągi znaków z różnych źródeł: odczytywane z systemu plików, usuwane z Internetu itp. Nikt nie może zagwarantować, że te ciągi są bezpieczne.
<select>
danych wejściowych. Rzeczywiście, nawet mało techniczny użytkownik mógłby dodać dodatkowe opcje za pomocą konsoli przeglądarki. jeśli utrzymasz tablicę z białą listą dostępnych wartości i porównasz z nią dane wejściowe, możesz to złagodzić (i powinieneś, ponieważ zapobiega to niechcianym wartościom)