Codificación del lado del cliente: ¿cómo evitar el uso malicioso?

60

En los últimos años, la tendencia de las aplicaciones del lado del cliente (navegador) realmente ha despegado.

Para mi último proyecto, he decidido intentar avanzar con los tiempos y escribir una aplicación del lado del cliente.

Parte de esta aplicación implica enviar correos electrónicos de transacciones a los usuarios (por ejemplo, validar el registro, correos electrónicos de restablecimiento de contraseña, etc.). Estoy usando una API de terceros para enviar los correos electrónicos.

Normalmente tendría mi aplicación ejecutándose en un servidor. Llamaría a la API de terceros desde el código de mi servidor.

Ejecutar una aplicación del lado del cliente significa que ahora esto debe suceder en el navegador de un usuario. La API de terceros proporciona los archivos JavaScript necesarios para lograr esto.

El primer problema evidente que puedo ver es que necesito usar una clave API. Esto normalmente se almacenaría de forma segura en mi servidor, pero ahora presumiblemente tendré que proporcionar esta clave al navegador del cliente.

Suponiendo que pueda solucionar este problema, el siguiente problema es lo que impide que un usuario experto en tecnología cargue la herramienta de desarrolladores de JavaScript en un navegador y use la API de correo electrónico de la forma que desee, en lugar de decir que se adhiera a las reglas que he establecido en la aplicación .

Supongo que mi pregunta general es: ¿cómo podemos evitar el uso malicioso de una aplicación del lado del cliente?

Gaz_Edge
fuente
24
¿Alguna razón por la que no tiene esta aplicación para comunicarse con su propio servidor y luego su servidor reenvía esas solicitudes a cualquier servicio externo que necesite usar? (Muchos de estos servicios prohibirían usarlos de esta manera de todos modos)
thorsten müller
11
Es por eso que las claves API son, en última instancia, inútiles. El servidor no debe intentar confiar en la aplicación que le envía comandos; solo debe confiar en el usuario.
Kevin Panko
42
No he visto ninguna persona cuerda jamás definir "la aplicación del lado del cliente" como "bajo ninguna circunstancia jamás comunicarse con un servidor" - que se parece más a un hombre de paja que un argumento razonable. Claramente, hay algunas cosas que tiene que manejar en el lado del servidor, pero la gran mayoría de las acciones se pueden realizar localmente sin problemas, lo que a su vez mejorará enormemente la capacidad de respuesta y la escalabilidad ...
Voo
44
¿Dónde ves un impulso hacia las "Aplicaciones exclusivas del navegador"? Nunca he visto algo como lo que estás describiendo, guardar secretos en el código del cliente en una idea increíblemente mala, incluso los tipos más exigentes que conozco nunca harían eso.
Wheeyls
2
Cualquier intento de proteger recursos seguros del lado del cliente está condenado porque viola varias de las leyes inmutables de seguridad. # 2/3: si su software se está ejecutando en la computadora de su adversario, no es su computadora por definición y ya ha perdido. El intento n. ° 7 de proteger un recurso mediante cifrado está condenado, ya que también debe proporcionarle al cliente la clave de descifrado. # 10 ninguna tecnología puede arreglar lo anterior. blogs.technet.com/b/rhalbheer/archive/2011/06/16/…
Dan Neely

Respuestas:

200

No puedes, y mientras más personas entiendan esto, y cuanto más entiendan, mejor para el mundo.

El código que se ejecuta en un dispositivo bajo el control del usuario no se puede controlar. Los teléfonos inteligentes pueden tener jailbreak. Los decodificadores se pueden descifrar. Los navegadores ordinarios ni siquiera intentan impedir el acceso al código JavaScript. Si usted tiene algo digno de robar o abusar, un atacante determinado va a ser capaz de hacer eso a menos que validar todo lo que apreciamos el lado del servidor.

La ofuscación es de muy poca ayuda; el tipo de oponente que atraerá tan pronto como se involucre algo remotamente financiero lee el lenguaje ensamblador como anuncios clasificados. El cifrado no puede ayudarlo, porque el dispositivo que protegería la clave es el mismo dispositivo que debe asumir que está descifrado. Hay muchas otras contramedidas aparentemente obvias que no funcionan, por razones similares.

Desafortunadamente, esta es una verdad muy inconveniente. El mundo está lleno de operadores pequeños y grandes que piensan que de alguna manera pueden sortear la ruptura fundamental de la confianza remota, simplemente porque sería tan bueno si pudiéramos asumir que nuestro código se ejecutará de la manera que asumimos. Y sí, haría todo mucho más fácil que ni siquiera es gracioso. Pero desear no lo hace así, y esperar contra la esperanza de que usted sea la única cookie inteligente que pueda evitar lo desagradable solo los quemará a usted y a sus clientes. Por lo tanto, tenga en cuenta que Internet es territorio enemigo, incluya ese costo adicional en sus estimaciones y estará bien.

