Sending form data

En este artículo se analiza lo que sucede cuando un usuario envía un formulario - A dónde van los datos y cómo lo manejamos cuando se llega allí? También tenemos en cuenta algunos de los problemas de seguridad asociados con el envío de los datos del formulario.

Requisitos previos: Conocimientos básicos de informática, una comprensión de HTML , y conocimientos básicos de HTTP y programación del lado del servidor .
Objetivo: Para entender lo que sucede cuando se envía los datos del formulario, incluyendo la obtención de una idea básica de cómo se procesan los datos en el servidor

¿A dónde va los datos?

Aquí vamos a discutir lo que ocurre con los datos cuando se envía un formulario.

Sobre la arquitectura cliente / servidor

La web se basa en una arquitectura cliente / servidor muy básica que se puede resumir de la siguiente manera: un cliente (normalmente un navegador Web) envía una petición a un servidor (la mayoría de las veces un servidor web como Apache , Nginx , IIS , Tomcat , etc.), utilizando el protocolo HTTP . El servidor responde a la solicitud utilizando el mismo protocolo.

Un esquema básico de la arquitectura cliente Web / servidor

En el lado del cliente, un formulario HTML no es más que una manera fácil de usar conveniente para configurar una petición HTTP para enviar datos a un servidor. Esto permite al usuario para proporcionar información a ser entregada en la petición HTTP.

Nota : Para tener una mejor idea de cómo funcionan las arquitecturas cliente-servidor, lea nuestra programación de páginas web del lado del servidor, módulo: primeros pasos. En el lado del cliente: Debes definir como envías los datos.

El elemento {} {HTMLElement ( "forma")} define cómo se enviarán los datos. Todos sus atributos están diseñados para que pueda configurar la solicitud que se enviará cuando un usuario pulsa un botón de envío. Los dos atributos más importantes son acción y método.

El atributo acción.

Este atributo define el lugar donde los datos se envian. Su valor debe ser una dirección URL válida. Si no se proporciona este atributo, los datos serán enviados a la dirección URL de la página que contiene el formulario.

En este ejemplo, los datos se envían a una dirección URL absoluta - http://foo.com:

<Acción del formulario = "http://foo.com">

Aquí, nosotros usamos una URL relativa - los datos se envían a una dirección URL diferente en el servidor:

<Acción del formulario = "/ somewhere_else">

Cuando se especifica sin atributos, como abajo, el <forma> los datos se envían a la misma página en que la "forma" está presente :

<Form>

Muchas páginas más antiguas utilizan la siguiente notación para indicar que los datos deben ser enviados a la misma página que contiene el formulario; Esto fue necesario porque hasta HTML5, el atributo {} {htmlattrxref ( "acción", "forma")} se requería . Esto ya no es necesario.

<Form action = "#">

Nota: Es posible especificar una dirección URL que utiliza el protocolo HTTPS (HTTP seguro). Al hacer esto, los datos se cifran junto con el resto de la solicitud, incluso si el propio formulario está alojado en una página insegura accede a través de HTTP. Por otro lado, si el formulario está alojado en una página segura, pero se especifica una dirección URL HTTP inseguro con el atributo acción , todos los navegadores mostrarán una advertencia de seguridad para el usuario cada vez intenten enviar datos, ya que no se pueden cifrar los datos.

El método atributo

Este atributo define cómo se envían los datos. El protocolo HTTP proporciona varias formas de realizar una solicitud; Los datos del formulario HTML se pueden transmitir a través de un número de diferentes queridos, los más comunes de los cuales son el GETmétodo y el POSTmétodo.

Para entender la diferencia entre estos dos métodos, vamos a dar un paso atrás y examinar cómo funciona HTTP. Cada vez que desee llegar a un recurso en la Web, el navegador envía una petición a una URL. Una petición HTTP consta de dos partes: un encabezado que contiene un conjunto de metadatos mundial sobre las capacidades del navegador, y un cuerpo que puede contener la información necesaria para el servidor para procesar la petición específica.

El método GET

El GETmétodo es el método utilizado por el navegador que pedir el servidor para enviar de vuelta un recurso dado: "Hey servidor, quiero conseguir este recurso." En este caso, el navegador envía un cuerpo vacío. Debido a que el cuerpo está vacío, si un formulario se envía utilizando este método, los datos enviados al servidor se anexan a la URL.

