我有这个PHP页面。 问题是: 它不会检查帐户或字符名称是否有效。
PS:帐户是一个表帐户列字符名称是一个表格播放器列
我该如何检查?
<?php
function anti_injection($sql)
{
$sql = preg_replace(sql_regcase("/(from|select|insert|delete|where|drop table|show tables|#|\*|--|\\\\)/"),"",$sql);
$sql = trim($sql);
$sql = strip_tags($sql);
$sql = addslashes($sql);
return $sql;
}
$accountorname = anti_injection($_POST['accountorname']);
$gamecode = $_POST['gamecode'];
$category = $_POST['category'];
$premiumpoints = anti_injection($_POST['premiumpoints']);
switch ($category) {
case 'accountname':
$insertquery = "INSERT INTO gamecodes (gamecode, accountname, premium_points, alreadyused) VALUES ('$gamecode','$accountorname',$premiumpoints,'N')";
break;
case 'charactername':
$insertquery = "INSERT INTO gamecodes (gamecode, accountname, premium_points, alreadyused)
SELECT '$gamecode',accounts.name,$premiumpoints,'N'
FROM accounts
JOIN players
ON accounts.id = players.account_id
WHERE players.name = '$accountorname'";
break;
}
$result = mysql_query($insertquery);
?>
我需要你的帮助:)。
答案 0 :(得分:1)
不检查帐号或字符名称是否有效。
角色名称
您已经通过switch ($category)
检查$category
是'accountname'
还是'charactername'
。唯一剩下的就是输出错误信息,如果它不是其中之一。
帐户名称
1)我想帐户名是你插入的一个值,它实际上是gamecodes
表中的外键,并映射到accounts
表或类似的东西。
您可以做的最简单的事情就是在创建表时使用referential integrity
。定义表之间的关系,如果account name
无效,查询将失败。
2)另一种选择是使用account name
执行select语句,并验证另一个表中是否存在account
。此外,您可以使用PHP进行进一步检查。
MySQL_*
个函数。您应该查看Mysqli和PDO等替代方案。请参阅:http://www.php.net/manual/en/mysqlinfo.api.choosing.php
答案 1 :(得分:1)
你在这里思考正确的思路真是太棒了。 SQL注入可能是网站被黑客入侵的首要原因。实际上有几个步骤可以确保从简单到非常简单的事情是好的:
简单的事情
不应信任用户提供的任何变量(例如$ _GET,$ _POST,$ _COOKIE,$ _SERVER或其他任何地方)。
如果您使用的是mysql_ *,那么在90%的情况下确保您执行以下操作之一将会很好:
$safe_number = (int)$_GET['number']; // forces safe_number to be an integer
和
$safe_string = mysql_real_escape_string($_GET['string']); // ensure that the string doesn't have any characters in that will trip up mysql.
稍微复杂的事情
为SQL使用预准备语句。 mysql_ *函数(http://www.php.net/manual/en/function.mysql-query.php)被很多人使用,实际上并不好,因为它们不支持预处理语句。
您应该阅读http://www.php.net/manual/en/mysqli.prepare.php并改用它。简而言之,你告诉mysql,'嘿,这个变量是一个整数',mysql为你处理。
许多人建议使用PDO(http://php.net/manual/en/book.pdo.php),因为如果需要,它可以让您轻松地使用不同的数据库到mysql。
无论如何 - mysqli或PDO,只是没有mysql _ *。
答案 2 :(得分:0)
帐户名和 charactername 已被“验证”,因为仅在交换机符合这些文字时才会使用这些案例。
知道SQL注入需要防范是好的,然而,实际实现的解决方案不是 - 例如输入游戏代码是一个巨大的漏洞。理想情况下,您应该使用预准备语句mysqli_real_escape_string或其等价物也可以使用,但是您应该注意有关默认服务器字符集的警告。
最后,尽可能确保您获得的输入是您期望的输入preg_match。例如,如果游戏代码只能是一个6位整数,则可以执行
if (preg_match('/^[0-9]{6}$/', $gamecode) === 0){
// fail
}