2011-01-23 20 views

Odpowiedz

4

Zdecydowanie NIE.

Choć pytanie w tytule jest niejednoznaczna i może być interpretowane jako „są dynamiczne zapytań MySQL z każdego to część prawidłowo sformatowany...”, a tym samym mieć pozytywną odpowiedź na pytanie w organizmie jest nie:

Gdybym prowadził wszystkie dane otrzymane od użytkownika poprzez mysql prawdziwej ucieczki byłoby tak samo bezpieczne, jak za pomocą przygotowany mysql oświadczenia?

Jeśli spojrzeć na to pytanie bliżej, można zrozumieć, że jest to po prostu magia cytuje wcielenie! Celem tej zhańbionej, przestarzałej i usuniętej funkcji jest "uruchomienie wszystkich danych wejściowych przez użytkownika".
Obecnie wszyscy wiedzą, że magiczne cytaty są złe. Dlaczego więc odpowiedź pozytywna?

Okay, wydaje się, że trzeba to jeszcze raz wyjaśnić, dlaczego masowe ucieczki są złe.

Źródłem problemu jest dość silne złudzenie, dzielone przez prawie każdego użytkownika PHP:
Wszyscy mają dziwne przekonanie, że ucieczka może zrobić coś na "niebezpiecznych bohaterach" (co oni?) Czyni je "bezpiecznymi" (w jaki sposób?). Nie trzeba dodawać, że to tylko kompletne śmieci.

Prawda jest taka:

  • ucieczki nie "zdezynfekować" czegokolwiek.
  • Ucieczka nie ma nic wspólnego z zastrzykami.
  • Ucieczka nie ma nic wspólnego z wprowadzaniem danych przez użytkownika.

ucieczki jest jedynie ciąg formatowania i nic innego.
Kiedy jej potrzebujesz - potrzebujesz jej pomimo możliwości wstrzyknięcia.
Gdy go nie potrzebujesz - nie pomoże to nawet przy wtrysku.

Mówiąc o różnicy z przygotowanych sprawozdań, istnieje co najmniej jeden problem (co już wspomniano wiele razy pod sql-injection tag):
kod jak ten

$clean = mysql_real_escape_string($_POST['some_dangerous_variable']); 
$query = "SELECT * FROM someTable WHERE somevalue = $clean"; 

pomoże NIE przed wstrzyknięciem.
Beause escaping to tylko narzędzie do formatowania ciągów znaków, a nie urządzenie zapobiegające wstrzyknięciu.
Idź.

Jednak uciekając mieć coś wspólnego z przygotowanych sprawozdań:
ich obu nie gwarantuje ci od zastrzyku jeśli

  • używasz go tylko przed wejściem notorycznie „user”, a nie jako ścisłe reguły dla budowania ŻADNE zapytanie, pomimo źródła danych.
  • w przypadku, gdy konieczne jest wstawienie danych, a nie identyfikatora lub słowa kluczowego.

Aby być bezpiecznym w tych okolicznościach, zobacz moją odpowiedź wyjaśniającą FULL sql injection protection how-to

Krótko mówiąc: można rozważyć bardziej bezpieczny tylko wtedy, gdy chcesz wykonać 2 zasadniczych korekt i jeden dodatek do swojej początkowej oświadczenie:

Gdybym prowadził wszystkie dane otrzymanych od użytkownika przez mysql prawdziwej ucieczki i zawsze ująć ją w cudzysłów (i, jak ircmaxell wspomniano, mysqli_set_charset() jest używany do mysqli_real_esc ape string() faktycznie wykonuje swoją pracę (w tak rzadkiej okazji użycia jakiegoś nieparzystego kodowania jak GBK) czy byłby tak bezpieczny, jak używanie przygotowanych instrukcji mysql?

Przestrzeganie tych zasad - tak, byłoby tak samo bezpieczne, jak przygotowywane przez native speakera stwierdzenia.

+0

Przepraszam; Nie próbuję być wybredna ani nic, tylko ... "Ta obie nie gwarantuje _..." –

+0

Proszę o wybaczenie, czy jesteś na gramatyce czy znaczeniu? Jeśli były - zapraszam do edycji mojego posta, byłbym wdzięczny. Nie jestem native speakerem i czasami nie widzę swoich wad. –

17

Tak, ale kwalifikowane tak.

Musisz poprawnie uciec 100% danych wejściowych. Musisz poprawnie ustawić zestawy znaków (jeśli używasz API C, musisz zadzwonić pod numer mysql_set_character_set() zamiast SET NAMES). Jeśli przegapisz jedną drobną rzecz, jesteś podatny na zranienie. Tak więc, tak długo, jak robisz wszystko dobrze ...

I to jest powód, dla którego wiele osób zarekomenduje przygotowane zapytania. Nie dlatego, że są bezpieczniejsze. Ale ponieważ są one bardziej wybaczające ...

+0

Przygotowane oświadczenia mają 2 podróże w obie strony, przygotuj się i wykonaj. Czy za każdym razem uruchamiać ciąg znaków mysql w zmiennej liczbie jako podróż w obie strony do bazy danych? – bshack

+0

@bshack: Nie wierzę w to. Używa zestawu znaków z otwartego połączenia, więc nie powinno to wymagać podróży w obie strony (ale mógłbym się mylić, nie sprawdziłem kodu źródłowego interfejsu API, tylko [dokumentacja] (http: // dev. mysql.com/doc/refman/5.0/en/mysql-real-escape-string.html)) ... – ircmaxell

+0

Czy jest jeszcze coś, co musisz zrobić poza ustawianiem zestawu znaków? – Michael

1

Myślę, że @ircmaxell dobrze to zrozumiał.

Jako kontynuacja, szukaj takich rzeczy.
kiedyś zrobić to cały czas:

<?php 

//sanitize the dangerous posted variable... 
$clean = mysql_real_escape_string($_POST['some_dangerous_variable']); 

//...and then forget to use it! 
$query = "SELECT * FROM someTable WHERE somevalue = '{$_POST['some_dangerous_variable']}'"; 

?> 

A kiedy mówię „czynili to”, co mam na myśli to, że w końcu poddał się i po prostu zaczął używać sprawozdania przygotowanego!

Powiązane problemy