¿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.
fuente
Respuestas:
¿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).
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.
fuente
<script>
etiqueta, ya sea deliberadamente ("JSONP") o accidentalmente ( JSON sin protección ).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.
fuente
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,
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.
fuente
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.
fuente