(PHP 4 >= 4.3.0, PHP 5)
mysql_real_escape_string — Dodaje znaki unikowe dla potrzeb poleceń SQL, biorąc po uwagę zestaw znaków używany w połączeniu.
Dodaje znaki unikowe do łańcucha_bez_znaków_unikowych, mając na uwadze aktualnie używany w połączeniu zestaw znaków by tak przygotowanego łańcucha można bezpiecznie użyc w funkcji mysql_query(). Jeśli dopisywane dane mają postać binarną wymagane jest użycie tej funkcji.
mysql_real_escape_string() wywołuje funkcję biblioteki MySQL mysql_real_escape_string, która dodaje lewe ukośniki (backslash) do następujących znaków: \x00, \n, \r, \, ', " and \x1a.
Użycie tej funkcji jest wymagane zawsze (poza kilkoma wyjątkami) przed wysłaniem zapytania do bazy danych aby zabezpieczyć dane.
Łańcuch, do którego zostaną dodane znaki unikowe.
Połączenie MySQL. Jeśli identyfikator połączenia nie zostanie podany, użyte zostanie ostatnie połączenie otwarte przez mysql_connect(). Jeśli połączenie takie nie zostanie znalezione, funkcja spróbuje nawiązać połączenie tak, jakby wywołana została funkcja mysql_connect() bez argumentów. Jeśli żadne połączenie nie zostanie znalezione lub nawiązane, wygenerowany zostanie błąd poziomu E_WARNING.
Zwraca łańcuch ze znakami unikowymi lub FALSE w przypadku błędu.
Przykład #1 Prosty przykład użycia mysql_real_escape_string()
<?php
// Connect
$link = mysql_connect('host', 'uzytkownik', 'haslo')
OR die(mysql_error());
// Zapytanie
$query = sprintf("SELECT * FROM uzytkownicy WHERE uzytkownik='%s' AND haslo='%s'",
mysql_real_escape_string($uzytkownik),
mysql_real_escape_string($haslo));
?>
Przykład #2 Przykład ataku SQL Injection
<?php
// Zapytanie pobierające pasujących użytkowników
$query = "SELECT * FROM uzytkownicy WHERE uzytkownik='{$_POST['nazwa_uzytkownika']}' AND haslo='{$_POST['haslo']}'";
mysql_query($query);
// Nie sprawdziliśmy zmiennej $_POST['haslo'], która może zawierać wszystko czego chciał użytkownik! Na przykład:
$_POST['nazwa_uzytkownika'] = 'aidan';
$_POST['haslo'] = "' OR ''='";
// Oznacza to, że zapytanie ma postać:
echo $query;
?>
Zapytanie wysłane do bazy danych:
SELECT * FROM users WHERE user='aidan' AND password='' OR ''=''
Zapytanie to pozwala zalogować się każdemu bez znajomości poprawnego hasła.
Przykład #3 Dobra praktyka tworzenia zapytań
Użycie mysql_real_escape_string() na każdej zmiennej zapobiegnie atakom SQL Injection. Przykład ten demonstruje dobrą praktykę tworzenia zapytań, niezależną od ustawień Magic Quotes.
<?php
if (isset($_POST['nazwa_produktu']) && isset($_POST['opis_produktu']) && isset($_POST['id_uzytkownika'])) {
// Połącz
$link = mysql_connect('host', 'uzytkownik', 'haslo');
if(!is_resource($link)) {
echo "Nie udało się połączyć z serwerem\n";
// ... logowanie błędów
} else {
// Odwróć efekty działania magic_quotes_gpc/magic_quotes_sybase na zmiennych jeśli opcje te są WŁĄCZONE.
if(get_magic_quotes_gpc()) {
$nazwa_produktu = stripslashes($_POST['nazwa_produktu']);
$opis_produktu = stripslashes($_POST['opis_produktu']);
} else {
$nazwa_produktu = $_POST['nazwa_produktu'];
$opis_produktu = $_POST['opis_produktu'];
}
// Stwórz bezpieczne zapytanie
$query = sprintf("INSERT INTO products (`nazwa`, `opis`, `id_uzytkownika`) VALUES ('%s', '%s', %d)",
mysql_real_escape_string($nazwa_produktu, $link),
mysql_real_escape_string($opis_produktu, $link),
$_POST['id_uzytkownika']);
mysql_query($query, $link);
if (mysql_affected_rows($link) > 0) {
echo "Produkt został dopisany\n";
}
}
} else {
echo "Wypełnij poprawnie formularz\n";
}
?>
Od teraz zapytanie będzie poprawne wykonywane, podczas gdy ataki SQL Injection nie będą działać.
Informacja: Przed użyciem mysql_real_escape_string() należy otworzyć połączenie z bazą danych, w innym przypadku błąd poziomu E_WARNING zostanie wygenerowany i zwrócona zostanie wartość false. Jeśli identyfikator_połączenia nie został zdefiniowany zostanie użyte ostatnie połączenie z bazą danych.
Informacja: Jeśli opcja magic_quotes_gpc została włączona, najpierw na danych należy użyć stripslashes(). Użycie tej funkcji samej spowoduje, że do danych zostaną dodane podwójne znaki unikowe.
Informacja: Jeśli funkcja ta nie zostanie użyta na danych, zapytanie będzie podatne na ataki SQL Injection Attacks.
Informacja: mysql_real_escape_string() nie dodaje znaków unikowych do % i _. Maski te (wildcard) są stosowane w zapytaniach MySQL w połączeniu z LIKE, GRANT lub REVOKE.