【问题标题】:html form selector security vulnerabilityhtml表单选择器安全漏洞
【发布时间】:2014-04-25 07:24:30
【问题描述】:

如果我在下面有这个简单的表单选择器:

<form id="myform" class="form" role="form" accept-charset="utf-8" method="post" action="/mypage.php">
    <select id="gender" name="gender">
     <option selected="" value=""></option>
     <option value="man">man</option>
     <option value="women">women</option>
    </select>
    <button type="submit" name="insert"> Send </button>
</form>

还有这个用于检索数据的小 php 代码:

    if (isset($_POST['insert'])) {
        if(!isset($_POST['gender']) || strlen($_POST['gender'])<3)
        {
                        header('location:'.$_SERVER['PHP_SELF'].'?error');
                        exit;
        }

        $gender = ($_POST['gender']);
     ...
    // INSERT INTO DATABASE
    }

现在有人使用 Firebug 将选项值从“man”修改为“vulnerability”并单击提交,这个新值将被插入到我的数据库中,而不是之前的。

我的问题是:如何使用 php 语言防止这种情况发生?

谢谢。

【问题讨论】:

标签: php html forms security selector


【解决方案1】:

由于您已经定义了一组可能的值,因此很容易验证提交的值:

$options = array('', 'man', 'woman');
if (!in_array($_POST['gender'], $options)) {
    // invalid value
}

【讨论】:

    【解决方案2】:

    未提供您的数据库部分,因此我无法确切确定哪种解决方案最适合您。不过,在这种情况下,最好使用 PDO 绑定系统以及一些简单的 if-else 逻辑检查。

    像这个例子:

    $this->db_connection = new PDO('mysql:host='. DB_HOST .';dbname='. DB_NAME . ';charset=utf8', DB_USER, DB_PASS);
    
    $query_new_user_insert = $this->db_connection->prepare('INSERT INTO users (user_name, user_password_hash, user_email, user_activation_hash, user_registration_ip, user_registration_datetime, usertype, user_fname, user_lname) VALUES(:user_name, :user_password_hash, :user_email, :user_activation_hash, :user_registration_ip, now(), :usertype, :user_fname, :user_lname)');
                    
                    $query_new_user_insert->bindValue(':user_name', $user_name, PDO::PARAM_STR);
                    $query_new_user_insert->bindValue(':user_password_hash', $user_password_hash, PDO::PARAM_STR);
                    $query_new_user_insert->bindValue(':user_email', $user_email, PDO::PARAM_STR);
                    $query_new_user_insert->bindValue(':user_activation_hash', $user_activation_hash, PDO::PARAM_STR);
                    $query_new_user_insert->bindValue(':user_registration_ip', $_SERVER['REMOTE_ADDR'], PDO::PARAM_STR);
                    $query_new_user_insert->bindValue(':usertype', $usertype, PDO::PARAM_STR);
                    $query_new_user_insert->bindValue(':user_fname', $user_fname, PDO::PARAM_STR);
                    $query_new_user_insert->bindValue(':user_lname', $user_lname, PDO::PARAM_STR);
                    $query_new_user_insert->execute();
    

    现在您可以在这里看到我们正在绑定值。他永远不会知道你在这里的变量。此外,您可以使用生成的表单而不是直接编写代码。 使用数组传递数据也是另一个好习惯! 看看这个:https://blog.stackoverflow.com/2008/06/safe-html-and-xss/

    【讨论】:

    • real_escape_string 如果您使用如上所示的 PDO prepare() 则不需要。 PDO 是现代 PHP 基础而不是其他替代方案(您可以使用 PDO::quote())@user3436403
    【解决方案3】:

    就像@Joshua 所说的,你必须清理你的输入,你可以这样做,(这不是检查变量有效性的唯一方法)

    if($_POST['insert'] == "vulnerability"){
    //refresh the page and notify
    }
    if (isset($_POST['insert'])) {
        if(!isset($_POST['gender']) || strlen($_POST['gender'])<3)
        {
                        header('location:'.$_SERVER['PHP_SELF'].'?error');
                        exit;
        }
    
        $gender = ($_POST['gender']);
     ...
    // INSERT INTO DATABASE
    }
    

    您只想在确定变量安全或符合预期后才将变量插入数据库,即如果您的 php 代码在插入数据库之前没有进行有效性检查,则用户可以使用mysql 语句删除您的表或更改您的数据 ie"TRUNCATE TABLE MY_AWESOME_TABLE"。这将删除表中的所有数据(用户、密码等)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-24
      • 2011-12-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多