我想说清楚*(所以人们不要急于推销这个,因为这对他们来说很容易。*):
我是一名初学程序员,是的,在完成一些基本的东西之后,我会转向mysqli,而不是pdo,这对我来说很复杂。
require('header.php');
$id = mysql_real_escape_string($_GET["id"]);
$userRow = mysql_query("SELECT * FROM table WHERE `id` = $id AND visible = 1");
$row = mysql_fetch_assoc($userRow);
$user_1 = $row['id'];
if ($user_1)
{
echo function($user_1);
}else{
echo 'Error 404';
}
我如何从这段代码中避免sql注入,欢迎提出任何建议。
答案 0 :(得分:3)
PHP 1.5中不推荐使用PHP中的mysql扩展 - 即使你刚刚开始使用PHP / MySQL,这些函数也不应该是你的起点。最小值应该是mysqli。 mysql_
的大多数功能都具有mysqli_
等效功能。
通常,您应该尝试通过将允许值列入白名单来减少攻击面:
$userRow = mysql_query("SELECT * FROM table WHERE `id` = " . intval($_GET['id']) . " AND visible = 1");
这将消除此查询的所有SQL注入。$userRow = mysql_query("SELECT * FROM table WHERE `id` = \"" . preg_replace('/[^A-Za-z0-9]/', '', $_GET['id']) . "\" AND visible = 1");
- 除了A-Z,a-z和0-9之外的所有内容都将从字符串中删除。filter_var
- 只有在您收到的输入成功通过filter_var时才执行查询。$id = mysql_real_escape_string(preg_replace('[\'"]', '', $_GET["id"]));
或$id = mysql_real_escape_string(str_replace('"', '', str_replace('\'', '', $_GET["id"])));
转义字符串,都要删除它们 - 这会删除所有&# 34;和'来自字符串,通常不需要。mysqli_real_escape_string
是一个不错的选择。在您的示例中,您仍然需要$ id周围的引号,例如$userRow = mysql_query("SELECT * FROM table WHERE `id` = '$id' AND visible = 1");
棘手的部分是mysqli_real_escape_string
取决于使用的字符集 - 也使用mysqli_set_charset()
并将其设置为utf8。如您所见,您需要自己做很多考虑和关心 - 在我看来这不值得。使用现有的库或框架,其中有很多想法用于防止SQL注入,并且有详细的文档以避免安全漏洞。 Doctrine是一个不错的选择(使用DBAL,您仍然可以以最小的开销自己进行查询)。您仍然可以将这些库包装在您自己的对象或类中,以便完全控制。
如果你只想使用PHP的内置方法,那么PDO并不难。这是一个使用未命名占位符的示例:$db = new PDO("dbtype:host=yourhost;dbname=yourdbname;charset=utf8","username","password");
$insecuredata = $_GET["id"];
$query = $db->prepare("SELECT * FROM table WHERE id = ? AND visible = 1");
$query->execute(array($insecuredata));
$row = $query->fetch(PDO::FETCH_ASSOC);
此示例使用命名参数,这样可以轻松扩展查询(有几种方法可以执行此操作,$ query-&gt; bindParam也很有可能 - 请参阅PDOStatement::execute的PHP文档):< / p>
$db = new PDO("dbtype:host=yourhost;dbname=yourdbname;charset=utf8","username","password");
$insecuredata = $_GET["id"];
$query = $db->prepare("SELECT * FROM table WHERE id = :id AND visible = 1");
$query->execute(array(':id' => $insecuredata));
$row = $query->fetch(PDO::FETCH_ASSOC);
习惯PHP和现有框架为您提供的可能性 - 他们都经历了漫长的学习过程,以消除问题和安全漏洞。你真的想以最难的方式学习所有可能的问题吗?