Lista blanca de la API REST CORS

2

Tengo una API REST. Quiero usar esta API desde múltiples aplicaciones web. Solo quiero permitir solicitudes de clientes en lista blanca. Mi primer punto de llamada sería agregar los encabezados necesarios al servidor web REST API (dominios permitidos), todo bien. Pero, ¿esto solo son clientes de la lista blanca que usan navegadores? ¿Hay alguna manera de evitar realmente el acceso mediante secuencias de comandos a la API? Me refiero a PHP, Java, .NET o algún otro lenguaje del lado del servidor para hacer una llamada web directamente a la URL de la API de REST, y por supuesto, ya que la solicitud se construye manualmente, pueden agregar los encabezados que deseen (ORIGEN, etc.), por lo que podría falsificar una solicitud de dominio. Ni siquiera creo que necesites un script, una solicitud compuesta del fiddler lograría el mismo resultado.

¿Es posible permitir solo las solicitudes de los navegadores (que pasan la configuración de CORS) y denegar todas las demás?

En última instancia, es una API REST que habilita CORS intrínsecamente inseguro. A pesar de que los encabezados CORS le brindan un mecanismo para la inclusión de clientes en la lista blanca, se basa en HTTP y las solicitudes HTTP construidas manualmente pueden eludir esto fácilmente.

Por supuesto, una configuración de CORS evitará la inserción arbitraria en el sitio web que no desea, por lo que es bueno para todos.

Ha sido un tema que ha surgido dentro de mi equipo varias veces. En estos días estamos escribiendo más y más tipos de aplicaciones Web (REST) API, lo cual es una buena razón porque la funcionalidad se puede reutilizar en una nueva aplicación de manera simple, pero se han planteado ideas sobre la seguridad. No es seguridad en la exposición de datos, sino que solo permite el acceso a la API en función de los clientes permitidos, que tenemos en la lista blanca.

    
pregunta OJay 13.09.2016 - 23:38
fuente

2 respuestas

3

TLDR: No, y si crees que lo necesitas, probablemente estés haciendo algo mal.

Literalmente, no hay forma posible de evitar el acceso sin navegador a cualquier cosa que también esté expuesta a los navegadores. En lo que respecta a un servidor, un navegador web es solo un programa que envía y recibe tráfico HTTP (y protocolos relacionados). Eso es. Puede hacer eso usando curl , puede hacerlo usando cualquiera de los muchos tipos de objetos WebRequest disponibles para diferentes marcos de programación, puede hacerlo abriendo un simple socket TCP al servidor y escribiendo manualmente los bytes para enviar (ver el programa nc / ncat / netcat ). Cualquier otro programa puede falsificar cualquier información que un navegador normalmente proporciona: cookies, encabezado de Usuario-Agente, peculiaridades de URL y HTTPS específicas del navegador, autorización HTTP, certificados de cliente TLS, análisis de JavaScript, etc. Eso incluye absolutamente todos los encabezados y comportamientos de CORS.

Lo que puedes hacer es requerir autenticación. Si el consumidor de su servicio web está autenticado, a quién le importa si está usando un navegador web normal, un lector de pantalla para personas ciegas, una aplicación móvil, un servidor web PHP, un programa telnet en un Commodore 64, o pulsando el botón bits individualmente muy rápidamente por semáforo?

En teoría, la autenticación de origen cruzado no es tan difícil. Debe enviar el encabezado de respuesta Access-Control-Allow-Credentials: true CORS (que permite los encabezados y cookies de Autorización HTTP) o el encabezado de respuesta Access-Control-Allow-Headers: <HEADERNAME> CORS (con un encabezado de autenticación personalizado). En cualquier caso, también debe proporcionar alguna forma para que un cliente obtenga un token de autenticación válido (que podría ser a través de una aplicación web, un servicio web o algún otro medio; incluso podría ser otro servicio web habilitado para CORS) . Por supuesto, de manera similar, no tiene forma de impedir el acceso mediante secuencias de comandos al servicio de autenticación, por lo que cualquier persona / cualquier cosa con credenciales puede obtener un token válido y luego utilizarlo.

