Is using addslashes against SQL injection safe?

Asked

Viewed 8,313 times

16

Use the addslashes() is it really safe against SQL injection? If not, tell me why.

I’ll wear mine like this addslashes()

<?php
$id = addslashes ( $_GET ["id"] ) ; /* Adicionei as barras */
echo stripslashes ( ( "$id" ) ) ; /* Removi as barras para exibir só as aspas no echo  */
?>

The way I will use is correct or will leave the system vulnerable?

4 answers

19


There are chances to leave the system vulnerable.

That one article, addslashes() Versus mysql_real_escape_string() cites a good reason for this.

In free translation:

If I want to attempt an SQL injection attack against a database Mysql, having escaped simple quotes with a backslash is a nuisance.

If you are using addslashes(), however, I am in luck. All I need to do is inject something like 0xbf27 and addslashes() will return 0xbf5c27, a valid multi-byte character followed by an apostrophe.

In other words, I can successfully inject an apostrophe, though escaped. That’s because 0xbf5c is interpreted as a single character, not two. Oops, there goes the backslash.

Related: How to prevent SQL code injection into my PHP code

As mentioned in the question above, prefer to use PDO or functions mysqli.

That one other article explains how to inject an SQL code when using the function addslashes.

The function addslashes is widely used to return a string with backslashes before characters that need to be cited in the database. These characters are simple quotes ', double quotes ", backslash \ and Null (the Null character).

  • The apostrophe ' returns \'.
  • ' OR '1' = '1 will return \' OR \'1\' = \'1.

In a single byte character set, the sequence \' is seen by Mysql as 0x5c and 0x27. That is to say \ 0 1 0 1 1 0 0 and ' 0 0 1 0 1 1 1.

In a set of multi-byte characters as Big5 one byte is used to ascii and two bytes are used for characters Big5. Sometimes there is a twist when a Mysql database, table or column uses a multi-byte character set. If a character Big5 has as last byte the 0x5c (value for backslash), we can fool the function addslashes to form the character of two bytes Big5 when the backslash is inserted.

  • ¿ 1 0 1 1 1 1 1
  • ' 0 0 1 0 1 1 1

When this sequence is passed through the function addslashes, an inverted bar is inserted: 0xBF¿ 0x5c\ 0x27'.

  • ¿ 1 0 1 1 1 1 1

  • \0 1 0 1 1 0 0

  • ' 0 0 1 0 1 1 1

Mysql with the character set Big5 interpret this string as being 0xbf5c (0xBF followed by 0x5c) and 0x27( ').

  • 1 0 1 1 1 1 1 1 0 1 0 1 1 1 0 0
  • ' 0 0 1 0 1 1 1

Note that the quote was not escaped when processed by Mysql, and will now act as a delimiter that will allow you to inject an SQL code.

This works for two reasons:

  1. The value 0xbf5c is a two byte character valid in Big5.
  2. The function addslashes does not check the character set in Mysql.

So some multi-byte character sets allows a targeted attack on addslashes which results in successful SQL injection.

Any multi-byte character defined with a value of 0x5c at last byte of a valid character was vulnerable. Vulnerable sets included Big5, GBK, and SJIS among others. This problem has been fixed in Mysql in 2006. But malicious people can explore ways to attack using these character sets.

  • 1

    Thank you very much!

  • 1

    Can I use this method then? $task = mysql_real_escape_string ( $_GET [ "task" ] ) ;

  • @Lucasc. S No problem, but use mysqli_real_escape_string just in case.

  • 1

    Thank you very much!

  • 1

    I’ll start using PDO, but I don’t want to leave the old mysql

  • 1

    it is interesting to use var_dump($task); to see the function

Show 1 more comment

3

This is not safe. Especially if you are not Mysql. Other databases do not use the same syntax and do not benefit from it. Mysql itself job documentation indicates that specific functions for each database should be used to prevent injections.

You are probably using Mysql. In this case you can even help, but helping is not enough. mysqli_real_escape_string() should be used instead, depending on how you are communicating with Mysql. It is specific to this database and better understands what can enable a code injection and knows how to avoid injection in a proper way. There are other possible ways.

There is a well-known page that shows a form of attack by injecting SQL making escape with bar.

-1

Always create an anti_injection function, is what I have always used for security in login systems

// Função de Eliminação de qalquer comando que possa invadir ou alterar o sistema de forma indevida
function anti_injection($sql){
    $sql = preg_replace(sql_regcase("/(from|select|insert|delete|where|drop table|show tables|#|\*|--|\\\\)/"), "" ,$sql); // remove palavras que contenham sintaxe sql
    $sql = trim($sql); // limpa espaços vazios
    $sql = strip_tags($sql); // tira tags html e php
    $sql = addslashes($sql); //  adiciona barras invertidas a um string
    return $sql;
}

That’s what I’ve been using, I’m only in a dilemma with the passwords in MD5, when I put the password in MD5 I don’t use anti_injection, because MD5 already "protects", and if using anti_injection the password can not contain * (asterisks) and in my case I use a lot * in passwords

  • 1

    It was not easier to use some parameterization system for the queries?

  • 2

    @LINQ worse than not using the native tool is to detonate valid strings in an attempt to sanitize.

  • @Bacco Neither had attempted it, nor that the answer already has 2 years hehehe

-1

You can also use preg_replace() this way:

$text = "090933ojeoejf'@#$%";

/* Para deixar apenas letras */
$text = preg_replace("/[^[:alpha:]_]/", "", $text);

/* Para deixar letras e números */
$text = preg_replace("/[^[:alnum:]_]/", "", $text); 

if you want more research about this function.

  • 2

    But what if there are allowed to be symbols? And how is this code safer than the function addslashes?

  • @Andersoncarloswoss surely this code is safer, than addslashes, because the likelihood of SQli is minimal since it uses symbols, in the part of symbols (accentuation, removing operators), is unnecessary and I see no use to pass symbols (removing operators) via $_GET as the author quoted

  • You add more characters to validate (allow), and as was said and exemplified above, addslashes() has requirements such as the binary character mentioned. I did some tests here but not in the database I did to remove data passed in the URL, and works very well.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.