0

PHP controls that with get_magic_quotes_gpc();, however my question is: Is any SQL injection protection enabled by default when installing PHP > 5.xxxx?

I guess it is since I can't recall if I have enabled/disabled any options when dealing with this issue. On a side note, MySQL doesn't seem to be doing anything, since I tried to execute some simple SQL injection in ASP.net/C# with MySQL (community...5 something...) And it worked.

However when I tried the same in PHP - it was escaped with . Also, that was attempted on Windows 7.

VLAZ
  • 26,331
  • 9
  • 49
  • 67
leo
  • 61
  • 1
  • 3

5 Answers5

5

Magic quotes is NOT a solution to prevent SQL Injection. It is by far insufficient to do proper character escaping. Just disable it and use prepared SQL statements with bound parameters. See example using PDO:

$pdo = new PDO("mysql:dbname=my_database", $dbUser, $dbPassword);
$sql = "SELECT * FROM users WHERE login = :login AND password = :password";
$stmt = $pdo->prepare($sql);
$stmt->bindValue("login", $_POST["login"]);
$stmt->bindValue("password", md5($_POST["password"]));
$stmt->execute();
$rows = $stmt->fetchAll();

Or be sure to properly escape the inserted values:

$pdo = new PDO("mysql:dbname=my_database", $dbUser, $dbPassword);
$sql = "SELECT * FROM users WHERE login = " . $pdo->quote($_POST["login"]) . " AND password = " . md5($_POST["password"]);
$rows = $pdo->query($sql)->fetchAll();
NikiC
  • 100,734
  • 37
  • 191
  • 225
