¿Estoy sobreingeniería si considero un error intencional del usuario?

12

¿Es un exceso de ingeniería si agrego protección contra las irregularidades intencionales de un usuario (por decirlo suavemente), si el daño en el que puede incurrir el usuario no está relacionado con mi código?

Para aclarar, expongo un servicio JSON RESTful simple como este:

GET /items - to retrieve list of user's items
PUT /items/id - to modify an item
POST /items - to add a new item

El servicio en sí no está destinado a ser utilizado a través de un navegador, sino solo desde aplicaciones de terceros, controladas por el usuario (como aplicaciones de teléfono, aplicaciones de escritorio, etc.). Además, el servicio en sí mismo debe ser sin estado (es decir, sin sesión).

La autenticación se realiza con la autenticación básica sobre SSL.

Estoy hablando de un posible comportamiento "dañino" como este:

El usuario ingresa la URL GET en un navegador (no hay razón pero ...). El navegador solicita la autenticación básica, la procesa y almacena la autenticación para la sesión de navegación actual. Sin cerrar el navegador, el usuario visita un sitio web malicioso, que tiene un javascript CSRF / XSRF malicioso que realiza una POST a nuestro servicio.

El escenario anterior es altamente improbable, y sé que desde una perspectiva comercial no debería preocuparme demasiado. Pero en aras de mejorar la situación, ¿cree que si el nombre de usuario / contraseña también se requieren en los datos de JSON POST, será útil?

¿O debería abandonar la autenticación básica por completo, deshacerme de GET y usar solo POST / PUT con información de autorización? Como la información recuperada a través de GET también puede ser sensible.

Por otro lado, ¿el uso de encabezados personalizados se considera una implementación REST pura? Puedo soltar la autenticación básica y usar encabezados personalizados. De esa forma, se puede evitar al menos el ataque CSRF desde un navegador, y las aplicaciones que utilizan el servicio establecerán el nombre de usuario / contraseña en un brezo personalizado. Malo para este enfoque es que ahora el servicio no se puede consumir desde un navegador.

Soleado
fuente
3
Además de mi respuesta, también me gustaría dejar esta declaración, creo que esto probablemente se respondería mejor en SO o Seguridad
Jeff Langemeier
1
Creo que ha cambiado PUT y POST según lo definido por RFC 2616 ( tools.ietf.org/html/rfc2616#section-9.5 ).
Svante

Respuestas:

6

¿Ingeniería excesiva? De ningún modo. Las medidas anti-XSRF son una parte necesaria de cualquier aplicación o servicio web seguro. Puede ser o no "altamente improbable" que alguien elija atacarte, pero eso no hace que tu software sea menos inseguro.

Los sistemas han sido atacados comúnmente usando XSRF, y aunque los resultados son menos inmediatos, obviamente malos que la inyección SQL o XSS, son lo suficientemente malos como para comprometer todas las características interactuables por el usuario.

Eso significa que no puede tener una interfaz RESTful "pura" donde los únicos parámetros son las propiedades de la llamada en sí. Debe incluir algo en la solicitud que un atacante no pueda adivinar. Ese podría ser el par de nombre de usuario y contraseña, pero está lejos de ser la única opción posible. Podría tener un nombre de usuario junto con el token generado a partir de un hash salado de la contraseña. Podría tener tokens emitidos por el propio servicio en el momento de la autenticación (que podría recordarse en la sesión o verificarse criptográficamente).

debería deshacerme del GET

No, las solicitudes GET se utilizan para solicitudes de lectura que no tienen una operación de escritura activa (son "idempotentes"). Solo las operaciones de escritura requieren protección XSRF.

bobince
fuente
¿Qué sucede si la solicitud GET puede revelar información confidencial?
Soleado
@Sunny: ¿Qué estás considerando datos confidenciales?
Chris
2
Chris, si me vuelvo paranoico, todos los datos son confidenciales, si los recibe el usuario "equivocado" :). Es teorico.
Soleado
Por favor, revise los cambios en la pregunta que agregué.
Soleado
1
Está bien que la respuesta (ya sea GET u otro método) contenga datos que solo el usuario debería ver. Un ataque XSRF solo le permite al atacante que el usuario haga una solicitud en particular, no le permite leer la respuesta que regresa de esa solicitud. A menos que el script de destino se construya de una manera especial para permitir que páginas de terceros lo lean desde una <script>etiqueta, ya sea deliberadamente ("JSONP") o accidentalmente ( JSON sin protección ).
bobince
32

