¿Cuáles son algunos de los posibles ataques que pueden llevarse a cabo en un sitio HTTP (sin SSL)?

Escribí esto como un artículo para una revista. Puedes leer el original o debajo. Creo que el formato del artículo original es mejor.

Página en healthycodemagazine.com

¿Cómo saber si está desarrollando un sitio web inseguro?

¿Qué es exactamente un sitio web inseguro?

Cualquier sitio web se crea para cumplir con cierta funcionalidad. En la mayoría de los casos, un sitio web ofrece capacidades personalizables por usuario. El sitio web también se ejecuta sobre una pila completa de software y hardware. Un sitio seguro garantizará que los datos del usuario no sean robados debido a cualquier debilidad de configuración o aplicación. Por lo tanto, un sitio web inseguro puede permitir el robo de datos del usuario o incluso el acceso a partes del software en el servidor.

Una pregunta común que se hace es acerca de por qué nuestro sitio web es un objetivo o nuestro sitio web no es nada especial, no tiene nada que atraiga a un ladrón. Bueno, eso simplemente no es cierto. Hay varias cosas que los ladrones de datos podrían estar buscando. La investigación muestra que la mayoría de los usuarios de sitios web reutilizan contraseñas. Entonces, si el nombre de usuario de su sitio web era básicamente su dirección de correo electrónico, hay buenas posibilidades de que un porcentaje de los usuarios del sitio web tenga la misma contraseña en otro lugar también. Considere lo que almacenamos en los buzones. Extractos bancarios, información de cuenta para sitios web sensibles y más.

Además de los datos importantes, la mayoría de los sitios web están utilizando conexiones rápidas a Internet, atendidos desde centros de datos con copias de seguridad, etc. Tal computadora puede ser bastante valiosa como plataforma de lanzamiento para un atacante. El procesador, la memoria de la computadora, el espacio en el disco duro, todo eso puede ser útil para un atacante.

### ¿Y por qué debería ser difícil saber cuándo usted o alguien está desarrollando un sitio web inseguro?
Ningún desarrollador quiere construir un sitio que pueda verse comprometido debido a vulnerabilidades en el código. Del mismo modo, ningún administrador web quiere que un sitio sea pirateado debido a debilidades en la configuración del servidor. Entonces la pregunta es por qué es difícil resolver esto.

En primer lugar, un sitio web tiene muchos programas sobre los que no tiene control.

Una mirada simplificada a las capas.

Entonces, para un sitio web seguro, incluso antes de escribir una línea de código, el servidor web subyacente, el sistema operativo, el sistema de archivos, la pila de red e incluso el hardware físico. ¿Cuántos de nosotros vemos en realidad el hardware desde el que se sirve nuestro sitio web? Así que supongamos que el servidor físico es seguro, la pila de red del sistema operativo está protegida y totalmente parcheada y el servidor web está configurado según las mejores prácticas y de nuevo completamente seguro. En este punto, podemos comenzar a pensar en la seguridad y la solidez del código del sitio web.

Construir sitios web se trata de hablar con un montón de sistemas

Un sitio web está compuesto de múltiples cosas. Existe el código que se va a interpretar. El intérprete más común es PHP. Debe haber un proceso que pueda interpretar el código. La combinación habitual es usar el servidor web Apache con un módulo llamado mod_php. Si el sitio web admite una base de datos, la mayoría de los sitios web modernos lo hacen, entonces el sitio web necesita tener el controlador para hablar también con el sistema de base de datos. Algunas veces los sitios web están detrás de los equilibradores de carga, tienen características de registro externo, dependen de otros servicios web, etc. Todos estos son sistemas. Un sitio web moderno contiene muchas bibliotecas de terceros que pueden depender de sistemas adicionales.

Si el sitio web tiene un requisito para la Seguridad de la capa de transporte (a veces se denomina incorrectamente SSL o HTTPS de capa de sockets seguros).

Todo lo que se requiere para servir un sitio web

Todos los sistemas necesitan hablar sincronizados para que un sitio web funcione correctamente. Al igual que hay una pila de cosas en el lado del servidor, también hay una pila de cosas en el cliente. Por ahora, sigamos discutiendo cosas en el lado del servidor por ahora.