¿Cuál es su caso de uso, aquí? ¿Por qué estás tratando de bloquear el acceso mediante scripts? ¿Por qué esperas que esto funcione? Me refiero a que los navegadores web pueden ejecutar secuencias de comandos, por lo que no hay nada que impida que un navegador web cargue una página que contenga JavaScript para acceder a su servicio web, recuperar los resultados y enviarlos a una aplicación de escritorio o servidor.

EDIT:

  

En última instancia, es una API REST que habilita CORS intrínsecamente inseguro

O no entiendes lo que significa "seguro" o no entiendes lo que hacen los servidores web. Los servidores web analizan las solicitudes HTTP entrantes (HTTP es un protocolo basado en texto típicamente enviado en el puerto TCP 80, o envuelto dentro de un flujo SSL / TLS enviado al puerto TCP 443) y, en función del contenido del Solicitud de HTTP, enviar de vuelta una respuesta HTTP. Los servidores web son "intrínsecamente inseguros" en el sentido de que, si expone información confidencial en uno, cualquier persona que pueda conectarse a ella a través de la red y pueda enviar la cadena correcta de bytes puede recuperar esa información. Por supuesto, así es como funciona aproximadamente cada servidor de red para cada protocolo en el mundo, así que ...

Como nota al margen, esto no es un problema de CORS. Si no permites CORS en absoluto, no hará absolutamente ninguna diferencia en el tipo de "atacante" que estás imaginando. CORS es una forma de abrir un agujero en una parte crítica del modelo de seguridad del navegador (llamada " política del mismo origen "), pero es absolutamente irrelevante para las cosas que no son navegadores.

    
respondido por el CBHacking 14.09.2016 - 00:02
fuente
1

Esto es bastante similar a la respuesta de CBHacking. Acabo de agregar algunos addo CSRF.

  

Quiero permitir solo solicitudes de clientes en lista blanca.

Si estás en la web, ya estás muerto con las botas allí. La única forma real de incluir en la lista blanca a los clientes es utilizar:

  1. Criptografía de clave pública para firmar todo el sistema operativo (y probablemente también el hardware) del dispositivo que ejecuta el cliente.
  2. Criptografía de clave pública para establecer un canal seguro entre el cliente y el servidor (aunque HTTPS puede ser lo suficientemente bueno si sus certificados de CA son parte de lo que firmó anteriormente).

En serio, no trates de hacer eso, es una tarea estúpida.

  

En última instancia, es una API REST que habilita a CORS intrínsecamente inseguro.

Por el contrario. Pero CORS se trata de seguridad del navegador , se trata de las expectativas del usuario frente a la ventana del navegador. En otras palabras, si su API REST en http://rest.com usa esto:

Access-Control-Allow-Origin: http://example.com

Luego, una persona que navega example.com con un navegador puede realizar una solicitud (que contenga Origin: http://example.com ) que cumpla con el requisito.

Pero una página web maliciosa no puede hacerlo desde el navegador.

Si no desea que toda la Internet vea una página web (o una API REST), debe autenticar a los usuarios que pueden verla. Y simplemente no lo envíe a los usuarios que no se autentiquen correctamente.

Para evitar llamadas falsificadas, debe defenderse de CSRF, no acceder desde un determinado cliente. Realizará la autenticación en la API REST y luego enviará los datos del usuario solo a los usuarios autorizados.

Ahora, esto requiere protección CSRF porque CSRF no está realmente cubierto por CORS (eso no es estrictamente cierto ya que el encabezado Origin puede usarse como protección CSRF pero es una protección bastante pobre). Use las pautas de OWASPs y produzca la sincronización del CSRF para que las personas tengan más cuidado. (decentemente) evite los scripts fraudulentos que pueden detectar el tráfico de un usuario para inyectar sus propias solicitudes.

Lectura adicional sobre tokens CORS versus CSRF: antiguo (pero aún actual) SO respuesta por SilverlightFox

    
respondido por el grochmal 14.09.2016 - 00:14
fuente

Lea otras preguntas en las etiquetas