Php 这能阻止sql注入吗

Php 这能阻止sql注入吗,php,mysql,sql-injection,code-injection,Php,Mysql,Sql Injection,Code Injection,我一直在使用下面的代码块来阻止sql注入。这是我第一次启动php时(不久前)有人向我展示的东西 我把它放在每一页上,就像打开的页面上显示的那样。我想知道它是否有效?我不知道如何测试sql注入 <?php //Start the session session_start(); //=======================open connection include ('lib/dbconfig.php'); //===============This stops SQL

我一直在使用下面的代码块来阻止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);
  }

这在某种程度上是有效的,但不是最理想的——不是你在“获取”和“发布”中收到的所有数据都会进入数据库。有时,您可能希望在页面上显示它,在这种情况下,mysql\u real\u escape\u字符串只会造成伤害(相反,您希望使用htmlentities)

我的经验法则是,在将某个东西放入需要转义的上下文之前,只转义它


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

这并不是为了阻止SQL注入,真正的转义方法只会将\添加到危险的查询中

像“或”这样的字符带有“hi”do'like“的字符串将变为“hi\”do'like\”因此

不那么危险

此方法并不总是有用的;如果您想显示

变量,它只会破坏页面,降低页面的可读性

mysql\u real\u escape\u 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 . '"';
/$unsafe\u string=''
$safe=mysql\u real\u escape\u string($safe\u string);
$query='updatemytable SET Name=“”$安全。”"';
该查询将按预期执行,但现在在打印此人姓名的任何页面上,他的脚本都将执行。

这还不够。 1.缺少COOKIE,$\u COOKIE变量。 2.如果您使用$\u请求,您会遇到麻烦。 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,您可能会发现我使用的这些辅助函数很有用:


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

这是完全错误的方法

事实上,你在模仿臭名昭著的魔法格言,这被认为是一种不好的做法。尽管有很多缺点和危险

  • 帮助你理解为什么你最初的方式是错误的
  • 要帮助您理解为什么转义与“数据安全”无关,但不足以保护您的查询,请执行以下操作:
  • 为了帮助您了解准备的陈述在什么情况下不充分,以及在这些情况下应该做什么:

您的代码似乎还可以,但方法是错误的。从早期PHP的婚姻时代开始,世界就进步了。使用PDO/MySQLI。使用参数化查询,在数据库中使用单个访问点……感谢您的回答,请原谅我的无知,但您能否详细说明单个访问点。在我当前的项目中,我在每个pa上访问数据库ge正在创建条目和查询。这是不正确的?我通常有一个类来管理与数据库的连接和低级操作(如对数据库运行查询并返回结果)。我有另一个层,负责获取不同格式的请求并将其转换为SQL,该层也是唯一一个清理数据的层,我总是使用该类创建SQL。这样,我非常确定我不会被SQL注入,如果我没有,我只需要在一个地方修复它。酷,我有从来没有读过参数化查询,但快速搜索显示我有很多阅读要做。不能说这些查询是否安全,因为整个“$inserts”=“行未使用$\u GET/$\u POST变量。第三行也是一样,使用“$cid”。对。。所有登录和插入都是通过post完成的。Orly我的一些拉取要显示的数据的查询是用GET完成的,但我尽量避免这样做。谢谢你抽出时间…看来我的下一个研究领域是PDO。。。第一次阅读关于PDO的内容,我编辑了我的答案,并添加了一些我自己编写的PDO函数的链接,这些函数使使用PDO变得更加容易。使用PDO,你可以连接到任何你喜欢的数据库,因此当你学会了它,你将能够对所有数据库使用相同的函数:mysql、postgresql、sqlite-你只需在dsn中更改“mysql”到“sqlite”,谢谢。这是我没有想到的,插入一个完整的脚本链接。。。现在有很多东西要学习。谢谢你的回答。@Daniel这完全是错误的说法。mysql\u real\u escape\u string不会让任何东西变得“安全”。@Col.shrapanel我想你想说的是,“仅仅因为一个字符串可以安全地插入mysql查询并不意味着它是安全的。”这正是我在这篇文章中试图传达的。声称我写的东西是完全错误的是修辞和误导。引用一下,
mysql\u real\u escape\u string
”。不。我想说的是,mysql\u real\u escape\u字符串不会使“给定变量”成为“插入mysql查询的安全变量”。严格地说,这与“安全”无关。尽管你的后一个说法更为正确,但你回答中的说法完全是误导性的,并将导致注射。@Col.Shrapnel重新编写以供澄清。希望没有
$stmt = $PDO->prepare("SELECT * FROM test WHERE id = :id AND cat = :cat");
$stmt->execute(array(":id" => $_GET["id"], ":cat" => $_GET["cat"]));
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(..), ..)