Muchos de los sistemas que prestan servicio a un sitio web dependen de comandos y datos que provienen del sitio web para sus operaciones. Por ejemplo, si tiene una lista de usuarios almacenados en el servidor de la base de datos y su sitio web desea recuperar eso para alguna operación, enviará comandos y datos al servidor de la base de datos. Dado que la mayoría de los servidores de bases de datos tienden a ser sitios web de RDBMS, deben poder hablar en el idioma que entiendan. El lenguaje de consulta estructurado es la forma más común para que un sitio web hable con un servidor de base de datos.

Al igual que PHP, SQL también requiere un intérprete. La parte compleja para el intérprete es comprender qué parte de la comunicación es un comando y cuáles son los datos.

Por ejemplo, si intentáramos obtener todos los nombres de usuario para Bangalore City, esta es la consulta SQL que necesitaremos escribir.

“SELECCIONAR nombre de usuario DESDE usertable WHERE city = ‘Bangalore’;”

En esto, todo menos el nombre de la ciudad es el comando para el intérprete de SQL y * cityname * son nuestros datos. Según nuestro sitio web, también podría haber otros nombres de ciudades.

De la página en xkcd.com

Por lo tanto, es un problema cuando los intérpretes pueden ser engañados para ejecutar el comando cuando esperan datos. Esto es tan dañino y tan común que tiene un nombre. Se llama Inyección de forma genérica y el ejemplo en la tira cómica se llama Inyección SQL. De acuerdo con Open Web Application Security Project, la inyección es la falla más mortal y común que se encuentra en los sitios web. Está catalogado como el número 1 en su lista de los 10 riesgos principales que enfrentan los sitios web y las aplicaciones.