Dicho esto, por supuesto, existe una defensa en profundidad. Ofuscar su JavaScript no desanima a un atacante determinado, pero puede desanimar a algunos atacantes menos determinados. Si sus activos valen lo suficiente para proteger, pero no a cualquier costo, cualquiera de esas medidas puede agregar valor comercial a su sistema; Simplemente no puede ser perfecto. Mientras sea plenamente consciente de la compensación que está haciendo, esa puede ser una estrategia razonable.

Kilian Foth
fuente
66
Pero para poner esto en perspectiva: esto es cierto para CADA software, ya sea un sistema operativo o un traje de transacción. Al final, hay algunos ofuscadores de código muy buenos y puede elevar el nivel lo más probable, ¡si no hay un incentivo financiero inmediato para hackear su software!
Falco
55
En estos días, las empresas han recurrido a acciones legales amenazantes contra las personas que piratean el contenido recibido de ellas antes del procesamiento (es decir, a través de bloqueadores de anuncios). Eso solo demuestra lo imposible que es la acción técnica .
Kilian Foth
62
Si puedo dar más detalles sobre las dos primeras oraciones, la sutileza que la gente suele pasar por alto es que el punto de las aplicaciones del navegador del lado del cliente es descargar el trabajo pesado. Su servidor sigue siendo responsable de operaciones confiables, como enviar correos electrónicos o acceder a los datos. Sin embargo, hacer que el cliente procese un gráfico a partir de esos datos le ahorra tiempo (y dinero) de la CPU sin cambiar el modelo de seguridad.
ssube
11
@Gaz_Edge Es importante tener en cuenta que el problema aquí no es que las aplicaciones del lado del cliente sean intrínsecamente inseguras. El problema es escribir estas aplicaciones del lado del cliente de una manera que requiera confiarle al cliente información que no desea que sea pública. Es totalmente posible escribir una aplicación para el cliente que sea tan segura como una aplicación donde la mayor parte del procesamiento ocurre en el servidor. (Para más información sobre eso, vea la respuesta de jhocking )
Ajedi32
77
@ Ajedi32 Las aplicaciones del lado del cliente son inseguras. Es imposible diseñar una aplicación segura si alguna lógica realizada en el lado del cliente no se verifica en el lado del servidor. En ese punto, la lógica del lado del cliente se convierte en una herramienta de interfaz de usuario o en una forma de descargar las comprobaciones básicas, ¡pero todo debe comprobarse siempre en el servidor! .
69

La regla aquí es:

Haga todo lo que sea del lado del cliente que no afecte a nadie más si el usuario lo manipula. En particular, eso significa efectos gráficos.

Haga todo lo que sea seguro en el lado del servidor y simplemente envíe eventos de IU desde el cliente (por ejemplo, el cliente simplemente dice "el usuario tocó el botón Comprar" mientras el servidor realmente realiza la transacción). En particular, eso significa transacciones financieras.

jhocking
fuente
28

Este es exactamente el caso en lo que es una aplicación completamente del lado del cliente es no apropiada.

Puede realizar la validación lógica y básica de los formularios del lado del cliente (aún tiene que volver a validar en el servidor, porque alguien puede intentar falsificar la solicitud) para mejorar la capacidad de respuesta, puede hacer solicitudes HTTP desde JavaScript pasando datos allí y de vuelta en JSON a evite reenviar decoraciones de página y demás, pero si la transacción en sí misma necesita ser autenticada y autorizada, aún debe ocurrir en un servidor.

Jan Hudec
fuente
11
Nota: Si bien es genial validar los formularios del lado del cliente, ¡nunca olvides también validarlos del lado del servidor! Cuando envía su código de cliente al navegador, ¡deja de ser su código! ¡Tienes que validar cada bit que envía de nuevo!
Josef
17

Su párrafo medio es el corazón del problema:

Ejecutar una aplicación del lado del cliente significa que ahora esto debe suceder en el navegador de un usuario. La API de terceros proporciona los archivos js necesarios para lograr esto.

¿Por qué una aplicación del lado del cliente significa que no puede tener trabajo del lado del servidor? El impulso hacia la programación del lado del cliente no se trata de eliminar servidores, sino de aprovechar las tecnologías más nuevas que los navegadores finalmente admiten para hacer mejores interfaces de usuario.

En cuanto al .jsarchivo que recibió, ¿está seguro de que está destinado a un navegador? ¿Podría ser una biblioteca node.js?

Brandon
fuente
44
+1 para la muy buena sugerencia de que el archivo JS está destinado a un servidor NodeJS
Machinarius
11

