Las 10 vulnerabilidades de seguridad web más comunes

Publicado: 2022-03-11

Para demasiadas empresas, las mejores prácticas de seguridad web no se convierten en una prioridad hasta que se produce una violación de la seguridad. Durante mis años trabajando como profesional de seguridad de TI, he visto una y otra vez cuán oscuro puede ser el mundo de los problemas de seguridad del desarrollo web para muchos de mis compañeros programadores.

Un enfoque eficaz de las amenazas a la seguridad web debe, por definición, ser proactivo y defensivo. Con ese fin, esta publicación tiene como objetivo despertar una mentalidad de seguridad, con la esperanza de inyectar al lector una buena dosis de paranoia.

En particular, esta guía se enfoca en 10 errores de seguridad web comunes e importantes que debe tener en cuenta, incluidas recomendaciones sobre cómo pueden mitigarse. La atención se centra en las 10 principales vulnerabilidades web identificadas por Open Web Application Security Project (OWASP), una organización internacional sin fines de lucro cuyo objetivo es mejorar la seguridad del software en todo el mundo.

Un ejemplo de algunas vulnerabilidades web comunes que nadie quiere enfrentar.

Un pequeño manual de seguridad cibernética antes de comenzar: autenticación y autorización

Cuando hablo con otros programadores y profesionales de TI, a menudo encuentro confusión con respecto a la distinción entre autorización y autenticación. Y, por supuesto, el hecho de que la abreviatura auth se use a menudo para ambos ayuda a agravar esta confusión común. Esta confusión es tan común que tal vez este problema debería incluirse en esta publicación como "Common Web Vulnerability Zero".

Entonces, antes de continuar, aclaremos la distinción entre estos dos términos:

  • Autenticación: verificar que una persona es (o al menos aparenta ser) un usuario específico, ya que ha proporcionado correctamente sus credenciales de seguridad (contraseña, respuestas a preguntas de seguridad, escaneo de huellas digitales, etc.).
  • Autorización: Confirmación de que un usuario en particular tiene acceso a un recurso específico o se le otorga permiso para realizar una acción en particular.

Dicho de otra manera, la autenticación es saber quién es una entidad, mientras que la autorización es saber qué puede hacer una determinada entidad. Con esto en mente, entremos en los 10 principales problemas de seguridad en Internet.

Error común de seguridad web n.° 1: fallas de inyección

Las fallas de inyección son el resultado de una falla clásica para filtrar la entrada que no es de confianza. Puede suceder cuando pasa datos sin filtrar al servidor SQL (inyección SQL), al navegador (XSS; hablaremos de esto más adelante), al servidor LDAP (inyección LDAP) o en cualquier otro lugar. El problema aquí es que el atacante puede inyectar comandos a estas entidades, lo que provoca la pérdida de datos y el secuestro de los navegadores de los clientes.

Cualquier cosa que su aplicación reciba de fuentes no confiables debe filtrarse, preferiblemente de acuerdo con una lista blanca. Casi nunca debe usar una lista negra, ya que hacerlo bien es muy difícil y, por lo general, fácil de eludir. Los productos de software antivirus suelen proporcionar ejemplos estelares de listas negras fallidas. La coincidencia de patrones no funciona.

Prevención: la buena noticia es que protegerse contra la inyección es "simplemente" una cuestión de filtrar su entrada correctamente y pensar si se puede confiar en una entrada. Pero la mala noticia es que todas las entradas deben filtrarse adecuadamente, a menos que sea incuestionablemente confiable (pero el dicho "nunca digas nunca" me viene a la mente aquí).

En un sistema con 1000 entradas, por ejemplo, filtrar con éxito 999 de ellas no es suficiente, ya que esto aún deja un campo que puede servir como cura de Aquiles para derribar su sistema. Y podría pensar que poner el resultado de una consulta SQL en otra consulta es una buena idea, ya que la base de datos es confiable, pero si el perímetro no lo es, la entrada proviene indirectamente de personas con malas intenciones. Esto se llama inyección SQL de segundo orden en caso de que esté interesado.