Considere la siguiente forma:

<Form action = "http://foo.com" method = "get">
  <Div>
    <Label for = "dice"> Lo saludo qué quiere decir? </ Label>
    <Input name = "decir" id = "decir" value = "Hola">
  </ Div>
  <Div>
    <Label for = "para"> ¿Quién usted quiere decir que a? </ Label>
    <Input name = "a" value = "mamá">
  </ Div>
  <Div>
    <> Botón enviar mis saludos </ botón>
  </ Div>
</ Form>

Dado que la GETha seguido el método, verá la URL www.foo.com/?say=Hi&to=Momaparece en la barra de direcciones del navegador cuando se envía el formulario.

Los datos se añade a la URL como una serie de pares de nombre / valor. Después de la dirección web URL ha terminado, se incluye un signo de interrogación ( ?) seguido de los pares de nombre / valor, cada uno separado por un signo ( &). En este caso estamos pasando dos piezas de datos en el servidor:

  • say, Que tiene un valor de Hi
  • to, Que tiene un valor de Mom

La solicitud HTTP se ve así:

GET /? = Decir Hola & a = mamá HTTP / 1.1
Anfitrión: foo.com

Nota : Puede encontrar este ejemplo en GitHub - ver llegar-method.html ( verlo en directo también ).

El método POST

El POSTmétodo es un poco diferente. Es el método que el navegador utiliza para comunicarse con el servidor cuando se pide una respuesta que tenga en cuenta los datos proporcionados en el cuerpo de la petición HTTP: "Hey servidor, echar un vistazo a estos datos y me envía de vuelta un resultado apropiado." Si un formulario se envía utilizando este método, los datos se anexa al cuerpo de la petición HTTP.

Veamos un ejemplo - se trata de la misma forma en que lo miró en el GETapartado anterior, pero con la método atributo establecido post.

<Form action = "http://foo.com" method = "post">
  <Div>
    <Label for = "dice"> Lo saludo qué quiere decir? </ Label>
    <Input name = "decir" id = "decir" value = "Hola">
  </ Div>
  <Div>
    <Label for = "para"> ¿Quién usted quiere decir que a? </ Label>
    <Input name = "a" value = "mamá">
  </ Div>
  <Div>
    <> Botón enviar mis saludos </ botón>
  </ Div>
</ Form>

Cuando el formulario se envía mediante el POSTmétodo, no se obtienen los datos adjuntos a la dirección URL, y la solicitud HTTP se parece así, con los datos incluidos en el cuerpo de la petición en su lugar:

POST / HTTP/1.1
Anfitrión: foo.com
Content-Type: application / x-www-form-urlencoded
Content-Length: 13

decir = Hi & a = mamá

La Content-Lengthcabecera indica el tamaño del cuerpo, y la Content-Typecabecera indica el tipo de recurso se envía al servidor. Discutiremos estas cabeceras más adelante.

Nota : Puede encontrar este ejemplo en GitHub - ver post-method.html ( verlo en directo también ).

Visualización de peticiones HTTP

Peticiones HTTP nunca se muestran al usuario (si quieres verlos, es necesario utilizar herramientas como el Monitor de red Firefox o las herramientas de desarrollo de Chrome ). A modo de ejemplo, los datos del formulario se muestran a continuación en la pestaña de Chrome red:

Lo único que se muestra al usuario es la dirección URL llamada. Como mencionamos anteriormente, con una GETpetición del usuario verá los datos en su barra de direcciones, pero con una POSTpetición que no lo hará. Esto puede ser muy importante por dos razones:

  1. Si necesita enviar una contraseña (o cualquier otra pieza sensible de los datos), nunca utilice el GETmétodo o se arriesga a mostrar en la barra de direcciones, lo que sería muy inseguro.
  2. Si necesita enviar una gran cantidad de datos, el POSTse prefiere el método debido a que algunos navegadores limitan los tamaños de las direcciones URL. Además, muchos servidores limitan la longitud de las URL que aceptan.

En el lado del servidor: la recuperación de los datos

