Encriptación

La encriptación suele ser un tema de seguridad, pero también es importante para la privacidad. El objetivo de la encriptación es evitar que otras personas lean la información encriptada, pero evitar que otras personas lean tu información es una forma de mantenerla privada. A menudo, un usuario está limitado en cuanto a cuánto puede hacer eso por su cuenta, pero con tu asistencia como proveedor de un servicio que usa, la encriptación puede ayudar a mantener sus datos.

Existen tres formas relevantes de aplicar la encriptación para ayudar a la privacidad del usuario: encriptación en tránsito, encriptación en reposo y encriptación de extremo a extremo:

  • La encriptación en tránsito consiste en mantener los datos encriptados entre el usuario y tu sitio; es decir, HTTPS. Probablemente ya hayas configurado HTTPS para tus sitios, pero ¿seguro que todos los datos en tránsito hacia tus sitios están encriptados? Para eso son el redireccionamiento y el HSTS. Estos se describen a continuación y deben formar parte de la configuración de HTTPS.
  • La encriptación en reposo es la encriptación de los datos almacenados en tus servidores. Esto brinda protección contra violaciones de la seguridad de los datos y es una parte importante de tu postura de seguridad.
  • La encriptación de extremo a extremo es la encriptación de los datos en el cliente antes de que lleguen a tu servidor. Esto protege incluso los datos del usuario: puedes almacenar los datos de tus usuarios, pero no puedes leerlos. Esto es difícil de implementar y no es adecuado para todos los tipos de aplicaciones, pero es una gran ayuda para la privacidad del usuario, ya que solo ellos pueden ver sus datos.

HTTPS

El primer paso es entregar tu servicio web a través de HTTPS. Es muy probable que ya lo hayas hecho, pero, de no ser así, es un paso importante. HTTPS es HTTP, el protocolo que utiliza un navegador para solicitar páginas web de un servidor, pero encriptado con SSL. Esto significa que un atacante externo no puede leer una solicitud HTTPS entre el remitente (tu usuario) y el destinatario (tú), ni interferir en ella, porque está encriptada y el destinatario no puede leerla ni cambiarla. Esto es encriptación en tránsito, es decir, mientras los datos se transfieren de un usuario a otro o de ti al usuario. La encriptación HTTPS en tránsito también evita que el ISP del usuario, o el proveedor de la red Wi-Fi que está usando, pueda leer los datos que te envía como parte de su relación con el servicio. También puede afectar las funciones de tu servicio: muchos usos de las APIs de JavaScript existentes requieren que el sitio web se entregue a través de HTTPS. MDN tiene una lista más completa, pero las APIs con puerta de enlace detrás de un contexto seguro incluyen service worker, notificaciones push, uso compartido web y criptografía web, y algunas APIs de dispositivos.

Para entregar tu sitio web a través de HTTPS, necesitarás un certificado SSL. Se pueden crear de forma gratuita a través de Let's Encrypt, o, a menudo, se pueden proporcionar a través de tu servicio de hosting si usas uno. También es posible usar un servicio de terceros que “envía a través de proxy” tu servicio web y puede proporcionar HTTPS, además de servicios de almacenamiento en caché y CDN. Hay numerosos ejemplos de estos servicios, como Cloudflare y Fastly. Usarlos depende de tu infraestructura actual. En el pasado, HTTPS podía ser difícil o costoso de implementar, por lo que se solía usar solo en páginas de pagos o en orígenes muy seguros. Sin embargo, los certificados disponibles de forma gratuita, las mejoras de los estándares y la mayor proliferación de navegadores quitaron todos esos obstáculos.

  • Habilita HTTPS en tus servidores para todo (el método que elijas).
  • Considera usar un proxy frente a tus servidores, como Cloudflare (en httpsiseasy.com/ se explica el proceso).
  • Let's Encrypt te guiará durante el proceso de creación de tu propio certificado SSL de Let's Encrypt.
  • También puedes usar OpenSSL directamente para crear tu propio certificado y firmarlo por la autoridad certificadora (AC) que elijas (en Habilitar HTTPS se explica en detalle cómo hacerlo).

