我一直在使用下面的代码块来假设停止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());
答案 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 \'喜欢\”所以它是
不太危险
这种方法并不总是有用的;如果你想显示转移的内容
页面中的变量只会破坏它并降低其可读性