Mysql real escape string error

(PHP 4 >= 4.3.0, PHP 5)

(PHP 4 >= 4.3.0, PHP 5)

mysql_real_escape_stringЭкранирует специальные символы в строках для использования в выражениях SQL

Описание

mysql_real_escape_string(string $unescaped_string, resource $link_identifier = NULL): string

mysql_real_escape_string() вызывает библиотечную функцию MySQL
mysql_real_escape_string, которая добавляет обратную косую черту к следующим символам:
x00, n, r, ,
', " и x1a.

Эта функция должна всегда (за несколькими исключениями) использоваться для того,
чтобы обезопасить данные, вставляемые в запрос перед отправкой его в MySQL.

Предостережение

Безопасность: кодировка символов по умолчанию

Кодировка символов должна устанавливаться как на сервере, так и с помощью функции
mysql_set_charset(), чтобы влиять на поведение
mysql_real_escape_string(). Подробнее описано в разделе кодировка символов.

Список параметров

unescaped_string

Экранируемая строка.

link_identifier

Соединение MySQL. Если идентификатор соединения не был указан,
используется последнее соединение, открытое mysql_connect(). Если такое соединение не было найдено,
функция попытается создать таковое, как если бы mysql_connect() была вызвана без параметров.
Если соединение не было найдено и не смогло быть создано, генерируется ошибка уровня E_WARNING.

Возвращаемые значения

Возвращает строку, в которой экранированы все необходимые символы,
или false в случае возникновения ошибки.

Ошибки

Запуск этой функции без существующего соединения с MySQL вызовет ошибку уровня
E_WARNING. Данную функцию можно запускать только если есть
соединение с MySQL.

Примеры

Пример #1 Простой пример использования mysql_real_escape_string()


<?php
// Соединение
$link = mysql_connect('mysql_host', 'mysql_user', 'mysql_password')
OR die(
mysql_error());// Запрос
$query = sprintf("SELECT * FROM users WHERE user='%s' AND password='%s'",
mysql_real_escape_string($user),
mysql_real_escape_string($password));
?>

Пример #2 Пример использования mysql_real_escape_string() без наличия
соединения

Этот пример показывает, что произойдёт, если вызвать эту функцию без наличия
соединения с MySQL.


<?php
// Коннекта к MySQL нет$lastname = "O'Reilly";
$_lastname = mysql_real_escape_string($lastname);$query = "SELECT * FROM actors WHERE last_name = '$_lastname'";var_dump($_lastname);
var_dump($query);
?>

Результатом выполнения данного примера
будет что-то подобное:

Warning: mysql_real_escape_string(): No such file or directory in /this/test/script.php on line 5
Warning: mysql_real_escape_string(): A link to the server could not be established in /this/test/script.php on line 5

bool(false)
string(41) "SELECT * FROM actors WHERE last_name = ''"

Пример #3 Пример взлома с использованием SQL-инъекции


<?php
// Мы никак не проверили переменную $_POST['password'],
// а она может содержать совсем не то, что мы ожидали. Например:
$_POST['username'] = 'aidan';
$_POST['password'] = "' OR ''='";// посылаем запрос, чтобы проверить имя и пароль пользователя
$query = "SELECT * FROM users WHERE user='{$_POST['username']}' AND password='{$_POST['password']}'";
mysql_query($query);// посмотрим, какой запрос будет отправлен в MySQL:
echo $query;
?>

Запрос, который будет отправлен в MySQL:

SELECT * FROM users WHERE user='aidan' AND password='' OR ''=''

Это позволит кому угодно войти в систему без пароля.

Примечания

Замечание:

Функцию mysql_real_escape_string() можно использовать
только после того, как установлено соединение с MySQL. В противном
случае возникнет ошибка уровня E_WARNING, а функция
возвратит false. Если link_identifier не указан,
используется последнее открытое соединение.

Замечание:

Если magic_quotes_gpc включены,
то сначала данные следует обработать функцией stripslashes().
Если данную функцию применить к уже проэкранированным данным,
то данные будут проэкранированы дважды.

Замечание:

Если не пользоваться этой функцией, то запрос становится уязвимым для
взлома с помощью SQL-инъекций.

Замечание:

mysql_real_escape_string() не экранирует символы
% и _. Эти знаки являются масками
групп символов в операторах MySQL LIKE,
GRANT и REVOKE.

Смотрите также

  • mysql_set_charset() — Устанавливает кодировку клиента
  • mysql_client_encoding() — Возвращает кодировку соединения
  • addslashes() — Экранирует строку с помощью слешей
  • stripslashes() — Удаляет экранирование символов
  • Директива magic_quotes_gpc
  • Директива magic_quotes_runtime

feedr

12 years ago


Just a little function which mimics the original mysql_real_escape_string but which doesn't need an active mysql connection. Could be implemented as a static function in a database class. Hope it helps someone.

<?php

