1

I am having an issue with my SQL Update script. It prints "Motto Changed" but doesn't update the row. My code is all correct according to many tutorials. Please Help

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

UPDATE AGAIN:

<?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)
?>

1 Answers1

0

Never interpolate $_POST variables directly into SQL strings. You can't trust $_POST variables, they may easily contain characters that modify your SQL syntax, and that's what causes SQL injection vulnerabilties.

The weird thing is that you create an escaped version as $motto and then you never use it (as per comment from @Arth).

Always escape strings that you interpolate into SQL, even if you think they are "safe." For example, your $steamid contains only literal text that you control, plus a couple of integers. That should be safe, but what if some other developer changes the format of a steamid next year? If you escape it, you can't go wrong.

$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}'";

Of course, the best practice is to use query parameters. You are using PHP's deprecated mysql extension, which doesn't support query parameters. But I understand if you're not ready to rewrite a lot of code to switch to PDO. When you are, follow examples in How can I prevent SQL-injection in PHP?

Another issue: if you want to know if the UPDATE affected rows, don't assume it did just because the UPDATE didn't return an error. It's not an error if your condition in your WHERE clause simply matched zero rows. It's also not an error if the UPDATE matched a row, but the motto already contained the string you tried to set.

After the UPDATE, check the number of affected rows:

if (!mysql_query($sql, $con))
{
    die('Error: ' . mysql_error());
}
$n = mysql_affected_rows();
echo "Motto changed on {$n} row(s)";
Community
  • 1
  • 1
Bill Karwin
  • 462,430
  • 80
  • 609
  • 762
  • The changes to told me to make still don't work? i will update in the question. – user3826505 Jul 10 '14 at 18:04
  • I didn't mean for you to execute the update twice before you request the number of affected rows. The second update will report 0 rows changed, because when UPDATE changes values to the values the row already contained, it doesn't count as an "affected row." – Bill Karwin Jul 10 '14 at 18:10