El enfoque que elijas dependerá de las compensaciones de la empresa. Tener un tercero que administre la conexión SSL es la más fácil de configurar y viene con otros beneficios como el balanceo de cargas, el almacenamiento en caché y las estadísticas. Sin embargo, también implica la cedencia evidente de cierto control a ese tercero y una dependencia inevitable de sus servicios (y un posible pago, según los servicios que uses y tus niveles de tráfico).

Generar certificados y tenerlos firmados por una AC es la forma en que se llevaba a cabo el proceso SSL, pero usar Let's Encrypt puede ser más fácil si lo admite tu proveedor o si el equipo de servidor es lo suficientemente experto en términos técnicos para ello y es gratuito. También es común que tu proveedor ofrezca SSL como servicio si usas algo en un nivel superior que el hosting en la nube, por lo que vale la pena verificarlo.

Por qué

La seguridad es parte de tu historia de privacidad: poder demostrar que proteges los datos del usuario contra interferencias ayuda a generar confianza. Si no utilizas HTTPS, tus sitios también se marcarán como "no seguros" por parte de los navegadores (y lo han hecho desde hace tiempo). A menudo, las APIs de JavaScript existentes solo están disponibles para páginas HTTPS ("orígenes seguros"). También protege a tus usuarios contra el uso de la Web que ven sus ISP. Sin duda, esta es una práctica recomendada; por el momento, no hay razones para no utilizar HTTPS para sitios web.

Cómo presentan los navegadores una página HTTP (no segura)

Advertencia de la URL de escritorio de Chrome "No segura".
Google Chrome (computadoras de escritorio)
Advertencia sobre la URL HTTP de Firefox.
Mozilla Firefox (computadoras de escritorio)
Advertencia de URL HTTP para computadoras de escritorio de Safari.
Apple Safari (para computadoras con macOS)
Advertencia de HTTP para dispositivos móviles de Android.
Google Chrome (dispositivos móviles Android)
Advertencia de HTTP de iOS en Apple Safari.
Apple Safari (dispositivos móviles iOS)

Redireccionar a HTTPS

Si tu sitio está disponible en URLs http: y https:, debes redireccionar todos los accesos http a https. Esto es por los motivos mencionados anteriormente y también garantiza que tu sitio no aparezca en whynohttps.com si se vuelve popular. Cómo hacerlo depende en gran medida de tu infraestructura. Si estás alojado en AWS, puedes usar un balanceador de cargas clásico o de aplicación. Google Cloud es similar. En Azure, puedes crear una Puerta principal; en Node con Express, check for request.secure; en Nginx, capturar todos los puertos 80 y mostrar 301; y en Apache, usar una RewriteRule. Si usas un servicio de hosting, es muy probable que se manejen automáticamente con el redireccionamiento a URLs HTTPS por ti, como las páginas de Netlify, Firebase y GitHub, entre muchos otros.

HSTS

HSTS es la forma abreviada de "HTTP con Seguridad de Transporte Estricta" y es una forma de bloquear un navegador para que use HTTPS para tu servicio para siempre. Una vez que estés satisfecho con tu migración a HTTPS, o si ya lo hiciste, puedes agregar un encabezado de respuesta HTTP de seguridad de transporte estricta a tus respuestas salientes. Un navegador que haya accedido a tu sitio antes registrará haber visto este encabezado y, a partir de ese momento, accederá automáticamente al sitio como HTTPS, incluso si solicitas HTTP. De esta manera, se evita el redireccionamiento, como se indica más arriba: es como si el navegador "actualizara" silenciosamente todas las solicitudes de tu servicio para usar HTTPS.

De manera similar, puedes publicar un encabezado Upgrade-Insecure-Requests junto con tus páginas. Esto hace algo diferente a Strict-Transport-Security, pero está relacionado con él. Si agregas Upgrade-Insecure-Requests: 1, las solicitudes de esta página a otros recursos (imágenes, secuencias de comandos) se solicitarán como HTTPS incluso si el vínculo es http. Sin embargo, el navegador no volverá a solicitar la página como HTTPS, y este no la recordará para la próxima vez. En la práctica, Upgrade-Insecure-Requests resulta útil si conviertes un sitio existente con muchos vínculos a HTTPS y conviertes las URLs de los vínculos en el contenido resulta difícil, pero es mejor cambiar el contenido siempre que sea posible.

