Cómo funcionan los navegadores

Introducción a la seguridad de las aplicaciones web

Abramos esta serie sobre seguridad de aplicaciones web con una explicación de lo que hacen los navegadores y cómo lo hacen. Dado que la mayoría de sus clientes interactuarán con su aplicación web a través de un navegador, es imperativo comprender los conceptos básicos de estos maravillosos programas.

El navegador es un motor de renderizado . Su trabajo es descargar una página web y representarla de una manera que sea comprensible para un ser humano.

Aunque se trata de una simplificación excesiva casi criminal, es todo lo que necesitamos saber por ahora.

  • El usuario ingresa una dirección en la barra del navegador.
  • El navegador descarga el "documento" en esa URL y lo procesa.

Puede que esté acostumbrado a trabajar con uno de los navegadores más populares, como Chrome, Firefox, Edge o Safari, pero eso no significa que no existan navegadores diferentes.

lynx, por ejemplo, es un navegador ligero basado en texto que funciona desde la línea de comandos. En el corazón de lynx se encuentran exactamente los mismos principios que encontraría en cualquier otro navegador "convencional". Un usuario ingresa una dirección web (URL), el navegador busca el documento y lo procesa; la única diferencia es el hecho de que lynx no usa un motor de representación visual sino una interfaz basada en texto, lo que hace que los sitios web como Google se vean así. :

Entendemos ampliamente lo que hace un navegador, pero echemos un vistazo más de cerca a los pasos que estas ingeniosas aplicaciones hacen por nosotros.

¿Qué hace un navegador?

En pocas palabras, el trabajo de un navegador consiste principalmente en:

  • Resolución de DNS
  • Intercambio HTTP
  • Representación
  • Enjuague y repita

Resolución de DNS

Este proceso asegura que una vez que el usuario ingresa una URL, el navegador sabe a qué servidor tiene que conectarse. El navegador se pone en contacto con un servidor DNS para encontrar que se google.comtraduce en 216.58.207.110una dirección IP a la que el navegador puede conectarse.

Intercambio HTTP

Una vez que el navegador ha identificado qué servidor va a atender nuestra solicitud, iniciará una conexión TCP con él y comenzará el intercambio HTTP . Esto no es más que una forma para que el navegador se comunique con el servidor lo que necesita y para que el servidor responda.

HTTP es simplemente el nombre del protocolo más popular para comunicarse en la web, y los navegadores hablan principalmente a través de HTTP cuando se comunican con los servidores. Un intercambio HTTP implica que el cliente (nuestro navegador) envía una solicitud y el servidor responde con una respuesta .

Por ejemplo, después de que el navegador se haya conectado con éxito al servidor detrás google.com, enviará una solicitud similar a la siguiente:

GET / HTTP/1.1Host: google.comAccept: */*

Analicemos la solicitud, línea por línea:

  • GET / HTTP/1.1: con esta primera línea, el navegador pide al servidor que recupere el documento en la ubicación /, agregando que el resto de la solicitud seguirá el protocolo HTTP / 1.1 (también podría usar 1.0o 2)
  • Host: google.com: este es el único encabezado HTTP obligatorio en HTTP / 1.1 . Dado que el servidor puede servir a múltiples dominios ( google.com, google.co.uk, etc.) el cliente que aquí se menciona que la solicitud era para ese host específico
  • Accept: */*: un encabezado opcional, donde el navegador le dice al servidor que aceptará cualquier tipo de respuesta. El servidor podría tener un recurso que esté disponible en formatos JSON, XML o HTML, por lo que puede elegir el formato que prefiera.

Una vez que el navegador, que actúa como cliente , ha terminado con su solicitud, es el turno del servidor de responder. Así es como se ve una respuesta:

HTTP/1.1 200 OKCache-Control: private, max-age=0Content-Type: text/html; charset=ISO-8859-1Server: gwsX-XSS-Protection: 1; mode=blockX-Frame-Options: SAMEORIGINSet-Cookie: NID=1234; expires=Fri, 18-Jan-2019 18:25:04 GMT; path=/; domain=.google.com; HttpOnly
......

Vaya, es mucha información para digerir. El servidor nos permite saber que la solicitud fue exitosa ( 200 OK) y agrega algunos encabezados a la respuesta , por ejemplo, anuncia qué servidor procesó nuestra solicitud ( Server: gws), cuál es la X-XSS-Protectionpolítica de esta respuesta, etc.

En este momento, no es necesario que comprenda todas y cada una de las líneas de la respuesta. Cubriremos el protocolo HTTP, sus encabezados, etc., más adelante en esta serie.

Por ahora, todo lo que necesita saber es que el cliente y el servidor están intercambiando información y que lo hacen a través de HTTP.

