Ocultar datos confidenciales en URIs

5

Esta es una pregunta potencialmente hipotética, ya que no se ha determinado si se nos pedirá que hagamos esto, pero creo que es una pregunta que surgirá con mayor frecuencia.

Fondo

Al implementar servicios RESTful el enfoque estándar es que el URI contiene la información necesaria para identificar el resource en cuestión. Si bien no soy un restafarian , este enfoque tiene muchas ventajas sobre las que deseamos aprovechar.

Problema

Estamos sujetos a los requisitos reglamentarios relacionados con la protección de ciertos tipos de información. Algunos de estos elementos protegidos terminarán en rutas de recursos si seguimos la fórmula REST básica.

TLS cubrirá la mayoría de las inquietudes acerca de porque las URL están cifradas. Sin embargo, hay algunos lugares donde se pueden almacenar a la vista. En particular, a menudo se escriben para acceder a los registros (lo cual es útil) de manera predeterminada y si las personas usan los navegadores para esto, se pueden almacenar de forma clara en su historial de navegación.

Enfoque

Suponiendo que esto es un problema y queremos utilizar un enfoque de este tipo, parece que hay un candidato principal para la solución, que es cifrar partes de la URI o toda la misma. El hash no parece ser una opción, ya que los datos son altamente predecibles y el cálculo de todo el conjunto de valores es fácil. El cifrado de la URI completa limitará muchas de las ventajas del enfoque. El cifrado simétrico requiere distribuir una clave secreta ampliamente y, por lo tanto, anula el propósito. La opción que parece mejor es cifrar los datos confidenciales con una clave pública.

Tal como lo entiendo, su salida cifrada debe ser al menos tan larga como el módulo . Entonces, si vamos con una clave de 2048 bits, cada uno de los datos deberá tener al menos 256 bytes. Esto dará como resultado algunos URI bastante largos, pero creo que eso debería estar bien por un tiempo de todos modos y ese límite puede no aplicarse a nuestra solución.

¿Este enfoque parece válido y / o hay algo más que me estoy perdiendo? ¿Sería válido usar el mismo par de claves que se usaría para TLS? Probablemente deba haber alguna otra información en la parte encriptada para evitar ataques de reproducción o asignar un valor encriptado a la clave dada, ¿correcto?

NOTA : Debo mencionar que para mi problema específico, solo las partes autenticadas podrían llamar. Esto no es algo que pretendemos exponer en la Internet pública, aunque pueden ocurrir errores. Todas las partes involucradas están legalmente obligadas a proteger los datos. Creo que vale la pena explorar un uso más general de dicha idea debido a la creciente popularidad de los servicios RESTful.

    
pregunta JimmyJames 09.12.2016 - 17:34
fuente

5 respuestas

5
  

parece que hay un primer candidato para la solución, que es   encriptar partes de la URI o todo ello. El hash no parece ser un   Opción ya que los datos son altamente predecibles y calculan la totalidad   El conjunto de valores es fácil. Encriptar la URI completa se limitará una gran cantidad de   Las ventajas del enfoque. El cifrado simétrico requiere   Distribuyendo una clave secreta ampliamente y por lo tanto vence el propósito.   La opción que parece mejor es cifrar los datos confidenciales.   con una clave pública.

Tu lógica es sólida.

Sé de un producto que hace exactamente lo que usted sugiere; Los datos confidenciales se cifran en el navegador de los usuarios finales mediante el código Javascript, y se realiza una solicitud GET de HTTPS en la que algunos de los pares de parámetros 'clave = valor' tienen una cadena pública codificada en clave codificada en clave 64.

La ventaja es que estas solicitudes se pueden pasar a través de redes con múltiples puntos finales TLS sin que los datos confidenciales estén sujetos a descifrado, y cualquier registro o proxy del servidor web en el medio no tendrá acceso a los datos confidenciales.

  

¿Este enfoque parece válido y / o hay algo más que me estoy perdiendo?

Es válido, pero aquí están las cosas que no debes perderte:

  1. Necesita tener un cliente con suficiente inteligencia para realizar el cifrado por usted. Eso significa Javascript, o una aplicación personalizada, o algo así.
  2. No hagas rodar tu propia criptografía. Use una biblioteca sólida y confiable y obtenga una revisión del código de su aplicación.
  3. Gestión de claves. Debe generar claves, publicar claves, rotar claves y retirar claves ... y debe hacerlo con cuidado, porque hacerlo correctamente significa equilibrar entre perder el control de los datos y perder el acceso a los datos.
  

¿Sería válido usar el mismo par de claves que se usaría para TLS?

Lo recomendaría en contra. Aparte de la regla general de "no sobrecargar los sistemas criptográficos", hay algunas situaciones en las que esa clave no es "confiable". Uno de los que me he encontrado es que los servicios de mitigación DDoS a menudo les gusta tener una copia de sus certificados web y claves si están dirigiendo su tráfico durante un ataque.

  

