【问题标题】:form with array of checkboxes send incomplete data带有复选框数组的表单发送不完整的数据
【发布时间】:2013-08-12 12:16:44
【问题描述】:

我尝试传递一个包含其他表单的表单(内部表单相同,动态),但我检查了发送到“脚本处理程序”(php)的数据是否不完整。我认为某处缓冲区正在覆盖或其他东西。这是代码:

<?php
if(isset($_POST['submit_num']))
{
    $number=$_POST['sky'];

    if($number== 0)
    {
        header('Location: /ceid_coffee/user_order_form.php');
    }
    else
    {   
        $_SESSION['number'] = $number;
        echo '<form action="user_order_form.php" method="POST">'; 
        for($i=0;$i<$number;$i++)
        {
                $item = $_SESSION['item'];

                echo $item;
                $rec_query = "SELECT * FROM ylika";
                $rec_result= mysql_query($rec_query) or die("my eroors");
                while($row_rec = mysql_fetch_array($rec_result))
                {
                    echo '<br>';    
                    echo '<input type="checkbox" name="yliko[][$i]" value='.$row_rec['onoma'].'> '.$row_rec['onoma'].'';//<~~~~this line is form's data
                }
                echo '<br>';


        }
        echo '<input type="submit" name="submit" value="FINAL_ORDER">';

        echo '</form>';
    }
}

?>

这是处理脚本:

<?php
if (isset($_POST['submit']))
{   
    $number= $_SESSION['number'];
    $item = $_SESSION['item'];
    $max_id = "SELECT MAX(id_order) FROM id_of_orders";
    $x=mysql_query($max_id) or die("my eroors");
    $id= mysql_fetch_array($x);
    $xyz = $id['MAX(id_order)'];
    for($i=0;$i<$number;$i++)
    {
        $temp = $_POST['yliko'][$i]; // <~~~~ this line is the form's data
        $temp2 = implode("," , $temp);
        $inserts = ("INSERT INTO orders (order_id,product,ulika) VALUES ('$xyz' , '$item','$temp2')");
        $inc_prod=("UPDATE proion SET Counter = Counter + 1 WHERE proion.onomasia='$item'");
        mysql_query($inserts) or die(mysql_error());
        mysql_query($inc_prod) or die(mysql_error());
    }
}
?>

这里的这一行包含每个表单的数据,但我已经回显它们($temp2),我看到它们不完整。 $temp = $_POST['yliko'][$i];

如果我为每个项目($i)选择超过 1 个复选框,我只会从复选框中获得一个值到 sql 中。 你看看我是否错过了什么?

【问题讨论】:

  • 您不能在 html 中嵌套表单,请阅读:stackoverflow.com/questions/379610/can-you-nest-html-forms
  • 从复选框中我只得到每个表单的 1 个值,它们存储在 db 中。但是,如果我在复选框中输入的值超过了我的值,我只会为每个表单获得一个值。

标签: php forms checkbox


【解决方案1】:

好的,我发现了错误。我替换了这一行:

echo '<input type="checkbox" name="yliko[][$i]" value='.$row_rec['onoma'].'> '.$row_rec['onoma'].'';//<~~~~this line is form's data

这一行:

echo '<input type="checkbox" name="yliko['.$i.'][]" value='.$row_rec['onoma'].'> '.$row_rec['onoma'].'';

我不知道如何(我是 php 新手),但它确实有效。

【讨论】:

    【解决方案2】:

    您将只能为每个表单获得一个值,因为您将 $i 的值分配给每个表单:

    echo '<input type="checkbox" name="yliko[][$i]" value='.  etc.
    

    是你的问题线。

    查看您的代码生成的 HTML(大多数浏览器中的 ctrl-u),您就会明白为什么会得到错误的答案。您所有的复选框都需要有唯一的名称。

    我会通过为每个复选框分配一个与数据库中从中提取它们的行相关的名称来做到这一点,例如:

    name="checkbox_"'.$row['ylikaprimarykey']."etc.
    

    这将使您快速启动并运行。值得一提的是,您的表键的 id 可以为攻击者提供有关您网站的信息,因此最好以某种方式混淆它们。网上有许多免费的优秀课程可以为您做到这一点。

    如果您确实需要将每个表单中的内容作为单独的数据块处理,您可以轻松更改复选框名称:

    name="checkbox_$formnumber_$obfuscatedkeynumber"
    

    然后在您的处理页面中使用嵌套循环遍历它们。

    【讨论】:

    • “最佳实践”来混淆字段名称?嗯......我什至从未见过这样做过,更不用说自己做过了,我会嘲笑任何这样做的人。 IMO,通过默默无闻的安全性比根本没有安全性更糟糕;它给实施者一种虚假的安全感。在一个甚至设计得不太体面的页面中,您的字段名称只是告诉攻击者某个表单字段具有某种含义——这从查看生成的页面本身就很明显。如果他们做的不止这些,那么您的脚本就会严重损坏,并且混淆无法修复它。
    • 我不同意(当然!),因为很难确定你一切都正确,它没有害处,而且混淆 id 可能有好处。它的另一个优点是确保必须检查发送到接收脚本的任何数据的有效性 - 发送欺骗性数据非常困难,并且很容易确保数据仅从您期望的页面的特定实例发送它从。此外,代码非常短且轻,因此没有明显的性能影响。您可能将密钥混淆误认为数据混淆?
    • 好的,我会在一小时内检查。安全不是问题,功能才是。
    • @RobertSeddon-Smith:在我看来,您是在建议打乱表单控件的名称,以便它们不再与它们所代表的列/表的名称匹配。如果这不是你的意思,那么你可能想要消除歧义。但我认为可行的唯一其他解释是打乱行 ID 而不是列名......而且我没有看到任何一个真的有帮助。而且我从来没有见过任何一个完成。
    • 我应该提一下,如果我删除 1 个表单的标识符 $i 效果很好。
    猜你喜欢
    • 2011-02-25
    • 2018-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多