这是否可以阻止sql注入

时间:2011-11-12 15:50:24

标签: php mysql sql-injection code-injection

我一直在使用下面的代码块来假设停止sql注入。当我第一次开始使用php时(这不是很久以前)有人给我看的东西

我将它放在每个页面中,就像打开时所示。我想知道它是否有效?我不知道如何测试sql注射

<?php

//Start the session

session_start();


//=======================open connection

include ('lib/dbconfig.php');

//===============This stops SQL Injection in POST vars

  foreach ($_POST as $key => $value) {
    $_POST[$key] = mysql_real_escape_string($value);
  }

  foreach ($_GET as $key => $value) {
    $_GET[$key] = mysql_real_escape_string($value);
  }

我的典型插入和更新查询如下所示

$insert = ("'$email','$pw','$company', '$co_description', '$categroy', '$url', '$street', '$suite', '$city', '$state', '$zip', '$phone', '$date', '$actkey'");

mysql_query("INSERT INTO provider (email, pw, company, co_description, category, url, street, suite, city, state, zip, phone, regdate, actkey) VALUES ($insert)") or die ('error ' . mysql_error());

mysql_query("UPDATE coupon SET head='$_POST[head]', fineprint='$_POST[fineprint]', exdate='$exdate', creationdate=NOW() WHERE id='$cid'") or die ('error ' . mysql_error());

5 个答案:

答案 0 :(得分:4)

这有点有效,但它不是最理想的 - 并非_GET和_POST中收到的所有数据都会进入数据库。有时您可能希望在页面上显示它,在这种情况下,mysql_real_escape_string只会伤害(相反,您需要htmlentities)。

我的经验法则是在将某些东西放入需要转义的上下文之前立即逃避。

在这种情况下,你最好只使用参数化查询 - 然后自动为你完成转义。

答案 1 :(得分:3)

这还不够。 你错过了cookie,$ _COOKIE变量。 2.如果您使用$ _REQUEST,则遇到麻烦。 3.您没有显示查询,当您将其置于查询中时,必须使用单引号''引用每个变量(特别是当数据被假定为整数时,您可能认为在这种情况下引用不是必需的,但这将是一个很大的错误)。 4.查询中使用的数据可能来自其他来源。

最好的方法是使用数据绑定并让驱动程序自动转义数据,这在PDO扩展中可用。

示例代码:

$PDO = new PDO('mysql:dbname=testdb;host=127.0.0.1' $user, $password);
$stmt = $PDO->prepare("SELECT * FROM test WHERE id=? AND cat=?");
$stmt->execute(array($_GET["id"], $_GET["cat"]));
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);

您还可以使用字符串键绑定数据:

$stmt = $PDO->prepare("SELECT * FROM test WHERE id = :id AND cat = :cat");
$stmt->execute(array(":id" => $_GET["id"], ":cat" => $_GET["cat"]));

如果您想学习PDO,您可能会发现我使用的这些辅助函数很有用:

http://www.gosu.pl/var/PDO.txt

PDO_Connect(dsn, user, passwd) - connects and sets error handling.
PDO_Execute(query [, params]) - only execute query, do not fetch any data.
PDO_InsertId() - last insert id.

PDO_FetchOne(query [, params]) - fetch 1 value, $count = PDO_FetchOne("SELECT COUNT(*) ..");
PDO_FetchRow(query [, params]) - fetch 1 row.
PDO_FetchAll(query [, params]) - fetch all rows.
PDO_FetchAssoc(query [, params]) - returns an associative array, when you need 1 or 2 cols

1) $names = PDO_FetchAssoc("SELECT name FROM table");
the returned array is: array(name, name, ...)

2) $assoc = PDO_FetchAssoc("SELECT id, name FROM table")
the returned array is: array(id=> name, id=>name, ...)

3) $assoc = PDO_FetchAssoc("SELECT id, name, other FROM table");
the returned array is: array(id=> array(id=>'',name=>'',other=>''), id=>array(..), ..)

获取数据的每个函数都接受为第二个参数参数数组(可选),用于对sql注入进行自动数据绑定。本文前面已经介绍过它的使用。

答案 2 :(得分:2)

有点。

mysql_real_escape_string函数接受给定变量并将其转义为SQL查询。因此,您可以安全地将字符串附加到像

这样的查询中
$safe =  mysql_real_escape_string($unsafe_string);
$query = 'SELECT * FROM MyTable WHERE Name LIKE "' . $safe . '" LIMIT 1';

它不会保护您免受某人将恶意代码放入该查询以便稍后显示(即XSS或类似攻击)。因此,如果有人将变量设置为

// $unsafe_string = '<script src="http://dangerous.org/script.js"></script>'
$safe =  mysql_real_escape_string($unsafe_string);
$query = 'UPDATE MyTable SET Name = "' . $safe . '"';

该查询将按预期执行,但现在在您打印此人姓名的任何页面上,他的脚本都会执行。

答案 3 :(得分:1)

这是完全错误的做法。

事实上,你正在模仿臭名昭着的魔法引语,这被认为是一种不好的做法。带着它的所有缺点和危险。

答案 4 :(得分:-2)

这不是为了防止SQL注入真正的转义方法只添加\到危险的

像“或”之类的字符所以带有“hi”do'like“的字符串将变成”hi \“do \'喜欢\”所以它是

不太危险

这种方法并不总是有用的;如果你想显示转移的内容

页面中的

变量只会破坏它并降低其可读性