验证 PHP 中的 POST 个变量

Validating POST variables in PHP

我有一段代码,用户在 HTML 中完成输入表单。 在 post 上,我根据数据库中的可用点数 $points 验证了他们的 $_POST 条目 $userAmt,然后我继续。

我注意到一些用户能够绕过我的初始检查并输入比数据库中可用的更多的点,只要它在第二次验证的范围内 1-20。所以验证的某些部分正在工作,但我猜他们能够在我的初始验证后使用断点并编辑 post 变量?这是代码片段。

$query = mysqli_query($conn, "SELECT * FROM users WHERE id = '$id'");
$queryA = mysqli_fetch_assoc($query);
$points = $queryA['points']; //user points available


if(isset($_POST['submit'])){
$userAmt = $_POST['userInput']; //users input
$userAmt = mysqli_real_escape_string($conn, $userAmt);
$prize = $userAmt * 2;

    if($userAmt > $points ){ //<- attackers are circumventing
    $message = "You do not have enough points";
    } else if ($userAmt < 1 || $userAmt > 20){ //<-attackers are not circumventing
    $message = "Must be between 1 and 20";
    } else {
    // determine outcome and update DB
    // if user wins
    mysqli_query($conn, "UPDATE users SET points = points + '$prize' WHERE id = '$id'");
    }
}

也许我不应该做 if 而是 case switch?

货物崇拜编程。你为什么要 sql 转义 $userAmt,只是为了开始对它进行数学运算?

您还只是假设您的 select 查询成功。如果由于某种原因失败,则 $points 将是一个布尔值 FALSE,当在 > 操作中使用时,它会类型转换为整数 0,基本上

if ($userAmt > false)

只要用户输入任何内容,基本上总是正确的。

您还需要这样的东西:

$result = mysqli_query($con, "SELECT ...") or die(mysqli_error($conn));
if (mysqli_num_rows($result) == 0) {
   die("who are you and how did you get here?");
} else {
   $row = mysqli_fetch_assoc($result);
   $points = $row['points'];
}

除此之外,无论如何你都不应该自己逃跑。您正在使用 mysqli - 使用准备好的语句和占位符,因为您仍然容易受到 sql injection attacks.

它归结为 phps 类型杂耍和字符串比较:

//your code, valunerable:
$userAmt = " 20 ";
$points = "10";

if($userAmt > $points ){ //<- attackers are circumventing
    $message = "You do not have enough points";
} else if ($userAmt < 1 || $userAmt > 20){ //<-attackers are not circumventing
    $message = "Must be between 1 and 20";
} else {
     $message = "winner";
}

您可以通过简单地转换为 int 来避免这种情况:

echo $message;
//fixed by type cast to int

$userAmt = (int) " 20 ";
$points = (int) "10";

if($userAmt > $points ){ //<- attackers are circumventing
    $message = "You do not have enough points";
} else if ($userAmt < 1 || $userAmt > 20){ //<-attackers are not circumventing
    $message = "Must be between 1 and 20";
} else {
     $message = "winner";
}

echo $message;

实例:http://codepad.viper-7.com/bwkvG3