Michał Niedźwiedzki
  • 12,859
  • 7
  • 45
  • 47
  • magic quotes should be disabled to preserve many web applications – AbiusX Mar 26 '11 at 22:27
  • OT: magic_quotes was never intended as security feature, yet incidentally a workable approach around PHP2/PHP3 when the primarily used databases didn't have multibyte charset support. – mario Mar 26 '11 at 22:28
  • 1
    @mario, please don't rewrite history. Magic quotes *were* intended as a security feature, but were obviously very poorly conceived. From the [official docs](http://www.php.net/manual/en/security.magicquotes.why.php), "So why did this feature exist? Simple, to help prevent SQL Injection." – Matthew Flaschen Mar 26 '11 at 22:31
  • 1
    @Matthew: Nopey nope. That's a late misattribution, not from the original docs. It was never intended for that. It's sole purpose was to make SQL work out of the box for noobs. Security didn't enter the picture until PHP3 introduced mysql_escape_string. http://objectmix.com/php/488380-magic-quotes.html "Magic Quotes is a convenience feature, not a security feature." – mario Mar 26 '11 at 22:35
  • well...whatever the intention was...the consequence is obvious. – leo Mar 26 '11 at 22:43
  • @mario, nope. The PHP developers [were claiming](http://replay.waybackmachine.org/20020601190637/http://www.php.net/manual/en/security.database.php) addslashes (the function run by magic quotes) improves security as early as almost a decade ago. There's nothing "late" or "misattributed" about that. That 2004 third-party forum post does nothing to contradict what the PHP devs were saying years earlier. I also think the current PHP devs know more about their *past* intentions than you. – Matthew Flaschen Mar 26 '11 at 23:29
  • @Matthew: It's actually not a forum post, but one of the earlier postings on the php mailing list about the topic. http://www.mail-archive.com/php-general@lists.php.net/msg158435.html - It's speculation either way without having the developers testify under drugs. But anyway, here is an even earlier reference: http://www.php.net/manual/phpfi2.php#escapes - `If the MAGIC_QUOTES variable is defined in the php.h file then these quotes will be automatically escaped making it easier to pass form data directly to msql queries.` Easier, not safer, was seemingly the goal when originally introduced. – mario Mar 26 '11 at 23:56
0

I recommend using http://php.net/manual/en/function.mysql-real-escape-string.php

I always use that whenever I get an input from a user.

Robert Hyatt
  • 781
  • 6
  • 11
0

SQL Injection can not be prevented by the PL or the Platform or even the Framework if the programmer doesn't keep it in mind,

There are two general programmatic methods of SQLi prevention :

  1. escape all dynamic strings and then concat them to the query (a little unsafe)
  2. use prepared statements to separate data from query

To use the former try :

$cond = mysql_real_escape_string($cond);
mysql_query("SELECT * FROM table WHERE {$cond}");

To use the latter, you could use PDO in PHP, which has prepared statements supported in.

AbiusX
  • 2,379
  • 20
  • 26
  • 2
    `mysql_escape_string` is deprecated because it doesn't handle character sets correctly. Worse, you're **discarding** the return value, meaning the call effectively does nothing and you use the original value in the query. – Matthew Flaschen Mar 26 '11 at 22:31
  • 1
    Is there any particular reason why you chose to rollback my edit, which corrected your absolutely incorrect approach to escaping? – NikiC Mar 26 '11 at 22:34
  • @nikic i didnt roll it back, i was just performing formatting on my text and should've unknowingly overwritten yours. – AbiusX Mar 26 '11 at 22:36
  • collation? On a side note, seems like many things are now deprecated as of php 5.3 check this: http://www.cvedetails.com/cve/CVE-2010-4700/ – leo Mar 26 '11 at 22:39
0

What all the other answers didn't metion, mysql_real_escape_string WORKS ONLY FOR STRINGS.
I've seen something like this at least over 9000 times.

$id=mysql_real_escape_string($_GET['id']);
mysql_query("SELECT foo FROM bar WHERE foobar=$id");

Keep in mind, that you should explicit cast to an int in this case.

$id=(int)$_GET['id'];
lawl0r
  • 840
  • 6
  • 16
-1

Use a database class which does basic sanitation in case you forgot to do it e.g. mysql_real_escape_string. I personally use something like this for text inputs (it is not recursive for arrays).

function escape($mixed){
    if(is_array($mixed)){
        foreach($mixed as $m => $value){
            $mixed[$m] = mysql_real_escape_string(htmlspecialchars($value, ENT_QUOTES, "UTF-8"));
        }
    }else{
        $mixed =  mysql_real_escape_string(htmlspecialchars($mixed, ENT_QUOTES, "UTF-8"));
    }
return $mixed;
}

But you should manually sanitize every input using preg_replace for example using this...

function replace($string, $type = "an", $custom = ""){
    switch($type){
        case "n": $regex = "0-9"; break;
        case "a": $regex = "a-zA-Z"; break;
        case "an": $regex = "a-zA-Z0-9"; break;
    }
    return preg_replace("#([^$regex$custom]+)#is", "", $string);
}


$_POST["phone"] = "+387 61 05 85 05";
$phone = replace($_POST["phone"], "n"); // 38761058505

There is no silver bullet for this.

Dejan Marjanović
  • 19,244
  • 7
  • 52
  • 66
  • The "in case you forgot" attitude pretty much always causes double-escaping. And you shouldn't confuse business validation (e.g. restricting an age field to a positive integer) with preventing SQL injection. For SQL injection, there pretty much is a silver bullet, the correct use of prepared statements. – Matthew Flaschen Mar 26 '11 at 23:53
  • I don't see mysql_real_escape_string twice anywhere. Ok, you're right, show me the silver bullet now. Well what is SQL injection then? – Dejan Marjanović Mar 26 '11 at 23:55
  • I didn't say you called it twice in the above code. But if you didn't forget (and passed in escaped data), it will be double-escaped. Also, there is no need to use `htmlspecialchars`, as that has no effect on SQL injection. See [this question](http://stackoverflow.com/questions/60174/best-way-to-stop-sql-injection-in-php) for more info, and a good example of using PDO prepared statements. – Matthew Flaschen Mar 27 '11 at 00:14
  • It has on XSS, but if you insert validated data (eg phone number in proper format), then there is no possibility for SQLi whatsoever. Thanks for the link. – Dejan Marjanović Mar 27 '11 at 00:20
  • right, but the appropriate time to use htmlspecialchars would be right before outputting it to HTML (*if* it gets outputted to HTML). – Matthew Flaschen Mar 27 '11 at 00:26