我有一段代码,用户在HTML中填写输入表单。
在帖子上,我根据他们在数据库中可用的点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'");
}
}
,然后我继续。
我注意到有些用户只能在第二次验证Session
的范围内,绕过我的初始检查并输入比数据库中可用的更多的点数。因此,部分验证工作正常,但我猜他们能够在初始验证后使用断点并编辑帖子变量?这是代码的片段。
client
也许我不应该做其他事情而不是案例切换?
答案 0 :(得分:5)
货物崇拜节目。为什么你sql转义$userAmt
,只是开始做数学呢?
您还可以简单地确定您的选择查询是否成功。如果由于某种原因失败,那么$points
将是一个布尔FALSE
值,当在0
操作中使用时,它会转换为整数>
,基本上
if ($userAmt > false)
只要用户输入ANYTHING,基本上都是真的。
你需要更像这样的东西:
$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的攻击。</ p>
答案 1 :(得分:2)
它归结为phps类型杂耍和字符串比较:
NameError: global name 'DEFAULT_DOCKER_API_VERSION' is not defined
您可以通过简单地转换为int:
来避免这种情况//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";
}