2012-01-11 15 views
5

Tengo un problema no complicado ... que parece ser más complicado de lo que debería ser.Error prohibido al enviar el formulario PHP simple

Tengo un formulario simple que se utiliza para agregar contenido a un sitio web. Algunos de los campos necesitan tener html ingresado en ellos. Sin embargo, cuando ingresa ciertos elementos html en las diferentes partes del formulario, decide que lo odia y arroja un error 403 prohibido. Aquí está el siguiente formulario:

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

Tengo otras formas que siguen este mismo patrón sin ningún problema. Para hacer esto aún más confuso, solo arrojará este error cuando se suministren elementos de 2 html en el área de texto (maneja muy bien un elemento html). Las áreas de texto son anuncios, palabras clave, salarios y trabajos. Las otras áreas de texto lo tomarán bien, pero estos 4 no lo harán. Si puedo hacer esto un poco más confuso, si simplemente ingreso texto en esos campos y lo guardo, se ejecuta sin problemas.

Para manejar los datos de la publicación, solo uso mysql_real_escape_string() para manejar los datos, no hago una strip_tags() ya que necesito el html allí.

¿Es este un extraño error de apache que se puede arreglar con .htaccess? ¿Hay algún módulo en PHP que esté en conflicto con esto?

------- EDITAR Aquí está la respuesta --------

Ben trajo una respuesta fantástica que es probablemente el problema y no puedo solucionarlo debido a la falta de privilegios . Así que creé un evento onsubmit a partir de una idea que Gerben me dio y escribí el siguiente 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;  
    } 

Luego, en el extremo receptor, hice un str_replace para reemplazar # @! de vuelta a un < y eso al menos hizo que la cosa funcionara.

Estoy en un caballo .... hyaa!

Gracias por su ayuda. :)

+1

¿También puede publicar el código que está a cargo de procesar la presentación? Esto puede ser un problema de redirección o controlador de errores generado por la validación de php. –

+1

¿La URL se ve diferente al enviar el formulario, como se supone a la url de la página del formulario en sí? – Gerben

+0

@BenD Realmente no hay ningún código a cargo de procesar la presentación. Es un enunciado foreach simple para ejecutar los valores $ _POST y arrojar mysql_real_escape_string sobre ellos. No hay ninguna validación de JavaScript. Simplemente presiona enviar, carga la misma página, simplemente cae en una declaración de cambio que debe aterrizar en el área para actualizar la información. Funciona para todo lo demás (la misma declaración foreach) en otras partes del sitio, simplemente no aquí cuando se trata de múltiples elementos html. – n0nag0n

Respuesta

7

Dado que puede publicar, y que su manejo posterior es aparentemente muy simple y es tan improbable que arroje errores 403 o redireccione a directorios prohibidos, voy a arriesgarme a suponer que está ' re ejecutar un firewall de nivel apache. Eche un vistazo a los archivos de configuración de Apache y compruebe si está ejecutando mod_security o cualquier otro módulo de firewall cargado. Hay varias formas en que mod_security se puede configurar, incluyendo el escaneo de datos POST para contenido html y reaccionando en consecuencia. Si está configurado para evitar la inyección html, este puede ser su problema (consulte los detalles de configuración aquí: http://www.modsecurity.org/projects/modsecurity/apache/feature_content_injection.html).

Para probar esto, trate de añadir un archivo .htaccess en su raíz web (suponiendo que se permite anular la configuración de Apache con .htaccess) y ajuste:

SecFilterEngine Off 

Reiniciar Apache y luego ver si todavía está sucediendo.

Si este es un host compartido, o si no tiene la capacidad de modificar la configuración de apache, puede intentar una solución usando javascript que base64 encodes todos los datos antes de enviar (onsubmit), y luego base64_decode ($ _ POST [ clave]) en el script php que lo procesa.

+1

Estoy pensando que no puedo anular esa función. Hice phpinfo(); y no vi nada sobre firewall, o mod_security. Traté de ingresar el código en un archivo htaccess y me dio un Internal Server Error 500. Es otra cuenta de clientes y están usando fastwebhost.com que .... bloquea tu IP si respiras mal. – n0nag0n

+0

Gracias por su ayuda. Lo descubrí con la tuya y la ayuda de Gerben. – n0nag0n

+0

Esa es una gran idea también. El mío es más ... novato y ... sí solo novato. :) – n0nag0n

1

Acabo de tener el mismo tipo de problema en el envío mostró error 403, pero para mí fue simple porque el formulario era demasiado grande, lo que desencadenó una regla en mod_security.

También vale la pena aumentar php.ini post_max_size y tamaño de la prueba usando: $_SERVER['CONTENT_LENGTH']

0

Podría ser un poco tarde, pero se enfrentaron a un problema similar en la actualidad al intentar enviar un formulario a través del poste. No me permitiría enviar un texto con un enlace y arrojaría un error de Prohibición de acceso prohibido 403. Desactivando modsecurity (lo hice desde el panel de control) lo resolvió!

Cuestiones relacionadas