2012-01-11 6 views
5

У меня есть непростая проблема ... это кажется сложнее, чем должно быть.Запретная ошибка при отправке простой формы PHP

У меня есть простая форма, которая используется для добавления контента на сайт. В некоторых из полей должен быть введен html. Однако, когда вы вводите некоторые элементы html в разные части формы, он решает, что он ненавидит вас и бросает запрещенную ошибку 403. Вот приведенная ниже форма:

<?php 
    $data = f("SELECT * FROM table WHERE id = '{$_GET['id']}'"); 
?> 
<form action="<?=$_SERVER['PHP_SELF']?>?id=<?=$_GET['id']?>&action=edit" method="post"> 
    <table cellspacing="0" cellpadding="2" border="0"> 
     <tr> 
      <td><b>Title:</b></td> 
      <td><input type="text" name="title" style="width: 300px;" value="<?=$data['title']?>" /></td> 
     </tr> 
     <tr> 
      <td><b>URL:</b></td> 
      <td><input type="text" name="url" style="width: 300px;" value="<?=$data['url']?>" /></td> 
     </tr> 
     <tr> 
      <td><b>Sub-Category:</b></td> 
      <td> 
       <select name="subCategoryId"> 
        <option value=""></option> 
        <option value="1">A</option> 
        <option value="2">B</option> 

       </select> 
      </td> 
     </tr> 
     <tr> 
      <td><b>Short Description:</b></td> 
      <td><textarea name="shortDescription" rows="6" cols="60"><?=$data['shortDescription']?></textarea></td> 
     </tr> 
     <tr> 
      <td><b>Template:</b></td> 
      <td><textarea name="template" rows="6" cols="60"><?=$data['template']?></textarea></td> 
     </tr> 
     <tr> 
      <td><b>Ads:</b></td> 
      <td><textarea name="ads" rows="6" cols="60"><?=$data['ads']?></textarea></td> 
     </tr> 
     <tr> 
      <td><b>Keywords:</b></td> 
      <td><textarea name="keywords" rows="6" cols="60"><?=$data['keywords']?></textarea></td> 
     </tr> 
     <tr> 
      <td><b>Questions:</b></td> 
      <td><textarea name="questions" rows="6" cols="60"><?=$data['questions']?></textarea></td> 
     </tr> 
     <tr> 
      <td><b>Salary:</b></td> 
      <td><textarea name="salary" rows="6" cols="60"><?=$data['salary']?></textarea></td> 
     </tr> 
     <tr> 
      <td><b>Jobs:</b></td> 
      <td><textarea name="jobs" rows="6" cols="60"><?=$data['jobs']?></textarea></td> 
     </tr> 
     <tr> 
      <td><b>Meta Description:</b></td> 
      <td><input type="text" name="metaDescription" style="width: 300px;" value="<?=$data['metaDescription']?>" /></td> 
     </tr> 
     <tr> 
      <td><b>Meta Keywords:</b></td> 
      <td><input type="text" name="metaKeywords" style="width: 300px;" value="<?=$data['metaKeywords']?>" /></td> 
     </tr> 
     <tr> 
      <td>&nbsp;</td> 
      <td><input type="submit" name="submit" value="Edit Job" /></td> 
     </tr> 
    </table> 
</form> 

У меня есть другие формы, которые следуют этой же схеме без каких-либо проблем. Чтобы сделать это еще более запутанным, он будет вызывать эту ошибку только в том случае, если в текстовой области будут помещены любые 2 html-элемента (он отлично обрабатывает один элемент html). Текстовыми областями являются объявления, ключевые слова, зарплаты и рабочие места. Другие текстовые области сделают это очень хорошо, но эти 4 не будут. Если я могу сделать это еще немного запутанным, если я просто вложу текст в эти поля и сохраню его, он будет работать без проблем.

Чтобы обрабатывать данные сообщения, я использую mysql_real_escape_string() для обработки данных, я не делаю strip_tags(), поскольку мне нужен html.

Является ли это странной ошибкой apache, которая может быть исправлена ​​с помощью .htaccess? Есть ли в PHP модуль, который противоречит этому?

