2010-06-14 10 views
10

Skrypt jest w PHP i jako DB używam MySQL. Oto sam skrypt.Czy to zapytanie jest bezpieczne od wtrysku sql?

$unsafe_variable = $_GET["user-input"]; 
$sql=sprintf("INSERT INTO table (column) VALUES('%s')",$unsafe_variable); 
mysql_query($sql); 

Niektórzy ludzie mówią, że jeśli użytkownik przypisuje ;DROP TABLE blah; ciąg do zmiennej $ unsafe_variable usuwa tabelę.

Ale próbowałem ten przykład,

http://localhost/test.php?user-input=DROP%20TABLE%20my_table 

Ale nie usunąć tabelę, ale zamiast wstawiony nowy wiersz (;DROP TABLE blah;) w tabeli.

Czy ktoś mógłby mi wytłumaczyć, jak można zaatakować ten skrypt za pomocą wtyczek sql?

+3

'mysqli' lub' PDO' i ich sprawozdania przygotowanego będzie być lepszym wyborem. – Powerlord

+0

Wielkie dzięki dla wszystkich uczestników pytania. Zdałem sobie sprawę, że tylko z 'sprintf' nie możemy być pewni, że nasze zapytanie jest bezpieczne od ** sql-injections **. W tym konkretnym przykładzie ani ja, ani uczestnicy nie mogli przedstawić sposobu wykonania iniekcji sql. Ale znalazłem dobry przykład sql, gdzie możemy wykonać sql-injection, nawet jeśli używamy 'sprintf'. Przykład sql można znaleźć [tutaj] (http://php.net/manual/en/function.mysql-real-escape-string.php "PHP Online Manual"). Zobacz sekcję "Przykład # 2 Przykładowy atak iniekcyjny SQL" – Bakhtiyor

Odpowiedz

13

Ten konkretny zastrzyk nie zadziała, ponieważ funkcja PHP mysql_query zezwala tylko na jedno zapytanie na jedno połączenie. Jednak, następujące podmioty mogą działać, jeśli column ma podstawowy lub unikalny klucz:

$unsafe_variable = "admin') ON DUPLICATE KEY UPDATE password=MD5(CONCAT('knownsalt', 'newpassword'))#"; 

lepiej korzystać z rozwlekły mysql_real_escape_string funkcję:

$sql=sprintf("INSERT INTO table (column) VALUES(%s)", 
      mysql_real_escape_string($unsafe_variable)); 
mysql_query($sql); 
4

mysql_query() nie pozwala na wykonanie wielu zapytań w jednej funkcji. Więc nie możesz INSERT, a następnie UPUŚĆ tabelę. Ale nie powinieneś polegać na tym jako na "bezpieczeństwie". Zamiast tego użyj zapytań sparametryzowanych. Sprawdź bibliotekę PHP PDO.

Jednak mogą zmienić prawie wszystko, np. WYBRAĆ pole hasła z innej tabeli jako podzapytanie do umieszczenia w tym stole, aby mogli zobaczyć skrót.

+0

http://php.net/manual/en/function.mysql-query.php –

+0

Jakiś powód do objęcia funkcji? Przygotowane instrukcje są na ogół bezpieczniejsze niż 'mysql_real_escape_string'. –

1

Nie, sprintf nie ucieka wykorzystanie treści:

$unsafe_variable = mysql_real_escape_string($_GET["user-input"]); 
$sql=sprintf("INSERT INTO table (column) VALUES('%s')",$unsafe_variable); 
mysql_query($sql); 
1
mysql_real_escape_string($unsafe_variable) 
3

Podczas mysql_query pozwala jedno zapytanie do wykonania jedynie w ogóle to zapytanie nie jest bezpieczny. Przykładem niebezpiecznego wejścia, które wykorzystać zapytanie brzmi:

'); DROP TABLE my_table; -- 

'); na początku zamknie zapytanie i wstawić pustą wartość, ale pozwoli na dodatkowe pytania należy wykonać następujące wkładki. Następnie po upuszczeniu tabeli na końcu zaznacza się wszystko inne (np. Resztę zapytania) jako komentarz.

Aby bezpiecznie przygotować dane wejściowe do użycia w zapytaniu, należy użyć mysql_real_escape_string.

+0

Czy chcesz powiedzieć, że jeśli uruchomię ten skrypt [http: //authoringtool/test.php? User-input = '),% 20DROP% 20TABLE% 20my_table2;% 20--] to usunie my_table2 z mojego DB? Jeśli nie, daj mi prawdziwy przykład, jak to działa, ponieważ twój przykład nie usunął my_table2 :) – Bakhtiyor

+1

Jak wspomniano, 'mysql_query' nie obsługuje wykonywania wielu zapytań, ale powinieneś poprawnie zabezpieczyć swoje zapytanie. –

1

Niektórzy ludzie mówią, że jeśli użytkownik przydzieli, DROP TABLE blah; ciąg do zmiennej $ unsafe_variable usuwa tabelę.

To nie jest przypadek - ale jeśli nie rozumiesz dlaczego, to nie możesz stwierdzić, czy twój kod jest bezpieczny. Zamierzasz opublikować każdy wiersz tutaj, aby sprawdzić, czy jest bezpieczny?

Bez długich wyjaśnień na temat tego, co robi powyższy kod i jak go skompromitować (iniekcja SQL jest już bardzo dobrze udokumentowana w innym miejscu - spróbuj na początek Google'a) powinieneś ZAWSZE zapewnić, że wszelkie dane pozostawiające twój kod PHP są we właściwej reprezentacji dla tego, dokąd zmierza.

Na bazie danych MySQL, które oznacza:

1) używać wyjście mysql_real_escape_string (i upewnij się przekazać uchwyt zasobów prawej)

lub

2) wykorzystywać wiążącej parametr.

Właściwa dyskusja na temat ataków przy wtrysku kodu może z łatwością wypełnić kilkaset stron - trochę za dużo, aby odpowiedzieć w S.O. pytanie.

C.

0

myślę Przykładem może trzeba spróbować to http://localhost/test.php?user-input=';DROP%20TABLE%20my_table'

'); zamyka segment values('%s, a następnie wystawia nowe polecenie, drop table...

+0

To nie działa. – Bakhtiyor

Powiązane problemy