2013-11-15 47 views
5

我正在使用CakePHP的SecurityComponent。這是非常重要的,因爲它可以保存來自CSRF攻擊的表單。我的項目總共有10-12個表單,這是我第一個CakePHP項目。在啓用SecurityComponent後,我有點兒麻煩,但經過一些小心的分鐘後可以消除。這是我的項目的最後一個形式,似乎一切都對我來說是正確的,但仍然是形式是黑洞:(任何人都可以告訴我的問題?我不想禁用CSRF檢查或SecurityComponent。這是我的觀點代碼:請求已被黑洞 - CakePHP

<?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預先感謝

+0

你有沒有機會用javascript改變隱藏輸入的值? – Nunser

+0

是的,我願意。我正在通過jQuery改變4/5隱藏字段。但這是問題嗎? –

+1

也許吧,但讓我們來調試吧。嘗試更改隱藏的簡單文本輸入並嘗試提交表單。如果提交,那麼這是你的問題,我會回答解釋和可能的解決方案。如果不是,那麼我們必須看看還能有什麼。 – Nunser

回答

9
。。

根據註釋,問題的出現是因爲你正在改變表單的隱藏值SecurityComponent的工作方式是它「鎖定」字段的名稱,所以惡意者不能添加新字段或更改值一旦表格被髮送,但是它對隱藏值更加嚴格,因爲它鎖定了字段名稱的值。所以通過使用jQuery來改變它,你就會破壞你自己的形式。

有一個很好的小貼子,我學到了這個,拿look at it。作者還解釋了繞過這個問題的兩種方法。一種是禁用隱藏字段的安全性,所以爲令牌計算的哈希不包括那些值...這是不是真的安全...
而另一種解決方案是修改FormHelper,並告訴它「鎖定」隱藏字段名稱但不是值。我不記得作者使用什麼版本的Cake,但在那裏給出的代碼應該是實用的。因此,通過該解決方案,您可以通過選項數組來告訴表單對您不那麼嚴格。

哦,還有其他的選擇(這是我通常使用的)(我現在只是讀了它......我想我自己想到了......哦),只是使用普通輸入你想隱藏的文本字段,並添加一個像display:none這樣的css風格。

這取決於你自己認爲最好的。我喜歡css選項,因爲它更簡單,而且真的,如果有人打算用我的css(比如螢火蟲或類似的東西)來混淆,他們可能會用隱藏字段的值來做它,它不需要任何更多的努力。無論如何,您應該在處理表單提交時採取所有額外的步驟和驗證。但就像我說的,對你而言,你認爲最適合你的情況。

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', 
)):