请求已被黑洞 - CakePHP

时间:2013-11-15 13:55:08

标签: php cakephp

我正在使用CakePHP的SecurityComponent。而且它非常重要,因为它可以保存CSRF攻击中的形式。我的项目共有10-12个表单,这是我的第一个CakePHP项目。启用SecurityComponent之后我遇到了一些麻烦,但在经过一些小心的分钟后可能会被淘汰。这是我的项目的最后一种形式,似乎一切都是正确的,但仍然形式是黑洞:(。任何人都可以告诉我问题吗?我不想禁用CSRF检查或SecurityComponent。这是我的观看代码:

<?php
echo $this->Form->create('Record');
?>
<script type="text/javascript"> var me = new MetroExam(); </script>
<div class="exam_paper">
    <div class="question_box" id="q_b">
        <div class="q_n_a_header">
            <div class="instructions">
                <b>Instructions:</b><br>
                <?=$inst['value_text']; ?>
            </div>
            <div id="timer">Please wait</div>
        </div>
        <div id="q_paper">
           <img id="q" style="display: none;" src="/oes/<?=$exam['path'].'?ts='.time(); ?>">

            <img id="loading_img" src="/oes/img/loading.gif">
        </div>
    </div>
    <div class="ans_box" id="a_b">
        <!-- information about answer paper. !important -->
        <?php
        $i = 0;

        //these fields are essential for evaluating ans paper
        echo $this->Form->hidden('submit', array('value' => 'true'));
        echo $this->Form->hidden('start_time', array('value' => ''));
        echo $this->Form->hidden('end_time', array('value' => ''));
        echo $this->Form->hidden('duration', array('value' => ''));
        echo $this->Form->hidden('valid', array('value' => ''));
        echo $this->Form->hidden('passed', array('value' => ''));

        //options for all radio
        $options     = array(
            '1' => 'A',
            '2' => 'B',
            '3' => 'C',
            '4' => 'D'
        );
        if($exam['choices'] == 5){
            $options['5'] = 'None';
        }

        $questions = (int)$exam['questions']; // 40 <= $exam['questions'] <= 100
        $i = 1;
        while($questions--){
            echo '<div class="'.(($i%2)==1?'each_answer_even':'each_answer_odd').'" id="ans-'.$i.'">';
            echo '<div class="q_number">'.($i <= 9 ? '0'.$i : $i).'</div>';
            $name       = 'ans'.str_pad($i, 3, '0', STR_PAD_LEFT);
            $attributes = array('empty' => false, 'legend' => false, 'onclick' => 'me.answer_click('.$i.')');
            echo '<div class="mcq">'.$this->Form->radio($name, $options, $attributes).'</div>';
            echo '</div>';
            $i++;
        }
        echo $this->Form->end('Submit');
        ?>
    </div>
</div>

这基本上是一个MCQ考试表格。每组中有4个或5个单选按钮,总共有40到100个组。我正在使用CakePHP 2.4。提前谢谢。

2 个答案:

答案 0 :(得分:9)

根据评论,出现问题的原因是您正在更改表单的隐藏值。 SecurityComponent的工作方式是,它“锁定”字段的名称,因此一旦表单发送,恶意者就无法添加新字段或更改值。 隐藏值更严格,因为它锁定字段名称值。因此,通过使用jQuery对其进行更改,您就会对自己的表单进行黑洞操作。

我有一个很好的小帖子,我学到了这个,look at it。那里的作者还解释了绕过这个问题的两种方法。一种是禁用隐藏字段的安全性,因此为令牌计算的哈希值不包括那些值...这不是很安全...
另一个解决方案是修改FormHelper,并告诉它“锁定”隐藏字段名称而不是值。我不记得作者用于示例的Cake的版本,但是那里给出的代码应该是实际相同的。因此,使用该解决方案,您可以通过选项数组告诉表单不要太严格。

哦,那里给出的另一个选项(这是我通常使用的)(我现在只是在那里阅读......我以为我自己想的......哦,好吧),就是使用正常的输入您想要隐藏的文本字段,并添加像display:none这样的CSS样式。

由您认为最好的取决于您。我喜欢css选项,因为它更简单,而且真的,如果有人要用我的css捣乱(使用firebug或类似的东西),他们也可以用隐藏字段的值来做它,它不需要更多的努力。无论如何,在处理表单提交时,您应该采取所有额外的步骤和验证。但就像我说的那样,你认为哪种情况最适合你的情况。

答案 1 :(得分:1)

除了已经发布的内容之外,还有其他可能导致问题的原因:在我的情况下,隐藏的输入会覆盖它的名称。

$this->Form->create('ExampleModel'):
$this->Form->input('foo_bar', array(
    'type' => 'hidden',
    'name' => 'foo_bar',
));

因此,最终$this->request->data具有相应的键$this->request->data['foo_bar']。它不在$this->request->data['ExampleModel']数组中,问题是什么。

要解决此问题,我必须从模板中删除name键,使输入属于模型的数据,然后只需更改控制器即可接受该值。

希望这有助于其他人。

更新:这也适用于未附加到任何型号的表单,例如:

$this->Form->create(false, array(
    'url' => '/example',
)):