HSTS es principalmente una función de seguridad: "bloquea" tu sitio a HTTPS para los usuarios que ya estuvieron allí. Sin embargo, como se indicó antes, HTTPS es útil para la privacidad y HSTS es útil para HTTPS. Del mismo modo, las solicitudes de actualización no seguras no son realmente necesarias si estás actualizando todo el contenido, pero es un enfoque útil de "corte y llaves" para agregar defensa en profundidad para garantizar que tu sitio siempre sea HTTPS.

Agrega el encabezado HSTS a tus respuestas salientes:

Strict-Transport-Security: max-age=300; includeSubDomains

El parámetro max-age determina el tiempo, en segundos, que el navegador debe recordar y aplicar la actualización a HTTPS. (Aquí, lo configuramos en 300 segundos, es decir, cinco minutos). Con el tiempo, querrías que fuera 6,3072,000, lo que equivale a dos años, y es la cifra que recomienda hstspreload.org, pero es bastante difícil de recuperar si hay problemas. Por lo tanto, se recomienda configurar esto con un número bajo al principio (300), hacer pruebas para confirmar que no se haya dañado nada y, luego, aumentar el número en etapas.

Agrega los encabezados Upgrade-Insecure-Requests a tus respuestas salientes:

Upgrade-Insecure-Requests: 1 Content-Security-Policy: upgrade-insecure-requests

Encriptación de extremo a extremo

Una buena forma de mantener la privacidad de los datos del usuario es mostrárselos a nadie más que al usuario, incluso a ti. Esto ayuda mucho a tu postura de confianza: si no tienes los datos de tu usuario, está claro que no puedes hacer nada con ellos que él no querría. Una forma de hacerlo es almacenar todo del lado del cliente para no permitir que los datos del usuario salgan de su dispositivo. Este enfoque funciona, pero hay limitaciones para una aplicación pura del cliente: el almacenamiento de datos del navegador puede tener un tamaño limitado y, en algunos navegadores, se puede borrar con poca o ninguna advertencia. También es difícil o imposible acceder a tus datos desde dos dispositivos, como una laptop y un teléfono celular. Por este motivo, puede ser útil enviar datos al servidor con normalidad, pero encriptarlos con una clave conocida solo por el usuario, de modo que el servidor no pueda acceder a ellos (porque no puede desencriptarlos), pero sí almacenarlos.

¿Cómo funciona?

Las aplicaciones de mensajería usan este enfoque con frecuencia como “encriptación de extremo a extremo” o “e2e”. De esta manera, dos personas que conocen las claves de la otra pueden encriptar y desencriptar sus mensajes de un intercambio y, luego, enviarlos a través del proveedor de mensajería, pero el proveedor de mensajería (que no tiene esas claves) no puede leerlos. La mayoría de las aplicaciones no son apps de mensajería, pero es posible combinar los dos enfoques (un almacén de datos solo del cliente y la encriptación de datos con una clave que el cliente conozca) para almacenar datos de forma local, pero también enviarlos encriptados al servidor. Es importante tener en cuenta que este enfoque tiene limitaciones: esto no es posible para todos los servicios y, en particular, no se puede usar si tú, como proveedor de servicios, necesitas acceso a lo que el usuario almacena. Como se describe en la parte 2 de esta serie, es mejor obedecer el principio de minimización de datos; evita recopilar datos si puedes. Si el usuario necesita almacenamiento de datos, pero no necesitas acceder a ellos para proporcionar el servicio, la encriptación de extremo a extremo es una alternativa útil. Si proporcionas servicios que requieren poder ver lo que el usuario almacena para proporcionarlos, la encriptación de extremo a extremo no es adecuada. Pero si no lo haces, puedes hacer que el código JavaScript del cliente de tu servicio web encripte todos los datos que envía al servidor y desencripte los datos que recibe.

Un ejemplo: Excalidraw