Representación

Por último, pero no menos importante, el proceso de renderizado . ¿Qué tan bueno sería un navegador si lo único que mostrara al usuario fuera una lista de personajes divertidos?

......

En el cuerpo de la respuesta, el servidor incluye la representación de la respuesta según el Content-Typeencabezado. En nuestro caso, el tipo de contenido se estableció en text/html, por lo que esperamos un marcado HTML en la respuesta, que es exactamente lo que encontramos en el cuerpo.

Aquí es donde realmente brilla un navegador. Analiza el HTML, carga los recursos adicionales incluidos en el marcado (por ejemplo, podría haber archivos JavaScript o documentos CSS para recuperar) y los presenta al usuario lo antes posible.

Una vez más, el resultado final es algo que el ciudadano medio puede entender.

Para obtener una versión más detallada de lo que realmente sucede cuando presionamos enter en la barra de direcciones de un navegador, sugeriría leer "¿Qué sucede cuando ...", un intento muy elaborado de explicar la mecánica detrás del proceso.

Dado que esta es una serie centrada en la seguridad, voy a dejar una pista sobre lo que acabamos de aprender: los atacantes se ganan la vida fácilmente con las vulnerabilidades en la parte de intercambio y representación HTTP . Las vulnerabilidades y los usuarios malintencionados también acechan en otros lugares, pero un mejor enfoque de seguridad en esos niveles ya le permite avanzar en la mejora de su postura de seguridad.

Vendedores

Los 4 navegadores más populares que existen pertenecen a diferentes proveedores:

  • Chrome de Google
  • Firefox de Mozilla
  • Safari de Apple
  • Edge de Microsoft

Además de luchar entre sí para aumentar su penetración en el mercado, los proveedores también se relacionan entre sí para mejorar los estándares web , que son una especie de "requisitos mínimos" para los navegadores.

El W3C es el organismo detrás del desarrollo de los estándares, pero no es inusual que los navegadores desarrollen sus propias características que eventualmente se conviertan en estándares web, y la seguridad no es una excepción a eso.

Chrome 51, por ejemplo, introdujo las cookies SameSite, una función que permitiría a las aplicaciones web eliminar un tipo particular de vulnerabilidad conocida como CSRF (más sobre esto más adelante). Otros proveedores decidieron que era una buena idea y siguieron su ejemplo, lo que llevó a SameSite a ser un estándar web: a partir de ahora, Safari es el único navegador importante sin compatibilidad con las cookies de SameSite.

Esto nos dice 2 cosas:

  • Safari no parece preocuparse lo suficiente por la seguridad de sus usuarios (es broma: las cookies de SameSite estarán disponibles en Safari 12, que es posible que ya se hayan lanzado cuando lea este artículo)
  • parchear una vulnerabilidad en un navegador no significa que todos sus usuarios estén seguros

El primer punto es una oportunidad para Safari (como mencioné, ¡es broma!), Mientras que el segundo punto es realmente importante. Al desarrollar aplicaciones web, no solo debemos asegurarnos de que tengan el mismo aspecto en varios navegadores, sino también de que garanticen que nuestros usuarios estén protegidos de la misma manera en todas las plataformas.

Su estrategia hacia la seguridad web debe variar según lo que el proveedor de un navegador nos permita hacer . Hoy en día, la mayoría de los navegadores admiten el mismo conjunto de características y rara vez se desvían de su hoja de ruta común, pero casos como el anterior todavía ocurren, y es algo que debemos tener en cuenta al definir nuestra estrategia de seguridad.

En nuestro caso, si decidimos que vamos a mitigar los ataques CSRF solo a través de las cookies de SameSite, debemos ser conscientes de que estamos poniendo en riesgo a nuestros usuarios de Safari. Y nuestros usuarios también deberían saberlo.

Por último, pero no menos importante, debe recordar que puede decidir si admite una versión del navegador o no: admitir todas y cada una de las versiones del navegador no sería práctico (piense en Internet Explorer 6). Sin embargo, asegurarse de que las últimas versiones de los principales navegadores sean compatibles es, en general, una buena decisión. Sin embargo, si no planea ofrecer protección en una plataforma en particular, generalmente es recomendable que se lo informe a sus usuarios.

Consejo profesional : nunca debe alentar a sus usuarios a que utilicen navegadores obsoletos ni a apoyarlos activamente. Aunque es posible que haya tomado todas las precauciones necesarias, es posible que otros desarrolladores web no lo hayan hecho. Anime a los usuarios a utilizar la última versión compatible de uno de los principales navegadores.

¿Proveedor o error estándar?