Probablemente deba haber alguna otra información en la parte encriptada   para evitar ataques de repetición

Eso depende; Si la transacción REST con la que está trabajando es idempotente, entonces no es tan importante. Si cambia algo, entonces sí, la protección de repetición es más importante.

  

o asignando un valor cifrado a la clave dada, ¿correcto?

Sí, no es absolutamente necesario, dependiendo de la cantidad de teclas que uses y de la longitud de su cola OUP y RUP, pero es mucho más fácil no tener que adivinar qué tecla :)

    
respondido por el gowenfawr 11.12.2016 - 03:20
fuente
2
  

¿Este enfoque parece válido y / o hay algo más que me estoy perdiendo?

Su enfoque es válido, sin embargo; No descartaría usar una clave simétrica previamente compartida por las siguientes razones.

  • La asimetría es mucho más lenta de descifrar que la simétrica. Si el servicio tiene que descifrar múltiples valores de su rendimiento URI podría verse afectado.
  • El vector de ataque para este cifrado es limitado. TLS debería proteger estos datos en la mayoría de los casos.
  • Se puede dar diferentes claves pre-compartidas a diferentes consumidores para mayor seguridad (abordando su inquietud con simetría ampliamente compartida). Esto también permite una mayor flexibilidad con la rotación de la llave.
  • El cifrado asimétrico dará como resultado un gran texto cifrado. Si la cadena de consulta de URI + es lo suficientemente larga, podría causar un 414 (Request-URI demasiado largo)
  

¿Sería válido usar el mismo par de claves que se usaría para TLS?

En teoría, no deberías, porque si un atacante obtuviera tu par de claves podría descifrar tus conexiones TLS y amp; Sus encabezados encriptados.

... Ahora, desde un punto de vista realista / de soporte, si se obtiene su par de claves TLS es un escenario del día del juicio final. Tener un segundo par de llaves no evitaría un evento de "violación completa", ya que es probable que tenga datos confidenciales en los encabezados / cuerpo que podrían descifrarse.

Creo que debe sopesar cuidadosamente las opciones para su necesidad comercial específica.

    
respondido por el rdChris 27.12.2016 - 22:19
fuente
2

Recordé esto porque surgió como una "pregunta popular". Desde que pregunté esto, he aprendido que la recomendación OWASP es utilizar encabezados de solicitud:

  • En las solicitudes POST / PUT, los datos confidenciales deben transferirse en el cuerpo de la solicitud o en los encabezados de la solicitud
  • En las solicitudes GET, los datos confidenciales deben transferirse en un encabezado HTTP

Aunque esto hace que la API sea un poco más difícil de usar, hay soporte para este enfoque en al menos algunos marcos comunes.

    
respondido por el JimmyJames 25.04.2018 - 15:15
fuente
0

El enfoque más estándar es mover información sensible al cuerpo.

Realmente, esto se reduce a sus prácticas de registro. Podría hacer que la sugerencia anterior no valga la pena al incluir el cuerpo en sus registros, o podría evitar el problema al no registrar el URI completo. La información siempre está disponible para su servidor (incluso en su esquema cifrado, tiene que ser descifrado por al menos una parte de la pila).

Me parece que, en lugar de implementar un esquema complejo que engrosa las URL, hace que sea más difícil de depurar, y hace que los usuarios se pregunten qué está sucediendo, sería mejor cambiar los valores predeterminados en sus registros a algo que se adapte a ellos. tu entorno.

    
respondido por el Xiong Chiamiov 09.12.2016 - 20:50
fuente
0

Hay algunos puntos que su enfoque no ha considerado:

  •   

    encripte partes de la URI o todas ellas

    ¿Cómo cifrarás el URI? ¿El navegador lo hace o la página web? Si el navegador lo hace, ¿cómo sabe el navegador qué parte de la URI debe cifrar y si la página web lo hace, cómo obtendrá el certificado TLS del servidor? Lee esto . Además, no puede cifrar la URL completa; de lo contrario, el navegador no conocerá el servidor con el que debería hablar.

  •   

    Probablemente deba haber alguna otra información en la parte encriptada para evitar ataques de reproducción o asignar un valor encriptado a la clave dada, ¿correcto?

    Si está utilizando TLS, entonces la detección de reproducción ya está a cargo de TLS ( ¿Las solicitudes SSL encriptadas son vulnerables a los ataques de reproducción? ).

Hay varias discusiones sobre el cifrado de parámetros de URL que han ocurrido en StackOverflow: 1 , 2 y algunos otros resultados de búsqueda de Google: Es una mala idea , cómo hacerlo en Java

    
respondido por el Limit 10.12.2016 - 05:36
fuente

Lea otras preguntas en las etiquetas