Una rápida introducción a la seguridad web

Un manual para desarrolladores web sobre CORS, CSP, HSTS y todas las siglas de seguridad web.

Hay muchas razones para aprender sobre seguridad web, como:

  • Eres un usuario preocupado al que le preocupa que se filtren sus datos personales
  • Eres un desarrollador web preocupado que quiere que sus aplicaciones web sean más seguras.
  • Eres un desarrollador web que solicita empleo y quieres estar preparado si tus entrevistadores te hacen preguntas sobre seguridad web.

y así.

Bueno, esta publicación explicará algunos acrónimos comunes de seguridad web de una manera fácil de entender pero precisa.

Antes de hacer eso, asegurémonos de comprender un par de conceptos básicos de seguridad.

Dos conceptos básicos de seguridad

Nadie está 100% seguro.

No existe la noción de estar 100% protegido de ser pirateado. Si alguien te dice eso, se equivoca.

Una capa de protección no es suficiente.

No puedes simplemente decir ...

Oh, porque he implementado CSP, estoy a salvo. Puedo tachar las secuencias de comandos entre sitios de mi lista de vulnerabilidades porque eso no puede suceder ahora.

Tal vez eso sea un hecho para algunos, pero es fácil encontrarse pensando de esta manera. Creo que una de las razones por las que los programadores pueden pensar fácilmente de esta manera es porque gran parte de la codificación es en blanco y negro, 0 o 1, verdadero o falso. La seguridad no es tan simple.

Comenzaremos con uno con el que todos se encuentran bastante temprano en su viaje de desarrollo web. Y luego miras StackOverflow y encuentras un montón de respuestas que te dicen cómo evitarlo.

Uso compartido de recursos de origen cruzado (CORS)

¿Alguna vez ha recibido un error que se parece a esto?

No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.

Ciertamente no estás solo. Y luego lo buscas en Google, y alguien te dice que obtengas esta extensión que hará que todos tus problemas desaparezcan.

Genial, ¿verdad?

CORS está ahí para protegerte, no para hacerte daño.

Para explicar cómo le ayuda CORS, primero hablemos de las cookies, específicamente las cookies de autenticación . Las cookies de autenticación se utilizan para decirle a un servidor que ha iniciado sesión y se envían automáticamente con cualquier solicitud que realice a ese servidor.

Supongamos que ha iniciado sesión en Facebook y utilizan cookies de autenticación. Haces clic en el bit.ly/r43nugique te redirige a superevilwebsite.rocks. ¡Un script dentro superevilwebsite.rocksrealiza una solicitud del lado del cliente a la facebook.comque envía su cookie de autenticación!

En un mundo sin CORS, podrían realizar cambios en su cuenta sin que usted lo supiera. Hasta que, por supuesto, publican bit.ly/r43nugien su línea de tiempo, y todos sus amigos hacen clic en él, y luego publican bit.ly/r43nugien todas las líneas de tiempo de sus amigos y luego el ciclo continúa en un esquema maligno de amplitud primero que conquista a todos los usuarios de Facebook. y el mundo es consumido por superevilwebsite.rocks. ?

Sin embargo, en un mundo CORS, Facebook solo permitiría solicitudes con un origen de facebook.compara editar datos en su servidor. En otras palabras, limitarían el intercambio de recursos entre orígenes. Entonces podrías preguntar ...

Bueno, ¿puede superevilwebsite.rocks simplemente cambiar el encabezado de origen en su solicitud, para que parezca que proviene de facebook.com?

Pueden intentarlo, pero no funcionará porque el navegador simplemente lo ignorará y usará el origen real.

Ok, pero ¿y si superevilwebsite.rocks hizo la solicitud del lado del servidor?

En este caso, podrían omitir CORS, pero no ganarán porque no podrán enviar su cookie de autenticación durante el viaje. El script debería ejecutarse en el lado del cliente para obtener acceso a las cookies del lado del cliente.

Política de seguridad de contenido (CSP)

Para comprender CSP, primero debemos hablar sobre una de las vulnerabilidades más comunes en la web: XSS, que significa cross-site scripting (yay, otro acrónimo).

XSS es cuando una persona malvada inyecta JavaScript en su código del lado del cliente. Tú puedes pensar…

Qué van a hacer? ¿Cambiar un color de rojo a azul?

Supongamos que alguien ha inyectado con éxito JavaScript en el código del lado del cliente de un sitio web que está visitando.

¿Qué podían hacer que fuera malicioso?

  • Podrían realizar solicitudes HTTP a otro sitio haciéndose pasar por usted.
  • Podrían agregar una etiqueta de anclaje que lo envíe a un sitio web que se ve idéntico al que está con algunas características maliciosas ligeramente diferentes.
  • Podrían agregar una etiqueta de secuencia de comandos con JavaScript en línea.
  • Podrían agregar una etiqueta de secuencia de comandos que obtenga un archivo JavaScript remoto en algún lugar.
  • Podrían agregar un iframe que cubra la página y parezca parte del sitio web que le solicita que ingrese su contraseña.

Las posibilidades son infinitas.

CSP intenta evitar que esto suceda limitando:

  • qué se puede abrir en un iframe
  • qué hojas de estilo se pueden cargar
  • donde se pueden realizar solicitudes, etc.

¿Entonces, cómo funciona?

Cuando hace clic en un enlace o escribe la URL de un sitio web en la barra de direcciones de su navegador, su navegador realiza una solicitud GET. Eventualmente llega a un servidor que sirve HTML junto con algunos encabezados HTTP. Si tiene curiosidad acerca de los encabezados que recibe, abra la pestaña Red en su consola y visite algunos sitios web.

