Hay que admitir en cuanto a las librerías Javascript más populares que en su historia de desarrollo (9, 6 y 5 años para Angular, React y Vue, respectivamente), han pasado muchas cosas buenas en términos de seguridad, especialmente relacionadas con la vulnerabilidad para ataques XSS. Sin embargo, este artículo tratará sobre las pequeñas trampas y principios que los desarrolladores aún deben tener en cuenta.
XSS
Vivimos en la era de los frameworks, no de los lenguajes. Esto implica que los programadores deberían poder preocuparse menos por muchos aspectos del desarrollo, incluida la seguridad. La mayoría de los frameworks backend actuales implementan módulos de seguridad, que están siendo probados por empresas externas especializadas y grandes sociedades. Por lo tanto, menor concienciación en materia de seguridad podría ser evidente, por ejemplo entre los jóvenes programadores, que asumen más responsabilidad sobre los productos, especialmente en lo que se refiere al trabajo autónomo.
Uno de los ataques más comunes en el lado del cliente de la aplicación es el XSS (Cross-Site Scripting). Se realiza inyectando scripts ejecutables del lado del cliente en aplicaciones web [1] y utiliza métodos de renderizado HTML implementados o Javascript código evaluadores que lo ejecutan. El XSS es relativamente lucrativo, ya que se pueden recopilar muchos datos diferentes, incluidas las cookies de sesión o los datos de usuario, y puede instalar una aplicación de seguimiento como un keylogger, lo que lo hace peligroso tanto para los usuarios como para los propietarios de empresas. A veces, se realizan otras formas de ataque para permitir el XSS en la página, tales como Inyección SQL.
Ejemplo
El formulario de inicio de sesión de la página muestra el parámetro loginName enviado dentro de la solicitud GET en la entrada del nombre de inicio de sesión. El valor no es procesado ni por el servidor ni por el lado del cliente de la aplicación. Al solicitarlo: http://localhost:8080/login?name=<script>alert(document.cookies)</script>
se ejecuta el código y se exponen los datos
Este es un ejemplo de ataque XSS reflejado, en el que se inyectan scripts a través de una dirección URL especialmente preparada que se envía a la víctima y que se refleja en la respuesta del servidor. Otras formas populares conocidas de ataques son las siguientes:
- XSS almacenado se realiza con datos inyectados almacenados en el lado del servidor, normalmente mediante formularios disponibles en la aplicación. La aplicación cliente renderiza código almacenado, por ejemplo, en una base de datos.
- DOM XSS realiza un ataque XSS sin utilizar el lado del servidor. En la siguiente parte del artículo, nos centraremos en esta forma de ataque.
Vulnerabilidades actuales en las bibliotecas React y Vue
Para las versiones actuales React/Vue, se han detectado dos problemas importantes que aún no se han solucionado oficialmente. La primera vulnerabilidad tiene la misma naturaleza para todos los frameworks y está relacionada con los métodos que permiten renderizar HTML sin formato dentro de las plantillas: v-html y peligrosamenteSetInnerHTML, respectivamente, para Vue y React. Cada documentación [2] informa a los lectores de que un uso imprudente puede exponer a los usuarios a un ataque XSS. Si no hay otras opciones para resolver el problema, asegúrese de que los datos son filtrado y escapó. Aunque son peligrosos, no debe esperar que esos métodos sean fijos. Utilícelos bajo su propia responsabilidad.
En el primer trimestre de 2018, se detectó un gran error en React, que permitía la ejecución directa de código estableciendo la propiedad para el elemento de etiqueta. Pasar código de ejemplo dentro de atributos, como javascript:alert(1)
y ejecutar un enlace renderizado ejecutará el código. Este problema [4] sigue abierto y no se ha preparado ni fusionado ninguna solución, así que asegúrate de que tu código es seguro. Los ejemplos propuestos en la discusión oficial sugieren algunas formas de superar este problema.
Si no es posible actualizar a las últimas versiones, asegúrese de que los problemas antiguos no le causen problemas asegurándose de que su código no está expuesto para:
- niño nodo inyección - React, uso de React.createElement [5]
- renderizado en el servidor - React/Vue [6]
- Inyección de CSS [8]
Sigue tratándose de Javascript. Sigue tratándose de front-end
No olvide que además de los propios frameworks o librerías, Javascript como lenguaje tiene algunas funciones peligrosas, que deben evitarse o utilizarse con precaución. Generalmente están relacionadas con la manipulación del DOM o la ejecución de scripts. eval() representa funciones insignia de este tipo y es extremadamente peligrosa porque ejecuta directamente el código stringificado dado [9]. Además, fíjate mejor en tu código cuando encuentres una de estas funciones:
- document.write
- document.writeln
- (elemento).innerHTML
- (elemento).outerHTML
- (elemento).insertAdjacentHTML
En este caso, el uso de linters con un conjunto de reglas adecuado puede ser útil para encontrar esos puntos vulnerables. También hay un montón de analizadores de código abiertos o comerciales que pueden ayudarle a detectar brechas de seguridad en el código desarrollado.
Independientemente de la biblioteca o el marco que elijamos, debemos recordar los principios básicos relacionados con el desarrollo front-end. En primer lugar, asegúrate siempre de que el código externo que inyectas procede de una fuente de confianza. Auditoría tus dependencias, y elígelas sabiamente. Algunas pueden contener vulnerabilidades serias, exponiendo tu código incluso si todo está bien con el código en sí. Puedes leer más sobre la seguridad de las dependencias aquí:
https://thecodest.co/blog/security-in-javascript-packages/
Entonces... ¿debería seguir preocupado?
Sí - y animo encarecidamente a todo el mundo a que nunca confíe en bibliotecas externas o en sí mismo en términos de seguridad. No importa lo seguro que esperes que sea tu software, siempre haz un esfuerzo por probarlo tanto como sea posible en términos de formas de ataque comunes [10].
- https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml
- https://vuejs.org/v2/guide/syntax.html#Raw-HTML
- https://github.com/facebook/react/issues/12441
- http://danlec.com/blog/xss-via-a-spoofed-react-element
- https://medium.com/node-security/the-most-common-xss-vulnerability-in-react-js-applications-2bdffbcc1fa0
- https://github.com/dotboris/vuejs-serverside-template-xss
- https://frontarm.com/james-k-nelson/how-can-i-use-css-in-js-securely/
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval#Do_not_ever_use_eval!
Más información:
5 errores que debe evitar al mantener un proyecto en PHP
PHP Desarrollo. Symfony Console Component - Trucos y consejos
Por qué necesitamos Symfony Polyfill (... y por qué no deberíamos)