2013-11-15 2 views
5

Я использую CakePHP's 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

Да, да. Я изменяю 4/5 скрытых полей jQuery. Но это проблема? –

+1

Наверное, но давайте отлаживаем. Попробуйте изменить скрытые для простых текстовых входов и попробуйте отправить форму. Если он подает, то это ваша проблема, и я отвечу с объяснением и возможным решением. Если нет, то мы должны увидеть, что еще это может быть. – Nunser

ответ

9
....

В соответствии с комментариями проблема возникает из-за изменения скрытых значений формы. Способ работы SecurityComponent заключается в том, что он «блокирует» имя полей, поэтому злоумышленник не может добавлять новые поля или изменять значения после отправки формы. Но еще более строгий со скрытыми значениями, поскольку он блокирует имя поля и значение. Поэтому, изменив его с помощью jQuery, вы делаете черную дыру своей собственной формой.

Есть хороший маленький пост, где я узнал об этом, возьмите look at it. Здесь автор объясняет два пути обхода этой проблемы. Один из них - отключить защиту для скрытых полей, поэтому хэш, рассчитанный для токена, не включает эти значения ... который не очень безопасен ...
И еще одно решение - изменить FormHelper и сообщить ему «заблокировать» скрытые поля имена, но не значения. Я не помню, какую версию Cake автор использует для примера, но приведенный здесь код должен быть практически то же самое. Таким образом, с помощью этого решения вы можете сообщить, что форма не будет настолько строгой с вами с помощью массива параметров.

О, и другой вариант, данный там (это то, что я обычно использую) (я только что прочитал его сейчас ... Я думал, что сам по себе это делаю ... ну, хорошо), это просто использовать нормальный введите текстовые поля для тех, которые вы хотите скрыть, и добавьте стиль css, например display:none.

Это зависит от вас, что вы считаете лучшим. Мне нравится опция css, потому что она проще, и действительно, если кто-то собирается запутаться в моем CSS-сообщении (с помощью firebug или что-то в этом роде), они могут так же хорошо справиться со значениями скрытых полей, это не требует больше усилий. В любом случае вы должны выполнить все дополнительные шаги и проверки при обращении с этой формой. Но, как я уже сказал, до вас, как вы думаете, лучше всего подходит для вашей ситуации.

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', 
)): 
Смежные вопросы