Nunca confíes en nada. Cada solicitud es un ataque. Cada usuario es un hacker. Si desarrolla con esta mentalidad, su aplicación será mucho más segura, estable y menos probable que sea secuestrada por un usuario malintencionado. Todo lo que necesita es una persona inteligente para encontrar una forma de evadir su seguridad para que tenga serios problemas con sus datos (uno de sus recursos más valiosos ).

Si ha identificado un agujero de seguridad en su aplicación, haga todo lo que cree que necesita hacer para cerrar la brecha. Su API, especialmente, debería ser la pieza de software más poco confiable que existe. Solicitaría las credenciales e iría con las solicitudes de publicación.

Ortigas Jarrod
fuente
44
YAY para la paranoia! ¡Tienes enemigos! (Y +1 por cada solicitud es un ataque )
Treb
0

Si el código se establece y se mantiene, los casos límite se deben analizar y tratar caso por caso.

FIJACIÓN DEBIDO A ALGUNOS ERRORES DE MI PARTE:

GET aún debe usarse como parte de un servicio RESTful adecuado, la autenticación debe estar allí en cualquier caso. Lo que estaba tratando de suponer era que, por motivos de seguridad, GET es muy similar a POST, pero la publicación hace su trabajo sin poner la información en una barra de direcciones, que tiende a ser la gran diferencia de seguridad (y por qué no me gusta GET), pero como publicado por @Lee,

GET requests are used to retrieve resources, and PUT/POST are used to add/update 
resources so it would be completely against expectations for a RESTful API to use
PUT/POST to get data. 

Dado que esto será utilizado por aplicaciones de terceros, se deben seguir las buenas prácticas para un servicio RESTful para que el implementador final no se confunda en esta parte.

Jeff Langemeier
fuente
3
¿En qué se diferencia GET de POST en términos de seguridad? Ambos se envían sin formato a través del transporte (HTTP o HTTPS), la única diferencia es que las cadenas de consulta GET son visibles en la barra de direcciones.
tdammers
1
@Sunny: POST está tan expuesto como GET a este respecto. Enciende Telnet y habla con un servidor web si no me crees.
tdammers
1
@Jeff: La razón por la que estoy sacando Telnet (o curl, wget o un buen sniffer anticuado) es que te permite ver el flujo de datos completo. Sí, HTTPS oculta esta información de los espías, pero cualquier persona en cualquier extremo de la conexión SSL puede ver exactamente lo que ve Telnet.
tdammers
1
@Jeremy: POST no muestra los parámetros en la barra de direcciones, pero dado que los datos son tan visibles en la secuencia HTTP real, tiene toda la razón.
tdammers
77
Las solicitudes GET se usan para recuperar recursos, y PUT / POST se usan para agregar / actualizar recursos, por lo que sería completamente contrario a las expectativas de que una API RESTful use PUT / POST para obtener datos.
Lee
0

Debe tener en cuenta todas las eventualidades plausibles, incluido el hecho de que el usuario sea activamente malicioso y (con éxito) aplique ingeniería inversa a cualquier barrera de "seguridad por oscuridad".

Pero al mismo tiempo, debe evaluar el impacto de un hack de éxito y la probabilidad de que tenga lugar un intento. Por ejemplo:

  • Es menos probable que un servicio interno protegido por un firewall sólido esté sujeto a ataques que un servicio en Internet público.

  • El impacto de que alguien elimine un foro de discusión de clientes es menor que el de robar tarjetas de crédito de clientes.


Mi punto es que la "seguridad total" es "infinitamente costosa" ... y prácticamente inalcanzable. Idealmente, debe tomar sus decisiones sobre dónde trazar la línea basándose en un análisis exhaustivo de costo-beneficio.

Stephen C
fuente
Gracias. La cuestión no era proteger "del" usuario, sino proteger al usuario si actúan de manera irresponsable. Pero su respuesta tiene pocos puntos buenos.
Soleado