Retrocedamos con esto y echemos un vistazo a un nivel superior ... ¿deberíamos ... Eudora o Outlook (una aplicación del lado del cliente, que ni siquiera necesita un navegador) alguna vez causó una pérdida financiera para alguna empresa? No. Cualquiera podría escribir en las API POP / SMTP y ser el cliente. Pero no hay pérdida para el servidor. El servidor no limitó las acciones del cliente, los cálculos, el almacenamiento, la temperatura, el tamaño del disco, el tamaño del ram, el monitor DPI, GPU, FPU yada yada del cliente, pero especificó exactamente a qué respondería y nada más. ¿Alguna vez has oído hablar de quicken o MS-Money que se utiliza para ir a un banco?

La aplicación de su navegador (es decir, del lado del cliente) puede usar la misma arquitectura.

  1. Construye su servidor con una API (que por cierto, siempre se reduce a derivados de GET POST HEAD, etc.).
  2. En el servidor, asegúrese de que la API solo hable con un cliente autenticado y verificado por identidad para todas y cada una de las llamadas.
  3. Entonces no te importa quién es el cliente.
  4. Y luego no te importa si es un navegador, un dispositivo con jailbreak, Google Glass, DOS 3.1 o un nuevo Nexus en manos de un tecnófobo tatara-tatara-tatara-tatarabuelo que viajó en el tiempo hasta 2014 y se perdió todo La tecnología que ha estado inundando nuestras vidas en las últimas 15 décadas.
  5. Ahora puede comenzar a descargar todo lo demás al lado del cliente.

SoapBoxBegin

@KilianFoth plantea un importante punto de conciencia para los ingenuos e imprudentes, principalmente aquellos que leen los titulares todo el tiempo pero nunca piensan que sucederá con su aplicación, su código, su empleador, su cliente, su propia cuenta bancaria. Aún más imprudentes son sus empleadores (especialmente los CTO) que permitirían que salgan aplicaciones que expongan cualquier sistema a una exposición no controlada / no controlada. Sin embargo, siempre me sorprende cómo parece que "nunca aprendemos".

SoapBoxEnd

Entonces para resumir. Haga una API sólida y estrecha del lado del servidor. Descargue todo lo demás al cliente en función de lo que el cliente pueda manejar.

LMSingh
fuente
6

Yo diría que realmente no puedes. Si está dispuesto a enviar los datos al cliente, debe esperar que se abusará de ellos, aunque sea posible. Su ejemplo con respecto a la clave API es ilustrativo del punto, y no incluiría eso en su lado JS del cliente: será robado y abusado.

Definitivamente, todavía necesitará una cierta cantidad de código de servidor para mantener las cosas seguras. Incluso algo tan simple como recuperar solo los datos relacionados con el usuario conectado. Esa autenticación no se puede hacer todo del lado del cliente o nuevamente se aprovechará de usted y sus datos no son seguros.

Siempre vería la experiencia del lado del cliente JS como una adición al código del servidor. La validación en el cliente proporciona una buena experiencia de usuario, pero si no verifica también los datos POST en el servidor receptor, se está abriendo para atacar. Cualquier cosa del cliente debe considerarse sospechosa.

Matt Klinker
fuente
4

Es bastante simple, de verdad. Suponga que la computadora cliente y todo el software que se ejecuta en ella está bajo el control completo de un hacker malicioso inteligente.

Eso significa que cualquier información que envíe del servidor al cliente será conocida por el hacker malicioso, por lo que debe asegurarse de no enviar ninguna información al cliente que pueda usarse para atacar su servidor o su empresa.

También significa que cualquier cosa enviada desde el cliente al servidor ha sido producida por un hacker malicioso, por lo que su código de servidor debe asegurarse de que nada que el cliente pueda enviar sea capaz de atacar con éxito su servidor.

Es cierto que la implementación es un problema, pero lo importante es la actitud mental, la suposición de que el "cliente" con el que cree que su servidor está hablando no es un cliente sino un atacante activo.

(También debe suponer que el usuario es un estafador inteligente que intentará atacar sus métodos comerciales, pero eso no tiene nada que ver con la programación del lado del cliente).

gnasher729
fuente
0

La aplicación del lado del cliente, en mi opinión, se trata principalmente de la interfaz de usuario. Por ejemplo, todo su sistema de IU se enviará una vez al cliente, y luego el cliente hará lo que quiera con él.

Normalmente tendría mi aplicación ejecutándose en un servidor. Llamaría a la API de terceros desde el código de mi servidor.

Ejecutar una aplicación del lado del cliente significa que ahora esto debe suceder en el navegador de un usuario. La API de terceros proporciona los archivos JavaScript necesarios para lograr esto.

Si tiene una clave API, no está diseñada para funcionar en el lado del cliente. Si le da la clave API en el lado del cliente, entonces cualquiera tiene acceso a ella y luego puede usarla para su propio propósito. Almacénelo y utilícelo del lado del servidor cuando el cliente lo necesite, luego envíe el resultado usando Ajax / WebSockets.

Es como si su banco estuviera diciendo: "Bueno, voy a poner la contraseña del lado del cliente de la base de datos principal para que el cliente pueda solicitarla él mismo y no moleste más a nuestros servidores".

Depado
fuente