Sea cual sea el método HTTP que elija, el servidor recibe una cadena que será analizado con el fin de obtener los datos como una lista de pares clave / valor. La forma de acceder a esta lista depende de la plataforma de desarrollo que use y de las estructuras específicas que pueda estar usando con él. La tecnología se utiliza también determina cómo se manejan claves duplicadas; A menudo, el valor recibido más recientemente para una clave dada se da prioridad.

Ejemplo: PHP Raw

PHP ofrece algunos objetos globales para acceder a los datos. Suponiendo que usted ha utilizado el POSTmétodo, el siguiente ejemplo sólo toma los datos y lo muestra al usuario. Por supuesto, lo que se hace con los datos depende de usted. Es posible visualizarlo, almacenarla en una base de datos, enviarlo por correo electrónico, o procesar de alguna otra manera.

<? Php
  // La variable global $ _POST que permite acceder a los datos enviados con el método POST por su nombre
  // Para acceder a los datos enviados con el método GET, puede usar $ _GET
  $ = Decir htmlspecialchars ($ _POST [ 'decir']);
  $ A = htmlspecialchars ($ _POST [ 'a']);

  echo $ digamos, '', $ a;
?>

Este ejemplo muestra una página con los datos que enviamos. Esto se puede ver en acción en nuestro ejemplo php-example.html archivo - que contiene la misma forma ejemplo, como hemos visto antes, con una methodde posty un actionde php-example.phpEn nuestro ejemplo de antes. Cuando se presentó, envía los datos del formulario a php-ejemplo.php , que contiene el código de PHP visto en el bloque anterior. Cuando se ejecuta este código, la salida en el navegador es Hi Mom.

Nota : Este ejemplo no funcionará cuando se carga en un navegador localmente - navegadores cannnot interpretar el código PHP, por lo que cuando se envía el formulario que el navegador sólo ofrecen para descargar el archivo PHP para usted. Para conseguir que funcione, es necesario ejecutar el ejemplo a través de un servidor PHP de algún tipo. Buenas opciones para probar PHP locales son MAMP (Mac y Windows) y AMPPS (Mac, Windows, Linux).

Ejemplo: Python

Este ejemplo muestra como se puede utilizar Python para hacer la misma cosa - mostrar los datos presentados en una página web. Se utiliza el marco Frasco para la prestación de las plantillas, el manejo de la presentación de datos de formulario, etc (ver python-example.py ).

de importación matraz Matraz, render_template, solicitud
aplicación = Flask (__ name__)

@ App.route ( '/', métodos = [ 'GET', 'post'])
forma def ():
    render_template retorno ( 'form.html')

@ App.route ( '/ hola', métodos = [ 'GET', 'post'])
def hello ():
    render_template retorno ( 'greeting.html', dicen request.form = [ 'decir'], a = request.form [ 'a'])

Si __name__ == "__main__":
    app.run ()

Las dos plantillas de referencia en el código anterior son los siguientes:

  • form.html : La misma forma como hemos visto anteriormente en la El método POST sección, pero con el actionconjunto a {{ url_for('hello') }}. (Esta es una Jinja2 plantilla, que es básicamente HTML, pero puede contener llamadas al código Python que ejecuta el servidor web que figura entre corchetes. url_for('hello')Básicamente está diciendo "redirigir a /hellocuando se envía el formulario").
  • greeting.html : Esta plantilla solo contiene una línea que hace que los dos bits de datos que se pasan a ella cuando se representa. Esto se hace a través de la hello()función se ha visto anteriormente, que se ejecuta cuando la /helloURL se navega a.

Nota : Una vez más, este código no funcionará si sólo intenta cargarlo en un navegador directamente. Python funciona un poco diferente a PHP - Para ejecutar este código local que necesita para instalar Python / PIP , a continuación, instalar el frasco utilizando pip3 install flask. En este punto, usted debe ser capaz de ejecutar el ejemplo utilizando python3 python-example.py, a continuación, navegar a localhost:5000en su navegador.

Otros lenguajes y marcos