El hecho de que el usuario medio acceda a nuestra aplicación a través de un cliente de terceros (el navegador) añade otro nivel de direccionamiento indirecto hacia una experiencia de navegación clara y segura: el propio navegador puede presentar una vulnerabilidad de seguridad.

Los proveedores generalmente brindan recompensas (también conocidas como recompensas por errores ) a los investigadores de seguridad que pueden encontrar una vulnerabilidad en el navegador. Estos errores no están vinculados a su implementación, sino a cómo el navegador maneja la seguridad por sí solo.

The Chrome reward program, for example, lets security engineers reach out to the Chrome security team to report vulnerabilities they have found. If these vulnerabilities are confirmed, a patch is issued, a security advisory notice is generally released to the public, and the researcher receives a (usually financial) reward from the program.

Companies like Google invest a relatively good amount of capital into their Bug Bounty programs, as it allows them to attract researchers by promising a financial benefit should they find any problem with the application.

In a Bug Bounty program, everyone wins: the vendor manages to improve the security of its software, and researchers get paid for their findings. We will discuss these programs later on, as I believe Bug Bounty initiatives deserve their own section in the security landscape.

Jake Archibald is a developer advocate at Google who recently discovered a vulnerability impacting more than one browser. He documented his efforts, how he approached different vendors, and their reactions in an interesting blog post that I’d recommend you read.

A browser for developers

By now, we should have understood a very simple but rather important concept: browsers are simply HTTP clients built for the average internet surfer.

They are definitely more powerful than a platform’s bare HTTP client (think of NodeJS’s require('http'), for example), but at the end of the day, they’re “just” a natural evolution of simpler HTTP clients.

As developers, our HTTP client of choice is probably cURL by Daniel Stenberg, one of the most popular software programs web developers use on a daily basis. It allows us to do an HTTP exchange on-the-fly, by sending an HTTP request from our command line:

$ curl -I localhost:8080
HTTP/1.1 200 OKserver: ecstatic-2.2.1Content-Type: text/htmletag: "23724049-4096-"2018-07-20T11:20:35.526Z""last-modified: Fri, 20 Jul 2018 11:20:35 GMTcache-control: max-age=3600Date: Fri, 20 Jul 2018 11:21:02 GMTConnection: keep-alive

In the example above, we have requested the document at localhost:8080/, and a local server replied successfully.

Rather than dumping the response’s body to the command line, here we’ve used the -I flag which tells cURL we’re only interested in the response headers. Taking it one step forward, we can instruct cURL to dump a little more information, including the actual request it performs, so that we can have a better look at this whole HTTP exchange. The option we need to use is -v (verbose):

$ curl -I -v localhost:8080* Rebuilt URL to: localhost:8080/* Trying 127.0.0.1...* Connected to localhost (127.0.0.1) port 8080 (#0)> HEAD / HTTP/1.1> Host: localhost:8080> User-Agent: curl/7.47.0> Accept: */*>< HTTP/1.1 200 OKHTTP/1.1 200 OK< server: ecstatic-2.2.1server: ecstatic-2.2.1< Content-Type: text/htmlContent-Type: text/html< etag: "23724049-4096-"2018-07-20T11:20:35.526Z""etag: "23724049-4096-"2018-07-20T11:20:35.526Z""< last-modified: Fri, 20 Jul 2018 11:20:35 GMTlast-modified: Fri, 20 Jul 2018 11:20:35 GMT< cache-control: max-age=3600cache-control: max-age=3600< Date: Fri, 20 Jul 2018 11:25:55 GMTDate: Fri, 20 Jul 2018 11:25:55 GMT< Connection: keep-aliveConnection: keep-alive
<* Connection #0 to host localhost left intact

Just about the same information is available in mainstream browsers through their DevTools.

As we’ve seen, browsers are nothing more than elaborate HTTP clients. Sure, they add an enormous amount of features (think of credential management, bookmarking, history, etc) but the truth is that they were born as HTTP clients for humans. This is important, as in most cases you don’t need a browser to test your web application’s security, as you can simply “curl it” and have a look at the response.

One final thing that I’d like to point out, is that anything can be a browser. If you have a mobile application that consumes APIs through the HTTP protocol, then the app is your browser — it just happens to be a highly customized one you built yourself, one that only understands a specific type of HTTP responses (from your own API).

Into the HTTP protocol

As we mentioned, the HTTP exchange and rendering phases are the ones that we’re mostly going to cover, as they provide the largest number of attack vectors for malicious users.

In the next article, we’re going to take a deeper look at the HTTP protocol and try to understand what measures we should take in order to secure HTTP exchanges.

Originally published at odino.org (29 July 2018).

You can follow me on Twitter - rants are welcome! ?