function mysql_escape_mimic($inp) {

    if(
is_array($inp))

        return
array_map(__METHOD__, $inp);

    if(!empty(

$inp) && is_string($inp)) {

        return
str_replace(array('\', "", "n", "r", "'", '"', "x1a"), array('\\', '\0', '\n', '\r', "\'", '\"', '\Z'), $inp);

    }

    return

$inp;

}

?>


Walter Tross

10 years ago

nicolas

16 years ago


Note that mysql_real_escape_string doesn't prepend backslashes to x00, n, r, and and x1a as mentionned in the documentation, but actually replaces the character with a MySQL acceptable representation for queries (e.g. n is replaced with the 'n' litteral). (, ', and " are escaped as documented) This doesn't change how you should use this function, but I think it's good to know.

sam at numbsafari dot com

10 years ago


No discussion of escaping is complete without telling everyone that you should basically never use external input to generate interpreted code. This goes for SQL statements, or anything you would call any sort of "eval" function on.

So, instead of using this terribly broken function, use parametric prepared statements instead.

Honestly, using user provided data to compose SQL statements should be considered professional negligence and you should be held accountable by your employer or client for not using parametric prepared statements.

What does that mean?

It means instead of building a SQL statement like this:

"INSERT INTO X (A) VALUES(".$_POST["a"].")"

You should use mysqli's prepare() function (http://php.net/manual/en/mysqli.prepare.php) to execute a statement that looks like this:

"INSERT INTO X (A) VALUES(?)"

NB: This doesn't mean you should never generate dynamic SQL statements. What it means is that you should never use user-provided data to generate those statements. Any user-provided data should be passed through as parameters to the statement after it has been prepared.

So, for example, if you are building up a little framework and want to do an insert to a table based on the request URI, it's in your best interest to not take the $_SERVER['REQUEST_URI'] value (or any part of it) and directly concatenate that with your query. Instead,  you should parse out the portion of the $_SERVER['REQUEST_URI'] value that you want, and map that through some kind of function or associative array to a non-user provided value. If the mapping produces no value, you know that something is wrong with the user provided data.

Failing to follow this has been the cause of a number of SQL-injection problems in the Ruby On Rails framework, even though it uses parametric prepared statements. This is how GitHub was hacked at one point. So, no language is immune to this problem. That's why this is a general best practice and not something specific to PHP and why you should REALLY adopt it.

Also, you should still do some kind of validation of the data provided by users, even when using parametric prepared statements. This is because that user-provided data will often become part of some generated HTML, and you want to ensure that the user provided data isn't going to cause security problems in the browser.


rohankumar dot 1524 at gmail dot com

1 year ago


There is requirement for old projects which are using `mysql_escape_string`, and upgrading the PHP version to 7 and above. Basically this happens in maintenance projects where we don't know how many files the functions are used in application. We can use [mysqli.real-escape-string][1] for the function:

If you have a typical connection file like `conn.php`

    $conn = new mysqli($host, $user, $password, $db);
    // may be few more lines to handle the $conn
    if (!function_exists('mysql_escape_string')) {
        function mysql_escape_string($sting){ // if mysql_escape_string not available
            return $conn->real_escape_string($string); // escape using the $conn instance
        }
    }

  [1]: https://www.php.net/manual/en/mysqli.real-escape-string.php


strata_ranger at hotmail dot com

13 years ago


There's an interesting quirk in the example #2 about SQL injection:  AND takes priority over OR, so the injected query actually executes as WHERE (user='aidan' AND password='') OR ''='', so instead of returning a database record corresponding to an arbitrary username (in this case 'aidan'), it would actually return ALL database records.  In no particular order.  So an attacker might be able to log in as any account, but not necessarily with any control over which account it is.

Of course a potential attacker could simply modify their parameters to target specific users of interest:

<?php// E.g. attacker's values
$_POST['username'] = '';
$_POST['password'] = "' OR user = 'administrator' AND '' = '";// Malformed query
$query = "SELECT * FROM users WHERE user='$_POST[username]' AND password='$_POST[password]'";

echo

$query;// The query sent to MySQL would read:
// SELECT * FROM users WHERE user='' AND password='' OR user='administrator' AND ''='';
// which would allow anyone to gain access to the account named 'administrator'
?>


plgs at ozemail dot com dot au

13 years ago


Don't forget that if you're using Mysqli (ie, the "improved" Mysql extension) then you need to use the corresponding mysqli function mysqli_real_escape_string().  The parameter order is also different.

Aljo

5 years ago


@feedr
I elaborated his note as following:
$string = "asdasdx1aas\\\\dasd'asdasdna''sdasdad";
$array1 = array('\\\\', '', 'n', 'r', "'", '"', 'x1a');
$array2 = array('\\\\\\\\', '\', '\n', '\r', "\'", '\"', '\Z');
echo($string);
echo(PHP_EOL);
for( $i=0; $i<count($array1); $i++ ) {
    if ($i==0)
    $p = '/(?<!\\)'.$array1[$i].'(?!\\)/';
    else
    $p = '/(?<!\\)'.$array1[$i].'/';
    echo($i);
    echo($p);
    echo( $array2[$i]);
    $string = preg_replace($p, $array2[$i], $string);
    echo("t");
    echo($string);
    echo(PHP_EOL);
}
echo(PHP_EOL);
echo($string);

jonnie

5 years ago


To Quote Sam at Numb Safari

[ "No discussion of escaping is complete without telling everyone that you should basically never use external input to generate interpreted code. This goes for SQL statements, or anything you would call any sort of "eval" function on.

So, instead of using this terribly broken function, use parametric prepared statements instead.

Honestly, using user provided data to compose SQL statements should be considered professional negligence and you should be held accountable by your employer or client for not using parametric prepared statements." ]

Sam is right........

However I do not think it is sensible to stop all sanitising and simply pass the task on to parametric prepared statements.

A particular developer working in a particular situation will always know more about valid input (specific to that context).

If you ask a user to pass in a value you have already given them and you know that all such values start AB****** and the string should be of length 7 or 11 but never any other length then you have the basis of a good pre-sanitiser - different allowable lengths of a string might indicate legacy data.

I would never want to simply pass the rubbish that a malicious user may have passed in through a form to the parametric prepared statements, I would always want to do my own sanity checks first and in some cases these may err on the side of caution and simply choose to abort the Database op completely.

That way my DB does not get clogged up with unsafe statements made safe - it simply does not get clogged up which is better.

Security in layers - sanitisation and validation should still be considered in every situation BEFORE using prepared statements.

In addition as far as I can read into the official doc
==============================================

"Escaping and SQL injection

Bound variables are sent to the server separately from the query and thus cannot interfere with it. The server uses these values directly at the point of execution, after the statement template is parsed. Bound parameters do not need to be escaped as they are never substituted into the query string directly"

That suggests to me that danger is avoided in the internals by alternative handling not by nullification.

This means that a large project with incomplete conversion to prepared statements, legacy code in different parts of an organisation or servers talking to one another could all pass on the bad news from an immune location or situation to one that is not immune.

As long as the sanitisation is competently performed without incurring additional risks then personally I would stick with certain layers of sanitisation and then call the prepared statements.


presto dot dk at gmail dot com

13 years ago


If you want to make sure that the ID you're using to do a query is a number, use sprint() of (int) or intval(), but don't use mysql_real_escape_string.

There is no difference between ISO-8859-1's number 10 and UTF-8's number 10.


Содержание

  1. mysql_real_escape_string
  2. Description
  3. Security: the default character set
  4. Parameters
  5. Return Values
  6. Errors/Exceptions
  7. Examples
  8. Notes
  9. See Also
  10. User Contributed Notes 10 notes
  11. mysqli::real_escape_string
  12. mysqli_real_escape_string
  13. Описание
  14. Безопасность: набор символов по умолчанию
  15. Список параметров
  16. Возвращаемые значения
  17. Примеры
  18. Смотрите также
  19. User Contributed Notes 9 notes

mysql_real_escape_string

(PHP 4 >= 4.3.0, PHP 5)

mysql_real_escape_string — Escapes special characters in a string for use in an SQL statement

This extension was deprecated in PHP 5.5.0, and it was removed in PHP 7.0.0. Instead, the MySQLi or PDO_MySQL extension should be used. See also MySQL: choosing an API guide. Alternatives to this function include:

Description

Escapes special characters in the unescaped_string , taking into account the current character set of the connection so that it is safe to place it in a mysql_query() . If binary data is to be inserted, this function must be used.

mysql_real_escape_string() calls MySQL’s library function mysql_real_escape_string, which prepends backslashes to the following characters: x00 , n , r , , ‘ , » and x1a .

This function must always (with few exceptions) be used to make data safe before sending a query to MySQL.

Security: the default character set

The character set must be set either at the server level, or with the API function mysql_set_charset() for it to affect mysql_real_escape_string() . See the concepts section on character sets for more information.

Parameters

The string that is to be escaped.

The MySQL connection. If the link identifier is not specified, the last link opened by mysql_connect() is assumed. If no such link is found, it will try to create one as if mysql_connect() had been called with no arguments. If no connection is found or established, an E_WARNING level error is generated.

Return Values

Returns the escaped string, or false on error.

Errors/Exceptions

Executing this function without a MySQL connection present will also emit E_WARNING level PHP errors. Only execute this function with a valid MySQL connection present.

Examples

Example #1 Simple mysql_real_escape_string() example

// Connect
$link = mysql_connect ( ‘mysql_host’ , ‘mysql_user’ , ‘mysql_password’ )
OR die( mysql_error ());

// Query
$query = sprintf ( «SELECT * FROM users WHERE user=’%s’ AND password=’%s’» ,
mysql_real_escape_string ( $user ),
mysql_real_escape_string ( $password ));
?>

Example #2 mysql_real_escape_string() requires a connection example

This example demonstrates what happens if a MySQL connection is not present when calling this function.

// We have not connected to MySQL

$lastname = «O’Reilly» ;
$_lastname = mysql_real_escape_string ( $lastname );

$query = «SELECT * FROM actors WHERE last_name = ‘ $_lastname ‘» ;

var_dump ( $_lastname );
var_dump ( $query );
?>

The above example will output something similar to:

Example #3 An example SQL Injection Attack

// We didn’t check $_POST[‘password’], it could be anything the user wanted! For example:
$_POST [ ‘username’ ] = ‘aidan’ ;
$_POST [ ‘password’ ] = «‘ OR »=’» ;

// Query database to check if there are any matching users
$query = «SELECT * FROM users WHERE user=’ < $_POST [ ‘username’ ]>‘ AND password=’ < $_POST [ ‘password’ ]>‘» ;
mysql_query ( $query );

// This means the query sent to MySQL would be:
echo $query ;
?>

The query sent to MySQL:

This would allow anyone to log in without a valid password.

Notes

A MySQL connection is required before using mysql_real_escape_string() otherwise an error of level E_WARNING is generated, and false is returned. If link_identifier isn’t defined, the last MySQL connection is used.

If magic_quotes_gpc is enabled, first apply stripslashes() to the data. Using this function on data which has already been escaped will escape the data twice.

If this function is not used to escape data, the query is vulnerable to SQL Injection Attacks.

Note: mysql_real_escape_string() does not escape % and _ . These are wildcards in MySQL if combined with LIKE , GRANT , or REVOKE .

See Also

  • mysql_set_charset() — Sets the client character set
  • mysql_client_encoding() — Returns the name of the character set
  • addslashes() — Quote string with slashes
  • stripslashes() — Un-quotes a quoted string
  • The magic_quotes_gpc directive
  • The magic_quotes_runtime directive

User Contributed Notes 10 notes

Just a little function which mimics the original mysql_real_escape_string but which doesn’t need an active mysql connection. Could be implemented as a static function in a database class. Hope it helps someone.

function mysql_escape_mimic ( $inp ) <
if( is_array ( $inp ))
return array_map ( __METHOD__ , $inp );

No discussion of escaping is complete without telling everyone that you should basically never use external input to generate interpreted code. This goes for SQL statements, or anything you would call any sort of «eval» function on.

So, instead of using this terribly broken function, use parametric prepared statements instead.

Honestly, using user provided data to compose SQL statements should be considered professional negligence and you should be held accountable by your employer or client for not using parametric prepared statements.

What does that mean?

It means instead of building a SQL statement like this:

«INSERT INTO X (A) VALUES(«.$_POST[«a»].»)»

You should use mysqli’s prepare() function (http://php.net/manual/en/mysqli.prepare.php) to execute a statement that looks like this:

«INSERT INTO X (A) VALUES(?)»

NB: This doesn’t mean you should never generate dynamic SQL statements. What it means is that you should never use user-provided data to generate those statements. Any user-provided data should be passed through as parameters to the statement after it has been prepared.

So, for example, if you are building up a little framework and want to do an insert to a table based on the request URI, it’s in your best interest to not take the $_SERVER[‘REQUEST_URI’] value (or any part of it) and directly concatenate that with your query. Instead, you should parse out the portion of the $_SERVER[‘REQUEST_URI’] value that you want, and map that through some kind of function or associative array to a non-user provided value. If the mapping produces no value, you know that something is wrong with the user provided data.

Failing to follow this has been the cause of a number of SQL-injection problems in the Ruby On Rails framework, even though it uses parametric prepared statements. This is how GitHub was hacked at one point. So, no language is immune to this problem. That’s why this is a general best practice and not something specific to PHP and why you should REALLY adopt it.

Also, you should still do some kind of validation of the data provided by users, even when using parametric prepared statements. This is because that user-provided data will often become part of some generated HTML, and you want to ensure that the user provided data isn’t going to cause security problems in the browser.

There is requirement for old projects which are using `mysql_escape_string`, and upgrading the PHP version to 7 and above. Basically this happens in maintenance projects where we don’t know how many files the functions are used in application. We can use [mysqli.real-escape-string][1] for the function:

If you have a typical connection file like `conn.php`

$conn = new mysqli($host, $user, $password, $db);
// may be few more lines to handle the $conn
if (!function_exists(‘mysql_escape_string’)) <
function mysql_escape_string($sting) < // if mysql_escape_string not available
return $conn->real_escape_string($string); // escape using the $conn instance
>
>

There’s an interesting quirk in the example #2 about SQL injection: AND takes priority over OR, so the injected query actually executes as WHERE (user=’aidan’ AND password=») OR »=», so instead of returning a database record corresponding to an arbitrary username (in this case ‘aidan’), it would actually return ALL database records. In no particular order. So an attacker might be able to log in as any account, but not necessarily with any control over which account it is.

Of course a potential attacker could simply modify their parameters to target specific users of interest:

// E.g. attacker’s values
$_POST [ ‘username’ ] = » ;
$_POST [ ‘password’ ] = «‘ OR user = ‘administrator’ AND » = ‘» ;

// Malformed query
$query = «SELECT * FROM users WHERE user=’ $_POST [ username ] ‘ AND password=’ $_POST [ password ] ‘» ;

// The query sent to MySQL would read:
// SELECT * FROM users WHERE user=» AND password=» OR user=’administrator’ AND »=»;
// which would allow anyone to gain access to the account named ‘administrator’

To Quote Sam at Numb Safari

[ «No discussion of escaping is complete without telling everyone that you should basically never use external input to generate interpreted code. This goes for SQL statements, or anything you would call any sort of «eval» function on.

So, instead of using this terribly broken function, use parametric prepared statements instead.

Honestly, using user provided data to compose SQL statements should be considered professional negligence and you should be held accountable by your employer or client for not using parametric prepared statements.» ]

However I do not think it is sensible to stop all sanitising and simply pass the task on to parametric prepared statements.

A particular developer working in a particular situation will always know more about valid input (specific to that context).

If you ask a user to pass in a value you have already given them and you know that all such values start AB****** and the string should be of length 7 or 11 but never any other length then you have the basis of a good pre-sanitiser — different allowable lengths of a string might indicate legacy data.

I would never want to simply pass the rubbish that a malicious user may have passed in through a form to the parametric prepared statements, I would always want to do my own sanity checks first and in some cases these may err on the side of caution and simply choose to abort the Database op completely.

That way my DB does not get clogged up with unsafe statements made safe — it simply does not get clogged up which is better.

Security in layers — sanitisation and validation should still be considered in every situation BEFORE using prepared statements.

In addition as far as I can read into the official doc
==============================================

«Escaping and SQL injection

Bound variables are sent to the server separately from the query and thus cannot interfere with it. The server uses these values directly at the point of execution, after the statement template is parsed. Bound parameters do not need to be escaped as they are never substituted into the query string directly»

That suggests to me that danger is avoided in the internals by alternative handling not by nullification.

This means that a large project with incomplete conversion to prepared statements, legacy code in different parts of an organisation or servers talking to one another could all pass on the bad news from an immune location or situation to one that is not immune.

As long as the sanitisation is competently performed without incurring additional risks then personally I would stick with certain layers of sanitisation and then call the prepared statements.

Источник

mysqli::real_escape_string

mysqli_real_escape_string

(PHP 5, PHP 7, PHP 8)

mysqli::real_escape_string — mysqli::escape_string — mysqli_real_escape_string — Экранирует специальные символы в строке для использования в SQL-выражении, используя текущий набор символов соединения

Описание

Эта функция используется для создания допустимых в SQL строк, которые можно использовать в SQL выражениях. Заданная строка кодируется для создания экранированной строки SQL с учётом текущего набора символов подключения.

Безопасность: набор символов по умолчанию

Набор символов должен быть задан либо на стороне сервера, либо с помощью API-функции mysqli_set_charset() . В противном случае mysqli_real_escape_string() работать не будет. За дополнительной информацией обращайтесь к документации наборы символов.

Список параметров

Только для процедурного стиля: объект mysqli , полученный с помощью mysqli_connect() или mysqli_init() .

Строка, которую требуется экранировать.

Экранируемые символы NUL (ASCII 0), n, r, , ‘, «, и Control-Z .

Возвращаемые значения

Возвращает экранированную строку.

Примеры

Пример #1 Пример использования mysqli::real_escape_string()

( MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT );
$mysqli = new mysqli ( «localhost» , «my_user» , «my_password» , «world» );

/* этот запрос с экранированным $city будет работать */
$query = sprintf ( «SELECT CountryCode FROM City WHERE name=’%s’» ,
$mysqli -> real_escape_string ( $city ));
$result = $mysqli -> query ( $query );
printf ( «Возвращённые строки: %d.n» , $result -> num_rows );

/* этот запрос завершится ошибкой, потому что мы не экранировали $city */
$query = sprintf ( «SELECT CountryCode FROM City WHERE name=’%s’» , $city );
$result = $mysqli -> query ( $query );

( MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT );
$mysqli = mysqli_connect ( «localhost» , «my_user» , «my_password» , «world» );

/* этот запрос с экранированным $city будет работать */
$query = sprintf ( «SELECT CountryCode FROM City WHERE name=’%s’» ,
mysqli_real_escape_string ( $mysqli , $city ));
$result = mysqli_query ( $mysqli , $query );
printf ( «Возвращённые строки: %d.n» , mysqli_num_rows ( $result ));

/* этот запрос завершится ошибкой, потому что мы не экранировали $city */
$query = sprintf ( «SELECT CountryCode FROM City WHERE name=’%s’» , $city );
$result = mysqli_query ( $mysqli , $query );

Результатом выполнения данных примеров будет что-то подобное:

Смотрите также

User Contributed Notes 9 notes

Presenting several UTF-8 / Multibyte-aware escape functions.

These functions represent alternatives to mysqli::real_escape_string, as long as your DB connection and Multibyte extension are using the same character set (UTF-8), they will produce the same results by escaping the same characters as mysqli::real_escape_string.

This is based on research I did for my SQL Query Builder class:
https://github.com/twister-php/sql

/**
* Returns a string with backslashes before characters that need to be escaped.
* As required by MySQL and suitable for multi-byte character sets
* Characters encoded are NUL (ASCII 0), n, r, , ‘, «, and ctrl-Z.
*
* @param string $string String to add slashes to
* @return $string with « prepended to reserved characters
*
* @author Trevor Herselman
*/
if ( function_exists ( ‘mb_ereg_replace’ ))
<
function mb_escape ( string $string )
<
return mb_ereg_replace ( ‘[x00x0Ax0Dx1Ax22x27x5C]’ , ‘\’ , $string );
>
> else <
function mb_escape ( string $string )
<
return preg_replace ( ‘

?>

Characters escaped are (the same as mysqli::real_escape_string):

Note: preg_replace() is in PCRE_UTF8 (UTF-8) mode (`u`).

When escaping strings for `LIKE` syntax, remember that you also need to escape the special characters _ and %

So this is a more fail-safe version (even when compared to mysqli::real_escape_string, because % characters in user input can cause unexpected results and even security violations via SQL injection in LIKE statements):

/**
* Returns a string with backslashes before characters that need to be escaped.
* As required by MySQL and suitable for multi-byte character sets
* Characters encoded are NUL (ASCII 0), n, r, , ‘, «, and ctrl-Z.
* In addition, the special control characters % and _ are also escaped,
* suitable for all statements, but especially suitable for `LIKE`.
*
* @param string $string String to add slashes to
* @return $string with « prepended to reserved characters
*
* @author Trevor Herselman
*/
if ( function_exists ( ‘mb_ereg_replace’ ))
<
function mb_escape ( string $string )
<
return mb_ereg_replace ( ‘[x00x0Ax0Dx1Ax22x25x27x5Cx5F]’ , ‘\’ , $string );
>
> else <
function mb_escape ( string $string )
<
return preg_replace ( ‘

?>

Additional characters escaped:

The original MySQL `utf8` character-set (for tables and fields) only supports 3-byte sequences.
4-byte characters are not common, but I’ve had queries fail to execute on 4-byte UTF-8 characters, so you should be using `utf8mb4` wherever possible.

However, if you still want to use `utf8`, you can use the following function to replace all 4-byte sequences.

// Modified from: https://stackoverflow.com/a/24672780/2726557
function mysql_utf8_sanitizer ( string $str )
<
return preg_replace ( ‘/[x<10000>-x<10ffff>]/u’ , «xEFxBFxBD» , $str );
>
?>

Pick your poison and use at your own risk!

Note that this function will NOT escape _ (underscore) and % (percent) signs, which have special meanings in LIKE clauses.

As far as I know there is no function to do this, so you have to escape them yourself by adding a backslash in front of them.

Caution when escaping the % and _ wildcard characters. According to an often overlooked note at the bottom of:

the escape sequences % and _ will ONLY be interpreted as % and _, *if* they occur in a LIKE! (Same for MySQL 8.0)

In regular string literals, the escape sequences % and _ are treated as those two character pairs. So if those escape sequences appear in a WHERE «=» instead of a WHERE LIKE, they would NOT match a single % or _ character!

Consequently, one MUST use two «escape» functions: The real-escape-string (or equivalent) for regular string literals, and an amended escape function JUST for string literals that are intended to be used in LIKE.

Note that the “like” operator requires an *additional* level of escaping for its special characters, *on top of* that performed by mysql_escape_string. But there is no built-in function for performing this escaping. Here is a function that does it:

function escape_sql_wild($s)
/* escapes SQL pattern wildcards in s. */
<
$result = array();
foreach(str_split($s) as $ch)
<
if ($ch == «\» || $ch == «%» || $ch == «_»)
<
$result[] = «\»;
> /*if*/
$result[] = $ch;
> /*foreach*/
return
implode(«», $result);
> /*escape_sql_wild*/

Источник

PHP 4 >= 4.3.0, PHP 5

mysql_real_escape_string — Escapes special characters in a string for use in an SQL statement

mysql_real_escape_string(
string$unescaped_string,
[resource$link_identifier = NULL] ): string

Escapes special characters in the unescaped_string,
taking into account the current character set of the connection so that it
is safe to place it in a mysql_query. If binary data
is to be inserted, this function must be used.

mysql_real_escape_string calls MySQL’s library function
mysql_real_escape_string, which prepends backslashes to the following characters:
x00, n,
r, , ‘,
» and x1a.

This function must always (with few exceptions) be used to make data
safe before sending a query to MySQL.

Caution:

Security: the default character set

The character set must be set either at the server level, or with
the API function mysql_set_charset for it to affect
mysql_real_escape_string. See the concepts section
on character sets for
more information.

Parameters

unescaped_string

The string that is to be escaped.

link_identifier

The MySQL connection. If the
link identifier is not specified, the last link opened by
mysql_connect is assumed. If no such link is found, it
will try to create one as if mysql_connect had been called
with no arguments. If no connection is found or established, an
E_WARNING level error is generated.

Return Values

Returns the escaped string, or false on error.

Exceptions and Errors

Executing this function without a MySQL connection present will
also emit E_WARNING level PHP errors. Only
execute this function with a valid MySQL connection present.

Notes

Note:

A MySQL connection is required before using
mysql_real_escape_string otherwise an error of
level E_WARNING is generated, and false is
returned. If link_identifier isn’t defined, the
last MySQL connection is used.

Note:

If magic_quotes_gpc is enabled,
first apply stripslashes to the data. Using this function
on data which has already been escaped will escape the data twice.

Note:

If this function is not used to escape data, the query is vulnerable to
SQL Injection Attacks.

Note:

mysql_real_escape_string does not escape
% and _. These are wildcards in
MySQL if combined with LIKE, GRANT,
or REVOKE.

Related Functions

Example of mysql_real_escape_string

Show all examples
for mysql_real_escape_string

mysql_real_escape_string

Introduction to mysql_real_escape_string

mysql_real_escape_string() is used to escape special characters like ‘’,’n’ etc in a query string before sending the query to mysql server. The given unescaped_string is encoded and returns an escaped sql string as an output. mysql_real_escape_string() function returns the length of the encoded or escaped sqlstring. This mysql_real_escape_string() function is used to Escapes special characters like ,n in a string that can further used in the sql statement.

Syntax and Parameters

Below is the syntax of the mysql_real_escape_string() function:

String mysql_real_escape_string(string unescaped_string,resource link_identifier= =NULL);

This function contains two arguments, first is unescaped_string and the second is link identifier.

mysql_real_escape_string calls the function, which adds a backslashes before the following special characters: x00, n, r, , ‘, ” and x1a. This function must always be written with an exception to through an exception when any abnormal behavior happens to the data and to save the data before sending a query to mysql.

Parameters

unescaped_string: The given string needs to be escaped or encoded.

link_identifier: It is used to specify the link for establishing a connection. If the link identifier is not stated, the last link opened by mysql_connect is supposed. If no link is established, it will create one link with mysql_connect function with no arguments passed. At last, after doing all this, then also if we are failing in establishing the connection with the link it will display an e-warning error message in the console.

Return Values: it will either returns an escaped string as an output if everything will be right otherwise it will display an error message or returns FALSE flag in the output console.

Errors/Exceptions: If we execute the mysql_real_escape_string function without establishing the connection of function with the mysql server then it will throw an E_warning message. mysql_real_escape_string() function will only get executed when the full connection is established with the mysql server. Executing this function without a mysql connection present will also through E_warning as an error message. Only execute this function with a valid mysql connection present. It is very important that the function is able to escape the string otherwise the query gets susceptible to sqlinjection (sqli) attacks.

Sql injection: It is a mechanism that allows an attacker or hacker to view data that cannot be easily retrieved. This includes data of the other users or the data that only the application access it itself.

The special characters that cannot be escaped by mysql_real_escape_string function are % (percentage)and _(underscore).If these two characters are combined with a clause like grant, revoke, and like these are called wildcards in MySQL. _(underscore matches a single character in as string)

%: matches any number of characters or zero numbers of characters in string.

It adds a backslash before every special character in the string given. List of special characters that mysql_real_escape_string can encode are shown below:

0x00 (null)
Newline (n)
Carriage return (r)
Double quotes (")
Backslash ()
0x1A (Ctrl+Z)

We should be very careful while using mysql_real_escape_string() function to encode numeric parameters since they are usually written in the query without quotes. Below sample code shows if the mysql_real_escape _string is not implemented properly it could lead to sql injection.

Examples of mysql_real_escape_string

Following are the examples are given below:

Example #1

Suppose,the numeric user input is

500 OR 1=1

Sanitizing input

$prod_id = mysql_real_escape_string($_GET['id']);

Below is the generated query:

select prod_name from product where id=500 OR 1=1

The above-mentioned query will lead to sql injection since the id parameter is not enclosed within quotes.

Note: In order to avoid SQL injection(sqli), the parameter passed in the function must be enclosed between quotes.

Correction in the query to avoid sql injection is shown below in the query.

select prod_name from products where id=500 OR 1=1'

Since the id parameter in the above query is within quotes it will not lead to sql injection.

Like Operator

The function does not escape SQL wildcards for LIKE operator. Since these characters cannot be escaped, they are measured as classic wildcards by the LIKE operator: To prevent this from error we will use a backslash before the wildcard LIKE operator.

Example #2

User_input
Xyz’spq_

Escape all characters:

$value=mysql_real_esape_string($_GET[‘p’]);
$value=str_replace(“%”,”%”,$val);
$value=str_replace(“_”,”_”,$val);

Query

select * from employee where name LIKE ‘%Xyz’s pq_%’;

Disadvantages of the Function

Without any doubt, the mysql_real_escape_string function is the best way to avoid sql injections. But it has some demerits also like if we call the function so many times, the database server will get down slow. However, if we call the function twice on the same data by mistake we will have incorrect information or data in our database. Because of all these mentioned reasons, we can implement alternative solutions for example parameterized statements method or stored procedure.

Unsigned long mysql_real_escape_string(mysql * mysql,char * to,const char * from,unsigned long);

  • mysql: a mysqllink, that was connectedpreviously by mysql_init() or mysql_real_connect().
  • to: the encoded string. In the worst scenario, every character of the string needs to be escaped. Moreover, a 0 character will be appended.
  • from: a given string that needs to be encoded by the function.
  • long: the length of the given string.

Example #3

//establish connection with the mysql server
$link=mysql_connect(‘mysql_host’,’mysql_user’,’mysql_password’);
//sql query
$query=print(“select * from employee where user_name=’%s’ and pass-word=’’%s”,mysql_real_escape_string($user_name),mysql_real_escape_string($pass_word));
select * from employee where user_name=”%ta” and pass_word=”_123”

This query will login to the system with employee username ending with “ta” and starting with any number of characters and having a password with any single alphabet followed by 123.

Conclusions

In this article, we have learned how to use the mysql_real_escape_string() function. We have also learned to use the function to avoid sql injection. We have also learned about the specials characters that can be escaped by this function. The function is explained with various examples for a better understanding of the user.

Recommended Articles

This is a guide to mysql_real_escape_string. Here we also discuss syntax and parameter along with different examples and its code implementation. You may also have a look at the following articles to learn more –

  1. MySQL REVOKE
  2. MySQL DML
  3. MySQL Window Functions
  4. MySQL Foreign Key 

(PHP 4 >= 4.3.0, PHP 5)

mysql_real_escape_string — Escapes special characters in a string for use in a SQL statement

Description

string mysql_real_escape_string ( string unescaped_string [, resource link_identifier] )

Escapes special characters in the unescaped_string,
taking into account the current character set of the connection so that it
is safe to place it in a mysql_query(). If binary data
is to be inserted, this function must be used.

mysql_real_escape_string() calls MySQL’s library function
mysql_real_escape_string, which prepends backslashes to the following characters:
x00, n,
r, , ,
« and x1a.

This function must always (with few exceptions) be used to make data
safe before sending a query to MySQL.

Parameters

unescaped_string

The string that is to be escaped.


link_identifier

The MySQL connection. If the
link identifier is not specified, the last link opened by
mysql_connect() is assumed. If no such link is found, it
will try to create one as if mysql_connect() was called
with no arguments. If by chance no connection is found or established, an
E_WARNING level warning is generated.

Return Values

Returns the escaped string, or FALSE on error.

Examples

Example 1. Simple mysql_real_escape_string() example

<?php
// Connect
$link = mysql_connect('mysql_host', 'mysql_user', 'mysql_password')
    OR die(mysql_error());

// Query
$query = sprintf("SELECT * FROM users WHERE user='%s' AND password='%s'",
            mysql_real_escape_string($user),
            mysql_real_escape_string($password));
?>

Example 2. An example SQL Injection Attack

<?php
// Query database to check if there are any matching users
$query = "SELECT * FROM users WHERE user='{$_POST['username']}' AND password='{$_POST['password']}'";
mysql_query($query);

// We didn't check $_POST['password'], it could be anything the user wanted! For example:
$_POST['username'] = 'aidan';
$_POST['password'] = "' OR ''='";

// This means the query sent to MySQL would be:
echo $query;
?>

The query sent to MySQL:

SELECT * FROM users WHERE user='aidan' AND password='' OR ''=''

This would allow anyone to log in without a valid password.

Example 3. A «Best Practice» query

Using mysql_real_escape_string() around each variable
prevents SQL Injection. This example demonstrates the «best practice»
method for querying a database, independent of the
Magic Quotes setting.

<?php
// Quote variable to make safe
function quote_smart($value)
{
    // Stripslashes
    if (get_magic_quotes_gpc()) {
        $value = stripslashes($value);
    }
    // Quote if not a number or a numeric string
    if (!is_numeric($value)) {
        $value = "'" . mysql_real_escape_string($value) . "'";
    }
    return $value;
}

// Connect
$link = mysql_connect('mysql_host', 'mysql_user', 'mysql_password')
    OR die(mysql_error());

// Make a safe query
$query = sprintf("SELECT * FROM users WHERE user=%s AND password=%s",
            quote_smart($_POST['username']),
            quote_smart($_POST['password']));

mysql_query($query);
?>

The query will now execute correctly, and SQL Injection attacks will not work.

Notes

Note:
A MySQL connection is required before using
mysql_real_escape_string() otherwise an error of
level E_WARNING is generated, and FALSE is
returned. If link_identifier isn’t defined, the
last MySQL connection is used.

Note:
If magic_quotes_gpc is enabled,
first apply stripslashes() to the data. Using this function
on data which has already been escaped will escape the data twice.

Note:
mysql_real_escape_string() does not escape
% and _. These are wildcards in
MySQL if combined with LIKE, GRANT,
or REVOKE.

See Also

Понравилась статья? Поделить с друзьями:
  • Mysql raise error
  • Mysql query error что значит
  • Mysql query error битрикс при авторизации
  • Mysql query error log
  • Mysql query error index column size too large the maximum column size is 767 bytes