Excalidraw hace esto y explica cómo en una entrada de blog. Es una app de dibujo vectorial que almacena dibujos en el servidor, que se encriptan con una clave elegida al azar. Parte del motivo por el que Excalidraw puede implementar esta encriptación de extremo a extremo con relativamente poco código es que las bibliotecas criptográficas ahora están integradas en el navegador con window.crypto, un conjunto de APIs de JavaScript compatibles con todos los navegadores modernos. La criptografía es difícil y la implementación de los algoritmos incluye casos extremos. Hacer que el navegador realice el trabajo pesado aquí hace que la encriptación sea más accesible para los desarrolladores web y, por lo tanto, facilita la implementación de la privacidad a través de datos encriptados. Como se describe en Excalidraw en su informe, la clave de encriptación permanece del lado del cliente, porque forma parte del fragmento de URL: cuando un navegador visita una URL https://example.com/path?param=1#fraghere, la ruta de acceso de la URL (/path) y los parámetros (param=1) se pasan al servidor (example.com), pero el fragmento (fraghere) no lo hace, y el servidor nunca lo verá. Esto significa que, incluso si los datos encriptados pasan por el servidor, no lo hace y, por lo tanto, la privacidad se conserva porque los datos están encriptados de extremo a extremo.

Limitaciones

Este enfoque para encriptar los datos del usuario no es infalible. Contribuye a tu postura de confianza para tus usuarios, pero no puede reemplazarla por completo. Tus usuarios seguirán teniendo que confiar en tu servicio, ya que podrías, en cualquier momento, cambiar el código JavaScript del cliente por un JavaScript sutilmente similar que no encripta de forma impenetrable los datos. Si bien es posible que un usuario detecte si un sitio web lo hizo, es extremadamente difícil hacerlo. En la práctica, tus usuarios deberán demostrar que sus datos no son legibles y que no son dignos de confiar en que tus datos no son legibles y no es confiable.

También es importante recordar que uno de los objetivos de la encriptación de extremo a extremo es impedir que tú, el propietario del sitio, puedas leer los datos. Esto es bueno para la privacidad, pero también significa que, si hay problemas, no puedes ayudar. En términos simples, un servicio que usa encriptación de extremo a extremo pone al usuario a cargo de las claves de encriptación. (esto puede no ser evidente ni evidente, pero alguien debe tener la clave, y si los datos se mantienen privados para ti, no eres tú). Si se pierden esas claves, no habrá nada que puedas hacer para ayudar y es probable que también se pierdan los datos encriptados con esas claves. Aquí hay un buen equilibrio entre la privacidad y la usabilidad: se debe mantener la privacidad de los datos para todos los usuarios mediante la encriptación, pero también se debe evitar que los usuarios tengan que ser expertos en criptología que administren sus propias claves de forma segura.

Encriptación en reposo

Además de encriptar los datos en tránsito de tus usuarios, también es importante considerar la encriptación de los datos que almacenaste en el servidor. Esto ayuda a brindar protección contra las violaciones de la seguridad de los datos, ya que cualquier persona que obtenga acceso no autorizado a tus datos almacenados tendrá datos encriptados y, quizás, no tenga las claves para desencriptarlos. Existen dos enfoques diferentes y complementarios para la encriptación de datos en reposo: la encriptación que agregas y la encriptación que agrega tu proveedor de almacenamiento en la nube (si usas un proveedor de almacenamiento en la nube). La encriptación del proveedor de almacenamiento no brinda mucha protección contra las violaciones de la seguridad de los datos a través de tu software (ya que la encriptación del proveedor de almacenamiento suele ser transparente para ti como usuario de su servicio), pero ayuda contra las violaciones de la seguridad que ocurren en la infraestructura del proveedor. Suele ser fácil de activar, por lo que vale la pena considerarlo. Este campo cambia rápidamente y tu equipo de seguridad (o los ingenieros expertos en seguridad de tu equipo) son los mejores para asesorarlo, pero todos los proveedores de almacenamiento en la nube ofrecen encriptación en reposo para el almacenamiento en bloque Amazon S3 mediante la configuración, Azure Storage y Google Cloud Storage de forma predeterminada, y para el almacenamiento de datos de bases de datos AWS RDS, Azure SQL y Google Cloud SQL, entre otros.Google Cloud SQL{/11, entre otros. Verifica esto con tu proveedor de almacenamiento en la nube, si lo usas. Administrar la encriptación de datos en reposo por tu cuenta para ayudar a proteger los datos del usuario de las violaciones de la seguridad de los datos es más difícil, porque la logística de administrar de forma segura las claves de encriptación y hacer que estén disponibles para el código sin que también estén disponibles para los atacantes es un desafío. Este no es el mejor lugar para asesorar sobre problemas de seguridad en ese nivel. Comunícate con tus ingenieros expertos en seguridad, con un equipo dedicado o con agencias de seguridad externas.