Hay muchas otras tecnologías del lado del servidor que puede utilizar para el manejo de formularios, incluyendo Perl , Java , .Net , Rubí , etc. Sólo tiene que elegir el que más le guste. Dicho esto, vale la pena señalar que es muy raro de usar estas tecnologías directamente porque esto puede ser complicado. Es más común el uso de uno de los muchos marcos de formas agradables que hacen un manejo más fácil, tales como:

Vale la pena señalar que incluso el uso de estos marcos, trabajar con formas no es necesariamente fácil . Pero es mucho más fácil que tratar de escribir toda la funcionalidad a sí mismo a partir de cero, y le ahorrará mucho tiempo.

Nota : Está más allá del alcance de este artículo para enseñarle cualquier lenguaje del lado del servidor o marcos. Los enlaces de arriba le dará un poco de ayuda, caso de que deseen aprender.

Un caso especial: el envío de archivos

El envío de archivos con formularios HTML es un caso especial. Los archivos son datos binarios - o considerado como tal - mientras que todos los demás datos son datos de texto. Debido a que HTTP es un protocolo de texto, existen requisitos especiales para el manejo de datos binarios.

El enctype atributo

Este atributo le permite especificar el valor de la Content-Typecabecera HTTP incluido en la solicitud que se genera cuando se envía el formulario. Esta cabecera es muy importante porque le dice al servidor qué tipo de datos se está enviando. Por defecto, su valor es application/x-www-form-urlencoded. En términos humanos, esto significa: "Se trata de datos forma que ha sido codificada en parámetros de URL."

Si desea enviar archivos, es necesario tomar tres pasos adicionales:

  • Ajuste el método atributo POSTporque el contenido del archivo no se puede poner dentro de los parámetros de URL.
  • Establecer el valor de enctype que multipart/form-datadebido a que los datos se dividen en múltiples partes, una para cada archivo más uno para los datos de texto incluidos en el cuerpo de forma (si también se introduce el texto en la forma).
  • Incluir uno o más selector de archivos widgets para permitir a los usuarios seleccionar el archivo (s) que será subido.

Por ejemplo:

<Form method = "post" enctype = "multipart / form-data">
  <Div>
    <Label for = "archivo"> ​​Elija un archivo </ label>
    <Input type = "file" id = "file" name = "myFile">
  </ Div>
  <Div>
    <> Botón Enviar el archivo </ botón>
  </ Div>
</ Form>

Nota: Algunos navegadores son compatibles con la múltiple atributo en el elemento <entrada>, lo que permite más de un archivo para ser elegido para subir con un único <input>elemento . Cómo el servidor gestiona los archivos realmente depende de la tecnología utilizada en el servidor. Como se mencionó anteriormente, el uso de un marco le hará la vida mucho más fácil.

Advertencia: Muchos servidores están configurados con un límite de tamaño para los archivos y las peticiones HTTP con el fin de prevenir el abuso. Es importante comprobar este límite con el administrador del servidor antes de enviar un archivo.

problemas comunes de seguridad

Cada vez que envíe datos a un servidor, debe tener en cuenta la seguridad. formularios HTML son con mucho los vectores de ataque más comunes (en lugares donde ocurren los ataques contra servidores). Los problemas nunca vienen del HTML formas mismas - proceden de cómo el servidor maneja los datos.

Dependiendo de lo que está haciendo, hay algunos problemas de seguridad muy conocidos que te vienen en contra:

XSS y CSRF

Cross-Site Scripting (XSS) y Cross-Site Request Falsificación (CSRF) son tipos comunes de ataques que se producen cuando se muestran los datos enviados por un usuario nuevo al usuario o para otro usuario.

XSS permite a los atacantes inyectar secuencias de comandos del lado del cliente en páginas Web visitadas por otros usuarios. Una vulnerabilidad de secuencias de comandos entre sitio puede ser utilizado por los atacantes para eludir los controles de acceso, como la política del mismo origen . El efecto de estos ataques pueden ir desde una pequeña molestia a un riesgo de seguridad.

ataques CSRF son similares a los ataques XSS en que comienzan de la misma manera - mediante la inyección de comandos de cliente en páginas Web - pero su objetivo es diferente. CSRF atacantes tratan de escalar privilegios a los de un usuario de mayor privilegiada (por ejemplo, un administrador de sitio) para realizar una acción que no deberían ser capaces de hacer (por ejemplo, el envío de datos a un usuario no fiable).

