2009-08-21 12 views
34

Rozpoczęto korzystanie z przygotowanych oświadczeń PDO nie tak dawno temu, i, jak rozumiem, robi to wszystko dla ciebie ucieczki/bezpieczeństwa.jak bezpieczne są przygotowane oświadczenia PDO

na przykład, zakładając, że $ _POST ['title'] jest polem formularza.

$title = $_POST['title']; 
$query = "insert into blog(userID, title) values (?, ?)" 
$st = $sql->prepare($query); 
$st->bindParam(1, $_SESSION['user']['userID'], PDO::PARAM_INT); 
$st->bindParam(2, $title); 
$st->execute(); 

Czy to naprawdę bezpieczne? Czy muszę robić cokolwiek innego? co jeszcze muszę wziąć pod uwagę?

Dzięki.

Odpowiedz

66

Ściśle mówiąc, nie ma właściwie potrzeby ucieczki, ponieważ wartość parametru nigdy nie jest interpolowana do ciągu zapytania.

Sposób działania parametrów zapytania polega na tym, że zapytanie jest wysyłane do serwera bazy danych po wywołaniu prepare(), a wartości parametrów są wysyłane później, po wywołaniu execute(). Są więc oddzielone od tekstowej formy zapytania. Nigdy nie ma możliwości wstrzyknięcia SQL (pod warunkiem, że PDO::ATTR_EMULATE_PREPARES jest fałszywe).

Tak, parametry zapytania pomagają uniknąć tej luki w zabezpieczeniach.

Czy są one w 100% odporne na wszelkie luki w zabezpieczeniach? Nie, oczywiście nie. Jak być może wiesz, parametr zapytania zajmuje tylko miejsce pojedynczej wartości literowej w wyrażeniu SQL. Nie można zrobić jednego parametru zastępczego dla listy wartości, na przykład:

SELECT * FROM blog WHERE userid IN (?); 

nie można użyć parametru, aby nazwy tabel lub nazwy kolumn dynamiczna:

SELECT * FROM blog ORDER BY ?; 

Można „t użyć parametru dla innego rodzaju składni SQL:

SELECT EXTRACT(? FROM datetime_column) AS variable_datetime_element FROM blog; 

Tak więc istnieje sporo przypadków, w których trzeba manipulować kwerendy jako ciąg, przed wywołaniem prepare(). W takich przypadkach nadal trzeba napisać kod ostrożnie, aby uniknąć iniekcji SQL.

+2

to była bardzo dobra informacja. Dziękuję Ci! – sqram

+0

Również "LIKE?" Jest poprawne, ale powinieneś unikać znaków używanych do dopasowywania. –

+0

Jeśli chodzi o "Nigdy nie ma możliwości wstrzyknięcia SQL (pod warunkiem, że PDO :: ATTR_EMULATE_PREPARES jest fałszywe).", Czy oznacza to, że emulowane emulacje PDO NIE są tak bezpieczne, jak natywne przygotowanie sterownika db? Jeśli tak, dlaczego? –

2

Jeśli chodzi o iniekcje SQL, uważam, że jest to najbezpieczniejsze rozwiązanie, szczególnie jeśli używane są stałe takie jak PDO :: PARAM_INT.

+6

Ten "specjalnie" potrzebuje trochę wyjaśnienia MOM. Prawdopodobnie nie chcesz powiedzieć, że jest w 95% bezpieczny, ale jeśli używasz stałych, jest w 100% bezpieczny. Jeśli bez stałych nie jest w 100% bezpieczny, nie jest bezpieczny.Jeśli jest to 100%, to nie jest "szczególnie" bezpieczne ze stałymi. Jaka jest różnica bezpieczeństwa między używaniem stałych a ich używaniem? – koen

9

Jest bezpieczny od iniekcji SQL.

Kilka rzeczy, to nie jest bezpieczne od:

  • Denial of Service (powodując nadmierne ilości wierszy zostać utworzone)
  • cross-site ataków skryptowych (jeśli tytuł jest zawsze echem z powrotem do innego użytkownika)

Bezpieczeństwo to coś więcej niż zapobieganie iniekcji SQL.

+0

proszę przyczynić się. co masz na myśli, jeśli tytuł powraca do innego użytkownika? – sqram

+3

Załóżmy, że masz tytuł blogów przechowywanych w bazie danych, a inni użytkownicy mogą wyświetlać te posty. Istnieje potencjalna możliwość ataku typu cross-site scripting polegająca na tym, że złośliwy użytkownik może stworzyć tytuł zawierający kod HTML, który osadza złośliwy skrypt na stronie, tak jak jest pokazywany innym użytkownikom witryny. – Yuliy

Powiązane problemy