Samouczek SQL

SQL HOME Wprowadzenie do SQL Składnia SQL Wybór SQL SQL Wybierz Wyraźne SQL Gdzie SQL i lub nie Kolejność SQL według SQL Wstaw do Puste wartości SQL Aktualizacja SQL Usuń SQL SQL Wybierz Góra Minimalna i maksymalna wartość SQL Liczba SQL, średnia, suma Polubienie SQL Symbole wieloznaczne SQL SQL In SQL między Aliasy SQL Połączenia SQL Wewnętrzne złącze SQL Połączenie lewe SQL Prawe połączenie SQL Pełne dołączenie do SQL Samoprzyłączanie SQL SQL Union Grupa SQL według Posiadanie SQL SQL istnieje SQL Dowolne, Wszystkie SQL Wybierz do Wstaw SQL do Wybierz Sprawa SQL Funkcje zerowe SQL Procedury składowane w SQL Komentarze SQL Operatory SQL

Baza danych SQL

Tworzenie bazy danych SQL Porzucona baza danych SQL Kopia zapasowa bazy danych SQL Utwórz tabelę SQL Tabela upuszczania SQL Zmień tabelę SQL Ograniczenia SQL SQL nie jest pusty Unikalny SQL Klucz podstawowy SQL Klucz obcy SQL Sprawdzanie SQL Domyślny SQL Indeks SQL Automatyczny przyrost SQL Daty SQL Widoki SQL Wstrzyknięcie SQL Hosting SQL Typy danych SQL

Referencje SQL

Słowa kluczowe SQL Funkcje MySQL Funkcje serwera SQL Funkcje dostępu MS Szybkie odwołanie do SQL

Przykłady SQL

Przykłady SQL Quiz SQL Ćwiczenia SQL Certyfikat SQL

Wstrzyknięcie SQL


Wstrzyknięcie SQL

Wstrzyknięcie SQL to technika wstrzykiwania kodu, która może zniszczyć Twoją bazę danych.

Wstrzykiwanie SQL jest jedną z najczęstszych technik hakerskich.

Wstrzyknięcie SQL to umieszczanie złośliwego kodu w instrukcjach SQL za pośrednictwem danych wejściowych na stronie internetowej.


SQL na stronach internetowych

Wstrzyknięcie SQL zwykle występuje, gdy poprosisz użytkownika o wprowadzenie danych, takich jak nazwa użytkownika/identyfikator użytkownika, a zamiast nazwy/identyfikatora użytkownik podaje instrukcję SQL, którą nieświadomie uruchomisz w swojej bazie danych.

Spójrz na poniższy przykład, który tworzy SELECTinstrukcję przez dodanie zmiennej (txtUserId) do wybranego ciągu. Zmienna jest pobierana z danych wejściowych użytkownika (getRequestString):

Przykład

txtUserId = getRequestString("UserId");
txtSQL = "SELECT * FROM Users WHERE UserId = " + txtUserId;

Pozostała część tego rozdziału opisuje potencjalne zagrożenia związane z używaniem danych wejściowych użytkownika w instrukcjach SQL.


Wstrzykiwanie SQL oparte na 1 = 1 jest zawsze prawdziwe

Spójrz ponownie na powyższy przykład. Pierwotnym celem kodu było stworzenie instrukcji SQL w celu wybrania użytkownika o podanym identyfikatorze użytkownika.

Jeśli nic nie stoi na przeszkodzie, aby użytkownik wprowadził „złe” dane wejściowe, użytkownik może wprowadzić „inteligentne” dane wejściowe w następujący sposób:

Identyfikator użytkownika:

Wtedy instrukcja SQL będzie wyglądać tak:

SELECT * FROM Users WHERE UserId = 105 OR 1=1;

Powyższy kod SQL jest prawidłowy i zwróci WSZYSTKIE wiersze z tabeli „Użytkownicy”, ponieważ LUB 1=1 jest zawsze PRAWDĄ.

Czy powyższy przykład wygląda niebezpiecznie? Co się stanie, jeśli tabela „Użytkownicy” zawiera nazwy i hasła?

Powyższa instrukcja SQL jest bardzo podobna do tej:

SELECT UserId, Name, Password FROM Users WHERE UserId = 105 or 1=1;

Haker może uzyskać dostęp do wszystkich nazw użytkowników i haseł w bazie danych, po prostu wstawiając 105 LUB 1=1 w polu wejściowym.



