PHP插入。如何检查其有效性?

时间:2013-06-18 21:04:32

标签: php html select web insert

我有这个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);
?>

我需要你的帮助:)。

3 个答案:

答案 0 :(得分:1)

检查帐户和字符

  

不检查帐号或字符名称是否有效。

角色名称

您已经通过switch ($category)检查$category'accountname'还是'charactername'。唯一剩下的就是输出错误信息,如果它不是其中之一。

帐户名称

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

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

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

与API相关

不推荐使用

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
}