------- EDIT ВОТ ОТВЕТ --------

Бен воспитан фантастический ответ, который, вероятно, проблема, и я не могу исправить это из-за отсутствия льгот , Поэтому я создал событие onsubmit из идеи, которую дал мне Gerben, и написал следующий javascript.

function awesome() { 
     elements = document.forms[0].elements; 
     for(var i = 0; i < elements.length; i++) { 
      switch(elements[i].name) { 
       case "ads": 
       case "shortDescription": 
       case "template": 
       case "questions": 
       case "salary": 
       case "jobs": 
        str = elements[i].value; 
        elements[i].value = str.replace(/</g,"#@!"); 
        break; 
      } 
     } 
     return true;  
    } 

Тогда на принимающей стороне я сделал str_replace для замены # @! назад к < и это по крайней мере сделало вещь работающей.

Я нахожусь на лошади .... hyaa!

Благодарим за помощь. :)

+1

Можете ли вы также опубликовать код, который отвечает за обработку представления? Это может быть проблема перенаправления или ошибки, сгенерированная с помощью проверки php. –

+1

Является ли URL-адрес другим при отправке формы, как предполагалось в URL-адресе самой страницы формы? – Gerben

+0

@BenD На самом деле нет никакого кода, отвечающего за обработку представления. Это простой оператор foreach, который запускается через vars_post и бросает на них mysql_real_escape_string. Нет никакой проверки javascript. Вы просто попали в submit, он загружает одну и ту же страницу, он просто попадает в оператор switch, который должен поместить его в область для обновления информации. Он работает для всего остального (тот же оператор foreach) на других частях сайта, только не здесь, когда задействовано несколько элементов html. – n0nag0n

ответ

7

Учитывая, что вы можете публиковать сообщения, и что ваша пост-обработка, по-видимому, чрезвычайно проста и вряд ли будет метать 403 ошибки или перенаправлять на запрещенные каталоги, я собираюсь опасаться, re работает брандмауэр уровня Apache. Просмотрите конфигурационные файлы apache и проверьте, загружен ли модуль mod_security или какой-либо другой модуль брандмауэра. Существует несколько способов настройки mod_security, включая сканирование данных POST для содержимого html и соответствующее реагирование. Если он настроен на предотвращение инъекции html, это может быть вашей проблемой (подробности см. Здесь: http://www.modsecurity.org/projects/modsecurity/apache/feature_content_injection.html).

Чтобы проверить это, попробуйте добавить файл Htaccess в корневой каталог вашего веб (при условии, что вы разрешили переопределить Apache настройки с Htaccess) и настройки:

SecFilterEngine Off 

Перезапустите Apache, а затем посмотреть, если это все-таки происходит.

Если это общий хост или у вас нет возможности изменять параметры apache, вы можете попробовать обходной путь, используя javascript, чтобы base64 encodes все данные перед отправкой (onsubmit), а затем base64_decode ($ _ POST [ key]) в скрипте php, который его обрабатывает.

+1

Я думаю, что не могу переопределить эту функцию. Я сделал phpinfo(); и я ничего не видел о брандмауэре или mod_security. Я попытался ввести код в файл htaccess, и он дал мне Internal Server Error 500. Это еще одна учетная запись клиентов, и они используют fastwebhost.com, который ... блокирует ваш IP-адрес, если вы дышите неправильно. – n0nag0n

+0

Спасибо за помощь. Я понял это с твоей помощью и с Гербеном. – n0nag0n

+0

Это отличная идея. Мой больше ... новичок и ..... да, просто новичок. :) – n0nag0n

1

Просто у меня такая же проблема при отправке показала ошибку 403, но для меня это было просто, потому что форма была слишком большой, вызывая правило о mod_security.

Также стоит увеличения php.ini post_max_size и размера теста с использованием: $_SERVER['CONTENT_LENGTH']

0

Может быть ABIT поздно, но я сталкивался с подобной проблемой сегодня при попытке отправить форму через POST. Это не позволило мне отправить текст со ссылкой и выбросит ошибку 403 Forbidden Acess Denied. Отключение modsecurity (я сделал это с панели управления) решил!

Смежные вопросы