[OWASP Top 10 2013] (https://www.owasp.org/index.php/…)

Como verá, este problema no es particular en el lado del servidor, sino que también puede ocurrir en el lado del cliente.

¿Te llamas el intérprete más popular del lado del cliente? ¿Has oído hablar del término Cross Site Scripting?

Entrada del usuario, no puedo vivir con ella, no puedo vivir sin ella

Entonces, ¿qué está sucediendo exactamente cuando los comandos y los datos se mezclan? ¿Y por qué sucede? ¿No podemos tratar la causa raíz en sí misma?

Los sitios web modernos dependen de la entrada del usuario para todo. Básicamente son aplicaciones que esperan que varios tipos de entradas provenientes de los usuarios funcionen de cierta manera. Todos estamos acostumbrados a enviar correos electrónicos en un sitio web ahora. Antes de que Gmail se hiciera famoso con su bandeja de entrada de 1 GB, mucha gente solía usar el software de cliente de correo instalado en sus computadoras para acceder al correo electrónico. Mucha gente cambió porque el sitio web que ofrecía correo electrónico gratuito con una bandeja de entrada grande era más rápido en la búsqueda que su propia computadora que ejecutaba el software de correo. Ahora tenemos todo tipo de aplicaciones que ofrecen personalizaciones basadas en la información que proporcionamos. Por lo tanto, está bastante claro que la entrada del usuario se escucha para quedarse.

El problema con la entrada del usuario es que es una entrada del usuario. La mayoría de los programadores que crean sitios web suponen, aunque ingenuamente, que los usuarios son benignos y solo enviarán datos que les permitirán trabajar con el sitio web. La mayoría de las pruebas realizadas por los equipos de control de calidad se centran en garantizar que todas las funciones tengan sentido.

Probemos algunos casos de prueba para esto. El siguiente código es un ejemplo extremadamente simple de una aplicación, que toma el parámetro (entrada del usuario) llamado “nombre de usuario” y lo muestra en una página web.

<? php

$ username = $ _GET [‘nombre de usuario’];
print “

Hola $ nombre de usuario

“;

?>

Aloje este fragmento de código como un archivo llamado “user.php”.

Ahora vamos a probar esto por seguridad.

#### Caso de prueba 1

http: //servername/user.php? usern …

El usuario habitual solo proporciona su nombre

Caso de prueba 2

http: //servername/user.php? username =

Akash

El atacante agrega código JavaScript que se ejecutará en el navegador de un usuario

De acuerdo, este es un ejemplo extremadamente simplificado. Pero hace un punto. Cualquier entrada del usuario al sitio web que no esté validada por el código que se ejecuta en el sitio web tiene el potencial de atacar.

Los observadores astutos como tú notarán algo y exclamarán: * “Pero esto está ejecutando el navegador de un usuario, ¿cómo es esto un ataque a la aplicación?” *

Tienes toda la razón. Mientras hablamos de la seguridad o la inseguridad de un sitio web, necesitamos comprender lo que se está atacando. El ejemplo que acabamos de ver ataca claramente al usuario del sitio web y no al sitio web en sí.

En el ejemplo anterior, todo lo que hicimos fue ejecutar un cuadro de alerta simple que imprime la cadena “XSS”. ¿Qué pasaría si, en lugar de hacer eso, creáramos un elemento de marco flotante invisible y lo señalamos a una URL que controlamos y concatenamos la cookie de sesión? En este punto, podríamos haber suplantado al usuario actualmente conectado que tuvo la desgracia de hacer clic en nuestro enlace. Piense que esta es una lectura descabellada sobre cómo el servidor de Apache Software Foundation fue pirateado, así como así.

[Informe de incidentes de pirateo del servidor Apache] (https://blogs.apache.org/infra/e…)

Atacando el servidor

¿Cómo crees que los servidores son atacados? Sí, nuevamente la respuesta es controlada por el usuario. Los atacantes adoran los formularios con carga de archivos, cuadros de búsqueda donde pueden administrar enviar comandos SQL como parte de los datos.

Obtenga el nombre de usuario, la contraseña de un usuario y vea si coinciden con lo que proporciona un usuario.

SELECCIONE nombre de usuario, contraseña DE usuarios DONDE usuario = ‘$ nombre de usuario’ y contraseña = ‘$ contraseña’;

Permítanos proporcionar un nombre de usuario y contraseña adecuados

$ username = “akash”;
$ contraseña = “thisisanextremelycomplicatedpasswordThisPasswordIsLong”;

La consulta se convierte en

SELECCIONE nombre de usuario, contraseña DE usuarios DONDE user = ‘akash’ y password = ‘thisisanextremelycomplicatedpasswordThisPasswordIsLong’;

Esto es bastante sencillo. Ahora veamos qué puede enviar un atacante.

$ username = “akash O 1 = 1 – //”;
$ contraseña = “no me importa lo que ingrese aquí”

La consulta se convierte en

SELECCIONE nombre de usuario, contraseña DESDE usuarios DONDE usuario = ” O 1 = 1 – // ‘y contraseña =’ no me importa lo que ingrese aquí ‘;

¿Cómo crees que el intérprete de SQL en el servidor interpretará esto?

Evaluará el entero 1 como igual a 1 y verá las etiquetas de comentario e ignorará el resto de la consulta. Dado que esto se evalúa como verdadero, en función de la lógica de autenticación del sitio web, se puede evaluar como verdadero y permitir que “akash” inicie sesión.

Aún peor podría ser si el usuario ingresa “admin ‘OR 1 = 1“.

En MySQL, las etiquetas de comando son dos signos menos seguidos de un espacio, las dos barras al final aseguran que se mantenga el espacio.

Así que ahora hay una clara declaración del problema.

Entonces, ¿en quién confiamos?

Nos gustaría crear sitios web que permitan la personalización, la personalización y se comporten de manera diferente para diferentes usuarios, pero si no podemos confiar en los comentarios de los usuarios, ¿qué hacemos?

* Confía en la fuente, Luke *

Lo único en lo que realmente podemos confiar es en el código que se ejecuta en el servidor. La lógica de negocios, la lógica de autenticación y todos los demás elementos que intervienen en la creación de un sitio web. ¿Por qué deberíamos confiar en eso? Te escucho preguntar. Bueno, porque de alguna manera escribiste ese código. Entonces por eso.

Tenga en cuenta que todos los datos de entrada que recibe son incorrectos o contaminados. No se deben realizar operaciones en el sitio web con datos contaminados. Primero ejecutamos nuestras rutinas de validación en los datos contaminados. Las rutinas de validación pueden ser bastante simples.

* Se requiere nombre de usuario en el formulario.
* El nombre de usuario puede ser alfanumérico y no más de 30 caracteres.

Ahora se trata realmente de una simple validación. Una comilla simple no es un carácter alfanumérico y si la longitud es superior a 30, simplemente descarte dichos datos.

Una vez que todos los datos contaminados hayan pasado por las validaciones de su código (lo único en lo que puede confiar), ahora puede comenzar a usar estos datos. Esto ya no es simplemente una entrada del usuario. Esta es una entrada validada por el usuario.

Así es como puedes generar confianza.

La mayoría de las veces lidiará con el problema de poder identificar todas las piezas de entrada del usuario, en lugar de cómo hacerlo válido.

Examen sorpresa

¿Cuántos de los siguientes datos pueden ser controlados por un usuario?

1. Cadena de consulta
2. Parámetros POST
3. Cookie
4. UserAgent
5. Referer
6. Un archivo cargado por un usuario
7. JSON procedente de un AJAX (solicitud XML HTTP)
8. Verbo HTTP
9. Cualquier encabezado que comience con X-
10. Nombre de archivo del archivo que está cargando un usuario

¿Cuántos respondiste como controlado por el usuario? Todo lo anterior son datos que son controlados por el usuario. Algunos de ellos no se pueden cambiar si el usuario está utilizando un software de navegación web estándar. Pero todos ellos pueden ser manipulados, manipulados y difusos mediante el uso de clientes web que no son navegadores o mediante servidores proxy de intercepción como Burp Suite Pro, OWASP Zap, etc.

Por lo tanto, los sitios web enfrentan un problema masivo con confianza. Algo de esto también se debe al diseño simplista del propio protocolo HTTP. Eso sí, personalmente creo que el protocolo es increíble y ha resistido la prueba del tiempo bastante bien. Pero obviamente, como con todo lo demás, muestra signos de envejecimiento. No temas, la versión 2.0 de HTTP ya se está discutiendo y desarrollando activamente a medida que lees esto.

Autenticación

HTTP es un protocolo sin estado. Existe suficiente literatura sobre HTTP que no hay razón para repetirla. Hay un resultado específico de HTTP sin estado en términos de autenticación. Si estamos utilizando una cookie de sesión con un valor suficientemente aleatorio para identificar un cliente al servidor, entonces dicho valor debe enviarse al servidor cada vez, el cliente quiere que el servidor lo identifique.

Por ejemplo, si su oficina está protegida por un lector de tarjetas magnéticas. El hecho de que haya robado su documento de identidad por la mañana no significa que la puerta se le abrirá durante todo el día. Cada vez que entre y salga de la oficina deberá deslizar la tarjeta de identidad.

Por lo tanto, está muy bien que tenga autenticación y el servidor establecerá una variable de sesión fuerte en una cookie para que cada vez que solicite un recurso del servidor, la cookie se envíe como parte de la solicitud y obtendrá la respuesta correcta.

Pero esto puede conducir a * el confuso problema adjunto *.

El problema adjunto confundido

Las secuencias de comandos de sitios cruzados atacan a los usuarios de un sitio web y les roban información. La inyección SQL ataca al servidor directamente para robar datos, omitiendo los mecanismos de inicio de sesión y, en algunos casos, incluso ejecuta comandos en los servidores.

Hay otro ataque que hace algo tan siniestro que se puede hacer que un usuario legítimo de un sitio web ataque un sitio web sin darse cuenta.

Como HTTP no tiene estado y nuestra cookie de sesión debe enviarse al servidor con cada solicitud, el navegador web lo hará automáticamente en nuestro nombre. ¡Qué pequeño software útil es ese!

Ahora, ¿qué pasa si un atacante sabe que regularmente vamos a un determinado sitio web donde iniciamos sesión? ¿No se me ocurre ningún sitio de este tipo? ¿Qué pasa con su sitio de correo electrónico basado en la web, o el sitio interno de la intranet corporativa donde puede solicitar permisos y verificar su salario?

Por lo tanto, se supone que el atacante sabe qué sitio web visitamos y sabe que lo más probable es que iniciemos sesión en él. Eso significa que nuestra cookie de sesión será válida en ese sitio web en ese momento. En este punto, si abrimos un enlace controlado por el atacante en nuestro navegador web con su brillante interfaz con pestañas, podemos ser engañados para atacar el sitio web por el código que está bajo el control de los atacantes, aunque es posible que ni siquiera nos demos cuenta hasta que sea demasiado tarde.

En el lenguaje OWASP, esto se denomina falsificación de solicitud de sitios cruzados y se pronuncia como Sea-Surf. La mayoría de los sitios web que confían implícitamente en todos sus usuarios solían ser vulnerables a este ataque hasta hace muy poco.

¿Cómo crees que un sitio web puede protegerse de tal ataque? Obviamente, quieren que los usuarios legítimos sigan usando el sitio web al mismo tiempo que se protejan a sí mismos para que los usuarios legítimos que hayan iniciado sesión no sean cooptados para atacar el sitio web.

Entonces, ¿cuáles son las pruebas básicas que podemos ejecutar para ver si estamos construyendo un sitio web inseguro?
No hay una respuesta simple para esto. Hay miles de marcos, decenas de idiomas, cientos de formas diferentes de alojarlos. Pero lo que podemos hacer es ver una forma abstracta de ser seguro y, en ausencia de tales medidas de seguridad, saber que un sitio web en particular es inseguro o no.

1. ¿La entrada del usuario pasa por alguna rutina de validación antes de ser enviada al navegador web del usuario?
* Si no es así, es muy posible que pueda haber un problema de Cross Site Scripting (XSS).
* Hay muchos lugares diferentes donde los datos del usuario pueden terminar. Uno de los más difíciles de proteger es cuando JavaScript utiliza directamente los datos del usuario en el sitio web.
* Como mínimo, su rutina de validación debe verificar todos los caracteres que tienen un significado especial en HTML, como & lt ;, & gt ;, & quot; etc.

2. ¿La entrada del usuario pasa por alguna rutina de validación antes de pasar a otro intérprete como SQL o pasar a los sistemas operativos subyacentes para ejecutar comandos?
* Diferentes intérpretes tienen diferentes delimitadores. SQL tiene comillas simples y dobles que delimitan el comando y los datos. Idealmente, no use la entrada del usuario directamente en las consultas SQL y siempre verifíquelas por tipo y longitud.
* La inyección de comandos puede ser extremadamente mortal ya que puede permitir que un usuario ejecute comandos como el mismo nivel de privilegio del sitio web.

3. Agregar un valor de token suficientemente aleatorio que cambia en cada sesión como parte del cuerpo HTML al enviar formularios puede ser una medida para verificar si un usuario válido envió el formulario o fue cooptado por un atacante.
* Los navegadores web no permiten que dos pestañas diferentes lean los datos de otra pestaña. Por lo tanto, un atacante no tiene forma de robar esta ficha en particular, a menos que.
* Hay un problema de XSS en el sitio web, entonces el atacante puede robar el token adicional.

Conclusión
Si has llegado hasta aquí, te das cuenta de que hemos mencionado OWASP Top 10, varias veces. Eso implica que hay más de 3 debilidades diferentes que un sitio web puede enfrentar. Pero estos tres Cross Site Scripting, SQL Injection y Cross Site Request Forgery son los que se dispararán mucho más que otros. Esto no quiere decir que los otros no sean tan peligrosos, si no más.

¿Por qué SSL no te protege?
Todo lo anterior tiene lugar en la capa de aplicación y el cifrado proporcionado por SSL / TLS realmente no se aplica hasta la capa de abajo. Por lo tanto, realmente no importa, ya que los datos de ataque también pueden ser parte de los datos cifrados.