Wstrzykiwanie SQL oparte na „”=” jest zawsze prawdziwe

Oto przykład logowania użytkownika na stronie internetowej:

Nazwa użytkownika:

Hasło:

Przykład

uName = getRequestString("username");
uPass = getRequestString("userpassword");

sql = 'SELECT * FROM Users WHERE Name ="' + uName + '" AND Pass ="' + uPass + '"'

Wynik

SELECT * FROM Users WHERE Name ="John Doe" AND Pass ="myPass"

Haker może uzyskać dostęp do nazw użytkowników i haseł w bazie danych, po prostu wstawiając „ LUB „”= w polu tekstowym nazwy użytkownika lub hasła:

Nazwa Użytkownika:

Hasło:

Kod na serwerze utworzy prawidłową instrukcję SQL, taką jak ta:

Wynik

SELECT * FROM Users WHERE Name ="" or ""="" AND Pass ="" or ""=""

Powyższy kod SQL jest prawidłowy i zwróci wszystkie wiersze z tabeli „Użytkownicy”, ponieważ LUB „”=” jest zawsze PRAWDA.


Wstrzykiwanie SQL na podstawie wsadowych instrukcji SQL 

Większość baz danych obsługuje wsadowe instrukcje SQL.

Partia instrukcji SQL to grupa co najmniej dwóch instrukcji SQL oddzielonych średnikami.

Poniższa instrukcja SQL zwróci wszystkie wiersze z tabeli „Użytkownicy”, a następnie usunie tabelę „Dostawcy”.

Przykład

SELECT * FROM Users; DROP TABLE Suppliers

Spójrz na następujący przykład:

Przykład

txtUserId = getRequestString("UserId");
txtSQL = "SELECT * FROM Users WHERE UserId = " + txtUserId;

Oraz następujące dane wejściowe:

Identyfikator użytkownika:

Poprawna instrukcja SQL wyglądałaby tak:

Wynik

SELECT * FROM Users WHERE UserId = 105; DROP TABLE Suppliers;

Użyj parametrów SQL do ochrony

Aby chronić witrynę internetową przed wstrzyknięciem SQL, możesz użyć parametrów SQL.

Parametry SQL to wartości, które są dodawane do zapytania SQL w czasie wykonywania w kontrolowany sposób.

Przykład brzytwy ASP.NET

txtUserId = getRequestString("UserId");
txtSQL = "SELECT * FROM Users WHERE UserId = @0";
db.Execute(txtSQL,txtUserId);

Zauważ, że parametry są reprezentowane w instrukcji SQL przez znacznik @.

Silnik SQL sprawdza każdy parametr, aby upewnić się, że jest on poprawny dla jego kolumny i czy jest traktowany dosłownie, a nie jako część wykonywanego kodu SQL.

Inny przykład

txtNam = getRequestString("CustomerName");
txtAdd = getRequestString("Address");
txtCit = getRequestString("City");
txtSQL = "INSERT INTO Customers (CustomerName,Address,City) Values(@0,@1,@2)";
db.Execute(txtSQL,txtNam,txtAdd,txtCit);

Przykłady

Poniższe przykłady pokazują, jak tworzyć sparametryzowane zapytania w niektórych popularnych językach internetowych.

WYBIERZ OŚWIADCZENIE W ASP.NET:

txtUserId = getRequestString("UserId");
sql = "SELECT * FROM Customers WHERE CustomerId = @0";
command = new SqlCommand(sql);
command.Parameters.AddWithValue("@0",txtUserId);
command.ExecuteReader();

WSTAW W OŚWIADCZENIE W ASP.NET:

txtNam = getRequestString("CustomerName");
txtAdd = getRequestString("Address");
txtCit = getRequestString("City");
txtSQL = "INSERT INTO Customers (CustomerName,Address,City) Values(@0,@1,@2)";
command = new SqlCommand(txtSQL);
command.Parameters.AddWithValue("@0",txtNam);
command.Parameters.AddWithValue("@1",txtAdd);
command.Parameters.AddWithValue("@2",txtCit);
command.ExecuteNonQuery();

WPISAĆ DO OŚWIADCZENIA W PHP:

$stmt = $dbh->prepare("INSERT INTO Customers (CustomerName,Address,City)
VALUES (:nam, :add, :cit)");
$stmt->bindParam(':nam', $txtNam);
$stmt->bindParam(':add', $txtAdd);
$stmt->bindParam(':cit', $txtCit);
$stmt->execute();