【问题标题】:Stopping users posting more than once停止用户多次发布
【发布时间】:2011-02-24 18:58:11
【问题描述】:

在发布我的表单之前,我会检查数据库以查看用户之前是否有任何帖子。如果有以前的帖子,那么脚本将返回一条消息,说明您已经发布了。

问题是我试图实现的目标是行不通的,在我的 else 语句之后一切都出错了。也可能存在sql注入漏洞。你能帮忙吗??4

<?php

include '../login/dbc.php';
page_protect();

$customerid = $_SESSION['user_id'];

$checkid = "SELECT customerid FROM content WHERE customerid = $customerid";

if ($checkid = $customerid) {echo 'You cannot post any more entries, you have already created one';}

else

$sql="INSERT INTO content (customerid, weburl, title, description) VALUES
('$_POST[customerid]','$_POST[webaddress]','$_POST[pagetitle]','$_POST[pagedescription]')";

if (!mysql_query($sql))
  {
  die('Error: ' . mysql_error());
  }
echo "1 record added";

?>

【问题讨论】:

标签: php mysql forms post


【解决方案1】:

回答你问题的第二部分:是的,你很容易受到 SQL 注入的攻击

$sql="INSERT INTO content (customerid, ...) VALUES ('$_POST[customerid]', ...)";
                                                     ^

This article 解释 SQL 注入以及如何避免 PHP 中的漏洞。

【讨论】:

    【解决方案2】:

    您缺少大括号{}:

    <?php
    
    if ($checkid == $customerid) {echo 'You cannot post any more entries, you have already created one';}
    
    else
    {
    
    $sql="INSERT INTO content (customerid, weburl, title, description) VALUES
    ('$_POST[customerid]','$_POST[webaddress]','$_POST[pagetitle]','$_POST[pagedescription]')";
    
    if (!mysql_query($sql))
      {
      die('Error: ' . mysql_error());
      }
    echo "1 record added";
    }
    
    ?>
    

    【讨论】:

    • 别忘了修复你的 if() 语句,因为这是一个分配,并且总是评估为真(由 thetaiko 提到)
    【解决方案3】:

    除了前面提到的缺少花括号之外,您似乎在 if 语句中进行赋值,这将导致语句始终评估为 true:

    if ($checkid = $customerid) {echo 'You cannot post any more entries, you have already created one';}
    

    应该是:

    if ($checkid == $customerid) {echo 'You cannot post any more entries, you have already created one';}
    

    另外,$checkid 包含一个 SQL 查询字符串。我假设您打算在实际进行比较之前实际运行查询并使用与 $customerid 相当的内容填充 $checkid

    【讨论】:

      【解决方案4】:

      除了 SQL 注入(伙计,在开始之前阅读有关它的书/教程!)和 else 之后缺少的大括号之外,您还有两个错误:首先,您没有执行 $checkid查询,其次,你在if中只有一个=(所以你将$customerid的值赋给$checkid

      也有可能存在sql注入漏洞。

      为什么“可能”?你自己没看到吗?你不是以一种一开始就避免此类问题的方式编写代码吗?

      【讨论】:

        【解决方案5】:

        Re:sql 注入 - 任何时候您信任来自用户的数据时,您都容易受到攻击。获取您的 INSERT 语句并对其进行清理。

        $sql = sprintf("INSERT INTO content (customerid, weburl, title, description) VALUES ('%d','%s','%s','%s')",
            $_POST['customerid'], //forced as digit
            mysql_real_escape_string($_POST['webaddress']),
            mysql_real_escape_string($_POST['pagetitle']),
            mysql_real_escape_string($_POST['pagedescription']) );
        

        此外,您应该在数组键中使用撇号。用双引号括起来就是:

        echo "Post data webpage title is {$_POST['pagetitle']}";
        

        【讨论】:

          【解决方案6】:

          $_SESSION 将在浏览器关闭时清除。因此,我建议以明确的方式使用 Cookie。

          我已将您的代码更新如下:

          include '../login/dbc.php';
          page_protect();
          
          $customerid = $_COOKIE['user_id'];
          
          $checkid = "SELECT customerid FROM content WHERE customerid = $customerid";
          
          if ($checkid = $customerid) {echo 'You cannot post any more entries, you have already created one';}else{
          
          $sql="INSERT INTO content (customerid, weburl, title, description) VALUES
          ('$_POST[customerid]','$_POST[webaddress]','$_POST[pagetitle]','$_POST[pagedescription]')";
          
          if (!mysql_query($sql))
            die('Error: ' . mysql_error());
          else
            echo "1 record added";
          }
          

          如果您担心注入,请在插入查询之前添加此花絮:

          foreach($_POST as $key=>$value){
            $_POST[$key] = addslashes($value);
          }
          

          【讨论】:

          • 郑重声明,这不是我防止注入攻击的方法,但它是您脚本的快速补丁。
          • 只有当浏览器使用查询变量而不是 cookie(本机 PHP 会话的两个选项)并且没有正确设置 cookie 过期时,会话才会丢失。此外,您的 cookie 方法可以由用户使用一些简单的 javascript 进行更改,因此即使在应用花絮之后也可以注入。
          猜你喜欢
          • 1970-01-01
          • 2011-11-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-08-06
          相关资源
          最近更新 更多