-1

我得到了这个 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);
?>

我需要你的帮助 :)

4

3 回答 3

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_*。

于 2013-06-18T21:29:10.967 回答
1

检查帐户和字符

它不检查帐户或角色名称是否有效。

角色名字

您已经switch ($category)通过$categoryis'accountname''charactername'. 剩下的唯一事情是如果它不是其中之一,则输出错误消息。

帐户名称

1)我想帐户名称是您插入的值,它实际上是表中的外键gamecodes并映射到accounts表或类似的东西。

您可以做的最简单的事情就是简单地用于referential integrity创建表。定义表之间的关系,如果account name无效,查询将失败。

2) 另一种选择是使用 执行选择语句account name并验证account存在于另一个表中。此外,您可以使用 PHP 进行进一步检查。

关于 API

MySQL_*功能已弃用。您应该查看诸如 Mysqli 和 PDO 之类的替代方案。见:http ://www.php.net/manual/en/mysqlinfo.api.choosing.php

于 2013-06-18T21:18:55.423 回答
0

accountnamecharactername已经“验证”,因为只有当开关与这些文字匹配时才会采用这种情况。

知道需要防御 SQL 注入是件好事,但实际实现的解决方案却并非如此——例如,输入游戏代码就是一个大洞。理想情况下,您应该使用准备好的语句。mysqli_real_escape_string或等效项也是可行的,但是关于您应该注意的默认服务器字符集有一些警告。

最后,尽可能确保您获得的输入是您期望的输入,例如preg_match。例如,如果游戏代码只能是 6 位整数,您可以这样做

if (preg_match('/^[0-9]{6}$/', $gamecode) === 0){
    // fail
}
于 2013-06-18T21:31:42.793 回答