Dado que el filtrado es bastante difícil de hacer bien (como la criptografía), lo que generalmente aconsejo es confiar en las funciones de filtrado de su marco: se ha demostrado que funcionan y se analizan minuciosamente. Si no usa marcos, realmente debe pensar detenidamente si no usarlos realmente tiene sentido en el contexto de seguridad de su servidor. El 99% de las veces no lo hace.

Error común de seguridad web n.º 2: autenticación rota

Esta es una colección de múltiples problemas que pueden ocurrir durante la autenticación rota, pero no todos provienen de la misma causa raíz.

Suponiendo que alguien todavía quiera lanzar su propio código de autenticación en 2014 (¿qué estás pensando?), desaconsejo hacerlo. Es extremadamente difícil hacerlo bien, y hay una gran cantidad de posibles escollos, solo por mencionar algunos:

  1. La URL puede contener la identificación de la sesión y filtrarla en el encabezado de referencia a otra persona.
  2. Es posible que las contraseñas no estén cifradas ni en el almacenamiento ni en el tránsito.
  3. Los identificadores de sesión pueden ser predecibles, por lo que obtener acceso es trivial.
  4. La fijación de la sesión podría ser posible.
  5. El secuestro de sesiones puede ser posible, los tiempos de espera no se implementan correctamente o se usa HTTP (sin seguridad SSL), etc.

Prevención: la forma más sencilla de evitar esta vulnerabilidad de seguridad web es utilizar un marco. Es posible que pueda implementar esto correctamente, pero el primero es mucho más fácil. En caso de que quiera implementar su propio código, sea extremadamente paranoico e infórmese sobre cuáles son las trampas. Hay unos cuantos.

Error común de seguridad web n.º 3: Cross Site Scripting (XSS)

