SQL 注入获取 id 解决方案


Sql injection get id solution

我不知道如何使这段代码安全。我尝试在查询变量中使用mysql_real_escape_string,例如

$query = "select * from products where id= " . mysql_real_escape_string($products);
但没有奏效,还试图在产品变量中转义,但得到了相同的结果。有什么建议吗?谢谢。

<?php
/ Define vars.
$conn = mysql_connect('localhost', 'test', 'test');
$products = isset($_GET["products"]) ? $_GET["products"] : "";
$query = "select * from products where id=$products";
// List elements.
if ($conn)
{
	mysql_select_db('testsqli');
	$result = mysql_query($query);
	
	// Table head.
	echo '<table cellspacing="5" cellpadding="5">';
	echo '<tr>';
	echo '<td>Description</td>';
	echo '<td>Price</td>';
	echo '</tr>';
	
	// Empty table?
	if (@mysql_num_rows($result)==0)
	{
		echo '<tr>';
		echo '<td><i>That''s all!</i></td>';
		echo '</tr>';
	}
		// Listing data in table.
		while ($row = @mysql_fetch_array($result))
		{
			echo '<td>'.$row['Description'].'</td>';;
			echo '<td>'.$row['Price'].'</td>';;
			
		}
	echo '</table>';
}
?>

您仍然需要添加引号(并使用 msqli 代替),如下所示:

$query = "select * from products where id='" . mysqli_real_escape_string($products)."'";
// or
$query = sprintf(
  "select * from products where id='%s'",
  mysqli_real_escape_string($products)
);

我会使用预准备语句而不是MySQL转义。转义会跳过一些通配符,例如"%"和"*",这也可能会提供意外的结果。

$stmt = $dbh->prepare("SELECT * FROM PRODUCTS WHERE ID=?");
$stmt->bindParam(1, $products, PDO::PARAM_STR|PDO::PARAM_INPUT_OUTPUT, 4000); 
// call the stored procedure
$stmt->execute();

另外,请记住以下措施可确保其安全:

  • 切勿以超级用户或数据库所有者身份连接到数据库。使用具有非常有限权限的始终自定义用户。
  • 检查给定的输入是否具有预期的数据类型。(在这种情况下,请验证$products的格式是否符合预期,即,如果您的产品目录只有 9 个字符的索引,请确保它的长度不是 100 个字符。PHP 有广泛的输入验证函数,从变量函数和字符类型函数(例如分别为 is_numeric()、ctype_digit())中最简单的函数,到与 Perl 兼容的正则表达式支持。
  • 如果应用程序等待数字输入,请考虑使用 ctype_digit() 验证数据,或使用 settype() 静默更改其类型,或者使用 sprintf() 使用其数字表示形式。

参考: http://php.net/manual/en/security.database.sql-injection.php