Php 这是防止sql注入的安全方法吗?

Php 这是防止sql注入的安全方法吗?,php,mysql,sql-injection,Php,Mysql,Sql Injection,此代码对sql注入是否100%安全: $id = $_GET['id'] mysql_query('SELECT * FROM mytable WHERE id < ' . (int)$id); $id=$\u GET['id'] mysql_查询('SELECT*FROM mytable WHERE id%d的mytable中删除多少sql?我不知道曾经使用过这个。我给过你一个例子。你可以编写只针对一个case by的代码,但不能针对所有SQL注入进行保护。你的论点没有依据。如果在某些

此代码对sql注入是否100%安全:

$id = $_GET['id']
mysql_query('SELECT * FROM mytable WHERE id < ' . (int)$id);
$id=$\u GET['id']
mysql_查询('SELECT*FROM mytable WHERE id<'(int)$id);
还是我必须这么做

$id = $_GET['id']
mysql_query('SELECT * FROM mytable WHERE id < ' . mysql_real_escape_string($id));
$id=$\u GET['id']
mysql_query('SELECT*FROM mytable WHERE id<'。mysql_real_escape_string($id));

我使用
sprintf
mysql\u查询(sprintf('SELECT*FROM mytable,其中id<%d',$id))

这是安全的,但您可能希望这样做

if(is_int($id)){
mysql_query('SELECT * FROM mytable WHERE id < ' . mysql_real_escape_string($id)); // just to be safe always to escape
}
if(is_int($id)){
mysql_query('SELECT*FROM mytable WHERE id<')。mysql_real_escape_string($id));//只是为了安全起见,总是可以转义
}

这篇文章似乎很好地解释了mysql\u real\u escape\u string如何保护您免受SQL注入的影响,但也解释了它的“漏洞”

这个

mysql_query('SELECT * FROM mytable WHERE id < ' . mysql_real_escape_string($id));
mysql\u查询('SELECT*FROM mytable WHERE id<'.mysql\u real\u escape\u string($id));
这是一种糟糕的做法。如果希望它是一个字符串,请至少引用该字符串:

mysql_query('SELECT * FROM `mytable` WHERE `id`<"'.mysql_real_escape_string($id)).'"';

mysql\u query('SELECT*FROM`mytable`WHERE`id`您应该使用参数化查询。这样您就不必担心所有的转义。这也使SQL更易于阅读。哦,不要使用SELECT*,只需选择您想要的。

如果
$\u GET['id']
为空,或者
(int)$\u GET['id']
计算结果为空。查询中会出现语法错误。盲目地转义或键入强制转换值并将其填充到查询中是不够的。您必须检查最终的“安全”值是否确实安全,而不仅仅是穿着奶奶衣服的狼。


你必须这样做:

$id = mysql_real_escape_string($_GET['id']);
//put the escaped string in a $var, so your select statement stays readable
//this will help in debugging, and make **not** forgetting those vital quotes
//easier.
$query = "SELECT * FROM mytable WHERE id < '$id'";
//                                         ^   ^always single quote your $vars
//       ^                                      ^ and double quote the query 
$result = mysql_query($query);
//and test to see if your query ran successful.
if (!$result) { //your query gave an error, handle it gracefully.
$id=mysql\u real\u escape\u字符串($\u GET['id']);
//将转义字符串放在$var中,以便select语句保持可读性
//这将有助于调试,并使**不会忘记那些重要的引用
//更容易。
$query=“从mytable中选择*,其中id<'$id';
//^^始终为您的$VAR单报价
//^^并对查询进行双引号
$result=mysql\u query($query);
//并测试您的查询是否成功运行。
如果(!$result){//您的查询出现错误,请优雅地处理它。

那你就安全了。

我只认为这样更好,因为当$id不是int时,你想优雅地失败,而不是让应用程序崩溃。这不是很安全,因为如果$id不是int,它将转换为int。如果$id=“xyz”,那么它将是“从mytable中选择*,其中id<0”@Amir Raminfar:他说要防止sql注入,这是有效的。我认为现在的问题不是Cast。不,它不起作用,因为如果它是从id>%d的mytable中删除*的,那么我可以让它通过id>0来删除所有内容。不太好!!!@Amir Raminfar:哇,从id>%d的mytable中删除多少sql?我不知道曾经使用过这个。我给过你一个例子。你可以编写只针对一个case by的代码,但不能针对所有SQL注入进行保护。你的论点没有依据。如果在某些情况下让$id为0,那么我相信你可以想出一些可能不好的情况。你应该始终检查$id是否为I类型nt,也不例外。您的第二个代码块中有一个SQL注入漏洞,因为您没有双引号引用来自
mysql\u real\u escape\u string()
.Oldscool answer()的输出。正如其他答案中提到的:使用参数化查询。重复其他人的答案没有什么用处,这是使mysql\u real\u escape\u string()的方法安全。毫无疑问,PDO更好。但是,鉴于该函数使用了这么长的名称,我认为我应该指出它应该如何工作。为什么要给出不应该遵循的建议,而不是回答实际问题(参见关于我答案的讨论)。你的“否”对我来说仍然很奇怪。但是我会让你看看你的发现,尽管我认为你给我的答案打了-1是不正确的。@Nanne,mysql\u real\u escape\u string()正确使用与PDO一样安全。事实上,我也可以使用PDO进行注入。例如,如果我使用动态表名,SQL注入在PDO中是完全开放的。因此,PDO提供了与正确使用
mysql\u real\u escape\u string()
完全相同的保护级别。