ataques XSS explotar la confianza de un usuario de un sitio web, mientras que los ataques CSRF abusar de la confianza de un sitio web tiene para sus usuarios.

Para evitar estos ataques, siempre se debe comprobar los datos de un usuario envía a su servidor y (si es necesario mostrarlo) no tratan de mostrar el contenido HTML como proporcionada por el usuario. En su lugar, se debe procesar los datos proporcionados por el usuario para que no mostrarlo pie de la letra.  Casi todos los marcos en el mercado hoy implementar un filtro mínimo que elimina el código HTML <script>, <iframe> y <objeto> elementos de datos enviado por cualquier usuario. Esto ayuda a mitigar el riesgo, pero no necesariamente a erradicarla.

inyección SQL

La inyección de SQL es un tipo de ataque que intenta realizar acciones en una base de datos utilizada por el sitio web de destino. Esto normalmente implica el envío de una petición SQL en la esperanza de que el servidor se ejecutará (por lo general cuando el servidor de aplicaciones intenta almacenar los datos enviados por un usuario). Esto es en realidad uno de los principales ataques contra los sitios web de vectores .

Las consecuencias pueden ser terribles, que van desde la pérdida de datos a los ataques que toman el control de una infraestructura de todo el sitio web mediante el uso de una escalada de privilegios. Esta es una amenaza muy seria y nunca debe almacenar los datos enviados por un usuario sin realizar alguna sanitización (por ejemplo, mediante el uso mysql_real_escape_string()de una infraestructura de PHP / MySQL).

inyección de cabecera HTTP y la inyección de correo electrónico

Este tipo de ataques pueden ocurrir cuando su aplicación se basa cabeceras HTTP o mensajes de correo electrónico basado en la entrada de datos por un usuario en un formulario. Estos no dañan directamente su servidor o afectan a sus usuarios, pero son una puerta abierta a problemas más profundos tales como el secuestro de sesión o ataques de phishing.

Estos ataques son en su mayoría en silencio, y pueden dar vuelta a su servidor en un zombi .

Ser paranoico: Nunca confíe en sus usuarios

Entonces, ¿cómo se lucha contra estas amenazas? Este es un tema mucho más allá de esta guía, pero hay algunas reglas a tener en cuenta. La regla más importante es: nunca volver a confiar en sus usuarios, incluyendo a sí mismo; incluso un usuario de confianza podría haber sido secuestrado.

Todos los datos que vienen a su servidor deben comprobarse y desinfectados. Siempre. Sin excepción.

  • Escapar caracteres potencialmente peligrosos. Los caracteres específicos que deben tener cuidado con variará dependiendo del contexto en el que se utilizan los datos y la plataforma de servidores que emplean, pero todos los lenguajes del lado del servidor tienen funciones de este.
  • Limite la cantidad de entrada de datos para permitir sólo lo necesario.
  • Sandbox subido archivos (almacenarlos en un servidor diferente y permitir el acceso al archivo sólo a través de un subdominio diferente o incluso mejor a través de un nombre de dominio totalmente diferente).

Debe evitar muchos / la mayoría problemas si sigue estas tres reglas, pero siempre es una buena idea para obtener una revisión de seguridad realizada por una tercera parte competente. No asuma que usted ha visto todos los posibles problemas.

Nota : La seguridad del sitio web el artículo de nuestro lado del servidor tema de aprendizaje analiza las amenazas anteriores y las posibles soluciones con más detalle.

Conclusión

Como se puede ver, el envío de los datos del formulario es fácil, pero asegurando una aplicación puede ser complicado. Sólo recuerde que un desarrollador de aplicaciones para usuario no es el que debe definir el modelo de seguridad de los datos. Sí, como veremos, es posible realizar la validación de los datos del lado del cliente , pero el servidor no puede confiar en esta validación porque no tiene manera de saber realmente lo que realmente sucede en el lado del cliente.

Ver también

Si desea obtener más información sobre la seguridad de una aplicación web, se puede excavar en estos recursos:

Etiquetas y colaboradores del documento

 Colaboradores en esta página: SphinxKnight, chrisdavidmills, Ricky_Lomax
 Última actualización por: SphinxKnight,