Esta es una falla de saneamiento de entrada bastante extendida (esencialmente un caso especial del error común #1). Un atacante le da a su aplicación web etiquetas JavaScript en la entrada. Cuando esta entrada se devuelve al usuario sin desinfectar, el navegador del usuario la ejecutará. Puede ser tan simple como crear un enlace y persuadir a un usuario para que haga clic en él, o puede ser algo mucho más siniestro. En la carga de la página, el script se ejecuta y, por ejemplo, puede usarse para enviar sus cookies al atacante.

Prevención: existe una solución de seguridad web simple: no devolver etiquetas HTML al cliente. Esto tiene el beneficio adicional de defenderse contra la inyección de HTML, un ataque similar en el que el atacante inyecta contenido HTML simple (como imágenes o reproductores flash invisibles ruidosos), no de alto impacto pero seguramente molesto ("¡Por favor, haz que se detenga!"). Por lo general, la solución es simplemente convertir todas las entidades HTML, de modo que <script> se devuelva como &lt;script&gt; . El otro método de desinfección que se emplea a menudo es el uso de expresiones regulares para quitar las etiquetas HTML usando expresiones regulares en < y > , pero esto es peligroso ya que muchos navegadores interpretarán correctamente HTML severamente roto. Es mejor convertir todos los personajes a sus contrapartes escapadas.

Relacionado: 9 preguntas esenciales de la entrevista de seguridad del sistema

Error común de seguridad web n.º 4: referencias directas a objetos inseguras

Este es un caso clásico de confiar en la entrada del usuario y pagar el precio de una vulnerabilidad de seguridad resultante. Una referencia de objeto directo significa que un objeto interno, como un archivo o una clave de base de datos, está expuesto al usuario. El problema con esto es que el atacante puede proporcionar esta referencia y, si la autorización no se aplica (o se interrumpe), el atacante puede acceder o hacer cosas de las que debería estar excluido.

Por ejemplo, el código tiene un módulo download.php que lee y permite que el usuario descargue archivos, utilizando un parámetro CGI para especificar el nombre del archivo (por ejemplo, download.php?file=something.txt ). Ya sea por error o por pereza, el desarrollador omitió la autorización del código. El atacante ahora puede usar esto para descargar cualquier archivo del sistema al que tenga acceso el usuario que ejecuta PHP, como el código de la aplicación u otros datos que quedan en el servidor, como las copias de seguridad. UH oh.

Otro ejemplo común de vulnerabilidad es una función de restablecimiento de contraseña que se basa en la entrada del usuario para determinar de quién es la contraseña que estamos restableciendo. Después de hacer clic en la URL válida, un atacante puede simplemente modificar el campo de nombre de username en la URL para decir algo como "administrador".

Por cierto, ambos ejemplos son cosas que yo mismo he visto aparecer a menudo "en la naturaleza".

Prevención: Realice la autorización del usuario de manera adecuada y consistente, e incluya las opciones en la lista blanca. Sin embargo, la mayoría de las veces, todo el problema se puede evitar almacenando datos internamente y no confiando en que el cliente los pase a través de parámetros CGI. Las variables de sesión en la mayoría de los marcos son adecuadas para este propósito.

Error común de seguridad web n.º 5: configuración incorrecta de la seguridad

En mi experiencia, los servidores web y las aplicaciones que se han configurado mal son mucho más comunes que los que se han configurado correctamente. Quizá esto se deba a que no faltan formas de meter la pata. Algunos ejemplos:

  1. Ejecutar la aplicación con la depuración habilitada en producción.
  2. Tener la lista de directorios habilitada en el servidor, lo que filtra información valiosa.
  3. Ejecutar software obsoleto (piense en los complementos de WordPress, PhpMyAdmin antiguo).
  4. Tener servicios innecesarios ejecutándose en la máquina.
  5. No cambiar las claves y contraseñas predeterminadas. (¡Ocurre con mucha más frecuencia de lo que crees!)
  6. Revelar información de manejo de errores a los atacantes, como seguimientos de pila.

Prevención: tenga un buen proceso de "construcción e implementación" (preferiblemente automatizado), que pueda ejecutar pruebas en la implementación. La solución de configuración incorrecta de seguridad del hombre pobre son los ganchos posteriores a la confirmación, para evitar que el código se apague con contraseñas predeterminadas y/o elementos de desarrollo integrados.

Error común de seguridad web n.º 6: exposición de datos confidenciales

Esta vulnerabilidad de seguridad web tiene que ver con la criptografía y la protección de recursos. Los datos confidenciales deben cifrarse en todo momento, incluso en tránsito y en reposo. Sin excepciones. La información de la tarjeta de crédito y las contraseñas de los usuarios nunca deben viajar ni almacenarse sin cifrar, y las contraseñas siempre deben cifrarse. Obviamente, el algoritmo criptográfico/hashing no debe ser débil; en caso de duda, los estándares de seguridad web recomiendan AES (256 bits y más) y RSA (2048 bits y más).

Y aunque no hace falta decir que los ID de sesión y los datos confidenciales no deben viajar en las URL y las cookies confidenciales deben tener el indicador de seguridad activado, esto es muy importante y no se puede enfatizar demasiado.

Prevención:

  • En tránsito: use HTTPS con un certificado adecuado y PFS (Perfect Forward Secrecy). No acepte nada sobre conexiones que no sean HTTPS. Tenga la bandera segura en las cookies.

  • En almacenamiento: Esto es más difícil. En primer lugar, debe reducir su exposición. Si no necesita datos confidenciales, tritúrelos. Los datos que no tienes no pueden ser robados. Nunca almacene información de tarjetas de crédito, ya que probablemente no quiera tener que lidiar con el cumplimiento de PCI. Regístrese con un procesador de pagos como Stripe o Braintree. En segundo lugar, si tiene datos confidenciales que realmente necesita, guárdelos encriptados y asegúrese de que todas las contraseñas estén cifradas. Para hashing, se recomienda el uso de bcrypt. Si no usa bcrypt, infórmese sobre las tablas de salazón y arcoíris.

Y a riesgo de decir lo obvio, no almacene las claves de cifrado junto a los datos protegidos . Eso es como guardar tu bicicleta con un candado que tiene la llave adentro. Proteja sus copias de seguridad con encriptación y mantenga sus claves muy privadas. Y por supuesto, ¡no pierdas las llaves!

Error común de seguridad web n.º 7: Control de acceso de nivel de función faltante

Esto es simplemente una falla de autorización. Significa que cuando se llama a una función en el servidor, no se realizó la autorización adecuada. Muchas veces, los desarrolladores confían en el hecho de que el lado del servidor generó la interfaz de usuario y piensan que el cliente no puede acceder a la funcionalidad que no proporciona el servidor. No es tan simple como eso, ya que un atacante siempre puede falsificar solicitudes a la funcionalidad "oculta" y no se detendrá por el hecho de que la interfaz de usuario no hace que esta funcionalidad sea fácilmente accesible. Imagine que hay un panel /admin y el botón solo está presente en la interfaz de usuario si el usuario es realmente un administrador. Nada evita que un atacante descubra esta funcionalidad y la use indebidamente si falta la autorización.

Prevención: Del lado del servidor, siempre se debe hacer la autorización. Sí, siempre. Ninguna excepción o vulnerabilidad dará lugar a problemas graves.

Error común de seguridad web n.° 8: Falsificación de solicitud entre sitios (CSRF)

Este es un buen ejemplo de un ataque adjunto confuso en el que el navegador es engañado por otra parte para que haga un mal uso de su autoridad. Un sitio de terceros, por ejemplo, puede hacer que el navegador del usuario haga un mal uso de su autoridad para hacer algo por el atacante.

En el caso de CSRF, un sitio de terceros emite solicitudes al sitio de destino (por ejemplo, su banco) utilizando su navegador con sus cookies/sesión. Si ha iniciado sesión en una pestaña de la página de inicio de su banco, por ejemplo, y es vulnerable a este ataque, otra pestaña puede hacer que su navegador haga un uso indebido de sus credenciales en nombre del atacante, lo que genera el problema del diputado confuso. El adjunto es el navegador que hace mal uso de su autoridad (cookies de sesión) para hacer algo que el atacante le indica que haga.

Considere este ejemplo:

El atacante Alice quiere aligerar la billetera de Todd al transferirle parte de su dinero. El banco de Todd es vulnerable a CSRF. Para enviar dinero, Todd tiene que acceder a la siguiente URL:

http://example.com/app/transferFunds?amount=1500&destinationAccount=4673243243

Después de abrir esta URL, se presenta una página de éxito a Todd y se realiza la transferencia. Alice también sabe que Todd visita con frecuencia un sitio bajo su control en blog.aliceisawesome.com, donde coloca el siguiente fragmento:

<img src=http://example.com/app/transferFunds?amount=1500&destinationAccount=4673243243 width=0 height=0 />

Al visitar el sitio web de Alice, el navegador de Todd cree que Alice se vincula a una imagen y automáticamente emite una solicitud HTTP GET para obtener la imagen, pero esto en realidad le indica al banco de Todd que transfiera $ 1500 a Alice.

Por cierto, además de demostrar la vulnerabilidad CSRF, este ejemplo también demuestra la alteración del estado del servidor con una solicitud HTTP GET idempotente que en sí misma es una vulnerabilidad grave. Las solicitudes HTTP GET deben ser idempotentes (seguras), lo que significa que no pueden alterar el recurso al que se accede. Nunca, nunca, utilice métodos idempotentes para cambiar el estado del servidor.

Dato curioso: CSRF también es el método que la gente usaba para rellenar las cookies en el pasado hasta que los afiliados se volvieron más sabios.

Prevención: almacene un token secreto en un campo de formulario oculto al que no se puede acceder desde el sitio de terceros. Por supuesto, siempre tiene que verificar este campo oculto. Algunos sitios también solicitan su contraseña al modificar configuraciones confidenciales (como su correo electrónico de recordatorio de contraseña, por ejemplo), aunque sospecho que esto está ahí para evitar el mal uso de sus sesiones abandonadas (en un cibercafé, por ejemplo).

Error común de seguridad web n.º 9: usar componentes con vulnerabilidades conocidas

El título lo dice todo. Volvería a clasificar esto como un problema de mantenimiento/implementación. Antes de incorporar código nuevo, investigue un poco, posiblemente audite un poco. El uso de un código que obtuvo de una persona al azar en GitHub o en algún foro puede ser muy conveniente, pero no está exento de riesgo de una grave vulnerabilidad de seguridad web.

He visto muchos casos, por ejemplo, en los que los sitios son propiedad (es decir, cuando un extraño obtiene acceso administrativo a un sistema), no porque los programadores fueran estúpidos, sino porque un software de terceros permaneció sin parches durante años en producción. Esto sucede todo el tiempo con los complementos de WordPress, por ejemplo. Si cree que no encontrarán su instalación oculta de phpmyadmin , permítame presentarle dirbuster.

La lección aquí es que el desarrollo de software no termina cuando se implementa la aplicación. Tiene que haber documentación, pruebas y planes sobre cómo mantenerlo y mantenerlo actualizado, especialmente si contiene componentes de código abierto o de terceros.

Prevención:

  • Tenga cuidado. Más allá de tener precaución al usar tales componentes, no seas un codificador de copiar y pegar. Inspeccione detenidamente el fragmento de código que está a punto de incluir en su software, ya que podría estar roto sin posibilidad de reparación (o, en algunos casos, intencionalmente malicioso; a veces, los ataques a la seguridad web son involuntariamente invitados de esta manera).

  • Estar al día. Asegúrese de estar utilizando las últimas versiones de todo lo que confía y tenga un plan para actualizarlas periódicamente. Al menos suscríbase a un boletín de nuevas vulnerabilidades de seguridad con respecto al producto.

Error común de seguridad web n.º 10: redireccionamientos y reenvíos no validados

Esto es una vez más un problema de filtrado de entrada. Supongamos que el sitio de destino tiene un módulo redirect.php que toma una URL como parámetro GET . La manipulación del parámetro puede crear una URL en targetsite.com que redirige el navegador a malwareinstall.com . Cuando el usuario vea el enlace, verá targetsite.com/blahblahblah que el usuario cree que es confiable y seguro para hacer clic. Poco saben que esto realmente los transferirá a una página de descarga de malware (o cualquier otra página maliciosa). Alternativamente, el atacante podría redirigir el navegador a targetsite.com/deleteprofile?confirm=1 .

Vale la pena mencionar que introducir una entrada definida por el usuario sin desinfectar en un encabezado HTTP podría provocar una inyección de encabezado, lo cual es bastante malo.

Prevención: Las opciones incluyen:

  • No haga redireccionamientos en absoluto (rara vez son necesarios).
  • Tenga una lista estática de ubicaciones válidas a las que redirigir.
  • Incluya en la lista blanca el parámetro definido por el usuario, pero esto puede ser complicado.

Epílogo

Espero haber logrado estimular un poco su cerebro con esta publicación e introducir una buena dosis de paranoia y conciencia de la vulnerabilidad de la seguridad del sitio web.

La conclusión principal aquí es que las prácticas antiguas de software existen por una razón y lo que se aplicaba en el pasado para los desbordamientos de búfer, todavía se aplica a las cadenas encurtidas en Python hoy en día. Los protocolos de seguridad te ayudan a escribir (más) programas correctos, a los que todos los programadores deberían aspirar.

Utilice este conocimiento de manera responsable y no pruebe las páginas sin permiso.

Para obtener más información y ataques del lado del servidor más específicos, consulte: https://www.owasp.org/index.php/Category:Attack.

Los comentarios sobre esta publicación y sus consejos de mitigación son bienvenidos y apreciados. Se planean futuras publicaciones relacionadas, particularmente sobre el tema de la denegación de servicio distribuida (DDoS) y las vulnerabilidades de seguridad de TI de la vieja escuela (no web). Si tiene una solicitud específica sobre qué tipo de protección web escribir, no dude en ponerse en contacto conmigo directamente en [email protected].

¡Aquí está la seguridad del sitio web! Salud.

Relacionados:
  • Tutorial de JSON Web Token: un ejemplo en Laravel y AngularJS
  • Rendimiento y eficiencia: trabajar con HTTP/3