请求已被黑洞 - CakePHP

2021-12-21 00:00:00 php cakephp

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

Form->create('Record');?><script type="text/javascript">var me = new MetroExam();<div class="exam_paper"><div class="question_box" id="q_b"><div class="q_n_a_header"><div class="指令"><b>说明:</b><br><?=$inst['value_text'];?>

<div id="timer">请稍候</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 class="ans_box" id="a_b"><!-- 关于答题纸的信息.!重要--><?php$i = 0;//这些字段对于评估 ans 论文至关重要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 = 数组('1' =>'一个','2' =>'乙','3' =>'C','4' =>'D');if($exam['choices'] == 5){$options['5'] = '无';}$questions = (int)$exam['questions'];//40 <= $exam['questions'] <= 100$i = 1;而($问题--){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>';回声'</div>';$i++;}echo $this->Form->end('Submit');?>

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

解决方案

根据评论,出现问题是因为您正在更改表单的隐藏值.SecurityComponent 的工作方式是锁定"字段的名称,因此一旦发送表单,作恶者就无法添加新字段或更改值.但是它对隐藏值更加严格,因为它锁定了字段名称和值.因此,通过使用 jQuery 更改它,您就是在黑洞化您自己的表单.

有一个不错的小帖子,我学到了这一点,请参考 看看它.那里的作者还解释了绕过这个问题的两种方法.一种是禁用隐藏字段的安全性,因此为令牌计算的哈希不包括那些值......这不是真正安全......
另一种解决方案是修改 FormHelper,并告诉它锁定"隐藏字段 names 而不是值.我不记得作者在示例中使用了什么版本的 Cake,但是那里给出的代码实际上应该是相同的.因此,使用该解决方案,您可以使用选项数组告诉表单不要对您如此严格.

哦,那里给出的另一个选项(这是我通常使用的)(我现在刚在那里读过......我想我自己认为......哦),就是使用普通输入为您想要隐藏的文本字段添加一个 css 样式,如 display:none.

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

I'm using CakePHP's SecurityComponent. And it's very essential as it saves forms from CSRF attacks. My project has total 10-12 forms and this is my first CakePHP project. After enabling SecurityComponent I was in a bit trouble but could get rid off after some careful minutes. This is the last form of my project and seems everything is correct to me but still the form is being black holed :(. Can anybody please tell me the problem? I don't want to disable CSRF checking or SecurityComponent. Here is my view code:

<?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>

This is basically a MCQ exam form. Where each group has 4 or 5 radio buttons and total 40 to 100 groups in a form. I'm using CakePHP 2.4. Thanks in advance.

解决方案

As per the comments, the problem appears because you are changing the hidden values of the form. The way SecurityComponent works, is that it "locks" the name of the fields, so an evildoer can't add new fields or change the values once the form is sent. But it is even more strict with the hidden values, because it locks the field name and value. So by changing it with jQuery you're blackhole-ing your own form.

There's a nice little post where I learned this, take a look at it. The author there also explains two ways of bypassing this problem. One is to disable the security for hidden fields, so the hash calculated for the token doesn't include those values... which isn't really secure...
And another solution is to modify the FormHelper, and tell it to "lock" the hidden fields names but not the values. I don't remember what version of Cake the author uses for the example, but the code given there should be practicaly the same. So with that solution, you can tell the form to not be so strict with you with an option array.

Oh, and the other option given there (this is what I normally use) (I just read it now there... I thought I figure that on my own... oh well), is to just use normal input text fields for the ones you want hidden, and add a css style like display:none.

It's up to you what you think is best. I like the css option because is simpler, and really, if someone is going to mess with my css evily (with firebug or something like that), they might just as well do it with the values of hidden fields, it doesn't require any more effort. You should take all the extra steps and verifications when handling that form submission anyway. But like I said, up to you which do you think is best for your situation.

相关文章