SQL更新代码问题/PHP注入


SQL Update code issue/PHP injection

我有一个问题与我的SQL更新脚本。它打印"座右铭已更改",但不更新行。根据许多教程,我的代码都是正确的。请帮助

$sql="UPDATE loadout SET motto='".$_POST['motto']."'  WHERE steamid='".$steamid."'";

再次更新:

<?php
   require "../requires/php/steam.php";
 $dbhost  = '**';
 $dbname  = 'battlefield';
 $dbuser  = 'battlefield';
 $dbpass  = '**'; 
$con = mysql_connect($dbhost, $dbuser, $dbpass);
$authserver = bcsub( SteamID(), '76561197960265728' ) & 1;
    $authid = ( bcsub( SteamID(), '76561197960265728' ) - $authserver ) / 2;
$steamid = mysql_real_escape_string("STEAM_0:$authserver:$authid");


$motto = mysql_real_escape_string($_POST['motto']);
mysql_select_db($dbname, $con);

$sql="UPDATE loadout SET motto='{$motto}'  WHERE steamid='{$steamid}'";

if (!mysql_query($sql, $con))
{
   die('Error: ' . mysql_error());
}
echo "Motto Changed";
if (!mysql_query($sql, $con))
{
die('Error: ' . mysql_error());
}
 $n = mysql_affected_rows();
echo"Motto changed on {$n} row(s)";
mysql_close($con)
?>

永远不要将$_POST变量直接插入到SQL字符串中。你不能信任$_POST变量,它们可能很容易包含修改SQL语法的字符,这就是导致SQL注入漏洞的原因。

奇怪的是,你创建了一个转义版本作为$motto,然后你从不使用它(根据@Arth的评论)。

总是转义插入到SQL中的字符串,即使你认为它们是"安全的"。例如,您的$steamid只包含您控制的文本,加上几个整数。这应该是安全的,但如果明年其他开发商改变了steamid的格式怎么办?如果你逃避它,你就不会出错。

$steamid = mysql_real_escape_string("STEAM_0:$authserver:$authid");
$motto = mysql_real_escape_string($_POST['motto']);
$sql="UPDATE loadout SET motto='{$motto}'  WHERE steamid='{$steamid}'";

当然,最佳实践是使用查询参数。您正在使用PHP的过时的mysql扩展,它不支持查询参数。但是,如果您还没有准备好重写大量代码以切换到PDO,我可以理解。如果您是,请参考如何在PHP中防止sql注入中的示例?

另一个问题:如果您想知道UPDATE是否会影响行,不要仅仅因为UPDATE没有返回错误就认为它会影响行。如果WHERE子句中的条件仅仅匹配0行,这不是错误。如果UPDATE匹配一行,但格言已经包含您试图设置的字符串,也不会出现错误。

UPDATE后,检查受影响的行数:

if (!mysql_query($sql, $con))
{
    die('Error: ' . mysql_error());
}
$n = mysql_affected_rows();
echo "Motto changed on {$n} row(s)";