Es posible que vea un encabezado de respuesta similar a este:

content-security-policy: default-src * data: blob:;script-src *.facebook.com *.fbcdn.net *.facebook.net *.google-analytics.com *.virtualearth.net *.google.com 127.0.0.1:* *.spotilocal.com:* 'unsafe-inline' 'unsafe-eval' *.atlassolutions.com blob: data: 'self';style-src data: blob: 'unsafe-inline' *;connect-src *.facebook.com facebook.com *.fbcdn.net *.facebook.net *.spotilocal.com:* wss://*.facebook.com:* //fb.scanandcleanlocal.com:* *.atlassolutions.com attachment.fbsbx.com ws://localhost:* blob: *.cdninstagram.com 'self' chrome-extension://boadgeojelhgndaghljhdicfkmllpafd chrome-extension://dliochdbjfkdbacpmhlcpmleaejidimm;

Esa es la política de seguridad de contenido de facebook.com. Vamos a formatearlo para que sea más fácil de leer:

content-security-policy: default-src * data: blob:; script-src *.facebook.com *.fbcdn.net *.facebook.net *.google-analytics.com *.virtualearth.net *.google.com 127.0.0.1:* *.spotilocal.com:* 'unsafe-inline' 'unsafe-eval' *.atlassolutions.com blob: data: 'self'; style-src data: blob: 'unsafe-inline' *; connect-src *.facebook.com facebook.com *.fbcdn.net *.facebook.net *.spotilocal.com:* wss://*.facebook.com:* //fb.scanandcleanlocal.com:* *.atlassolutions.com attachment.fbsbx.com ws://localhost:* blob: *.cdninstagram.com 'self' chrome-extension://boadgeojelhgndaghljhdicfkmllpafd chrome-extension://dliochdbjfkdbacpmhlcpmleaejidimm;

Ahora, analicemos las directivas.

  • default-src restringe todas las demás directivas de CSP que no se enumeran explícitamente.
  • script-srcrestringe los scripts que se pueden cargar.
  • style-src restringe las hojas de estilo que se pueden cargar.
  • connect-src restringe las URL que se pueden cargar mediante interfaces de script, por lo que fetch, XHR, ajax, etc.

Tenga en cuenta que hay muchas más directivas CSP además de las cuatro que se muestran arriba. El navegador leerá el encabezado del CSP y aplicará esas directivas a todo el contenido del archivo HTML que se sirvió. Si las directivas se establecen adecuadamente, solo permiten lo necesario.

Si no hay un encabezado CSP, entonces todo funciona y nada está restringido. Dondequiera que veas *, eso es un comodín. Puedes imaginar reemplazarlo *con cualquier cosa y estará permitido.

HTTPS o HTTP seguro

Ciertamente has oído hablar de HTTPS. Tal vez hayas escuchado a algunas personas decir ...

¿Por qué me importa usar HTTPS si solo estoy en un sitio web jugando un juego?

O tal vez hayas escuchado el otro lado ...

Estás loco si tu sitio no tiene HTTPS. ¡Es 2018! No confíe en nadie que diga lo contrario.

Tal vez hayas escuchado que Chrome ahora marcará tu sitio como inseguro si no es HTTPS.

En esencia, HTTPS es bastante sencillo. HTTPS está cifrado y HTTP no.

Entonces, ¿por qué importa esto si no envía datos confidenciales?

Prepárese para otro acrónimo… MITM, que significa Man in the Middle.

Si está utilizando Wi-Fi público sin contraseña en una cafetería, es bastante fácil que alguien actúe como su enrutador, de modo que todas las solicitudes y respuestas pasen por ellos. Si sus datos no están cifrados, pueden hacer lo que quieran con ellos. Pueden editar HTML, CSS o JavaScript incluso antes de que llegue a su navegador. Dado lo que sabemos sobre XSS, puede imaginar lo malo que podría ser esto.

Bien, pero ¿cómo es que mi computadora y el servidor saben cómo cifrar / descifrar pero este MITM no?

Ahí es donde entran SSL (Secure Sockets Layer) y, más recientemente, TLS (Transport Layer Security). TLS se hizo cargo de SSL en 1999 como la tecnología de cifrado utilizada dentro de HTTPS. Exactamente cómo funciona TLS está fuera del alcance de esta publicación.

Seguridad de transporte estricta HTTP (HSTS)

Este es bastante sencillo. Usemos el encabezado de Facebook como ejemplo nuevamente:

strict-transport-security: max-age=15552000; preload
  • max-age especifica cuánto tiempo debe recordar un navegador para obligar al usuario a acceder a un sitio web mediante HTTPS.
  • preloadno es importante para nuestros propósitos. Es un servicio alojado por Google y no forma parte de la especificación HSTS.

Este encabezado solo se aplica si accedió al sitio mediante HTTPS. Si accedió al sitio a través de HTTP, el encabezado se ignora. La razón es que, simplemente, HTTP es tan inseguro que no se puede confiar en él.

Let’s use the Facebook example to further illustrate how this is helpful in practice. You are accessing facebook.com for the first time, and you know HTTPS is safer than HTTP, so you access it over HTTPS, //facebook.com. When your browser receives the HTML, it receives the header above which tells your browser to force-redirect you to HTTPS for future requests. One month later, someone sends you a link to Facebook using HTTP, //facebook.com, and you click on it. Since one month is less than the 15552000 seconds specified by the max-age directive, your browser will send the request as HTTPS, preventing a potential MITM attack.

Closing Thoughts

Web security is important no matter where you are in your web development journey. The more you expose yourself to it, the better off you will be. Security is something that should be important to everyone, not just the people who have it explicitly named in their job title! ?