In this article
Ups, creé una función y provoqué una vulnerabilidad de redireccionamiento abierto en una aplicación de Deno
Vamos a configurar paso a paso una aplicación web sencilla de Deno con «Hello World», un entorno de ejecución cada vez más popular para JavaScript y TypeScript. En concreto.
Crearemos una aplicación web de Deno que admita un parámetro de consulta de redireccionamiento y aprenderemos cómo los desarrolladores pueden abrir brechas de seguridad sin querer cuando siguen planes de trabajo y desarrollan funciones.
Primeros pasos con un tutorial de código «Hello World» de Deno
Como requisito previo, asegúrate de tener acceso a un entorno de desarrollo web de Deno con las herramientas necesarias para ejecutar proyectos de Deno e interactuar con la aplicación web.
Sigue estos pasos para crear tu aplicación «Hello World» de Deno:
1. Instala Deno en tu entorno de desarrollo. Si aún no lo hiciste, puedes encontrar las instrucciones de instalación en el [sitio web oficial de Deno](https://deno.land/#installation).
2. Crea un proyecto de Deno. Para ello, crea un directorio y agrega un archivo deps.ts. Este archivo contendrá nuestras dependencias, aunque no tendremos ninguna porque se trata de una aplicación sencilla.
```bash
mkdir deno-hello-world
cd deno-hello-world
echo "" > deps.ts
```
3. Crea un archivo server.ts. Este archivo contendrá la lógica del servidor. Aquí importaremos la función serve del módulo std/http, configuraremos un servidor y esperaremos solicitudes entrantes.
4. Agrega la lógica del servidor. En el archivo server.ts, agrega el siguiente código:
```typescript
import { serve } from "https://deno.land/std/http/server.ts";
const httpHandler = async (request: Request): Promise<Response> => {
let bodyContent = 'Hello World';
return new Response(bodyContent, {
status: 200,
headers: {
"content-type": "text/html"
}
})
};
serve(httpHandler, { hostname: "0.0.0.0", port: 8080 });
console.log("HTTP server is running on http://localhost:8080/");
```5. Ejecuta el servidor. Guarda el archivo server.ts e inicia el servidor con el siguiente comando en la terminal:
```bash
deno run --allow-net server.ts
```
¡Eso es todo! Ya tienes una aplicación web sencilla de Deno que muestra «Hello World!»
Redireccionamiento de solicitudes en una aplicación de Deno
Actualicemos el código funcional anterior para que admita un parámetro de consulta desde la ruta de índice principal / hacia una ruta /user que muestre los datos del usuario.
Primero, agrega la segunda ruta /user. Para no introducir dependencias ni frameworks web importantes, usaremos una comprobación condicional sencilla de la ruta solicitada.
Actualiza el código de httpHandler de la siguiente manera:
```typescript
const httpHandler = async (request: Request): Promise<Response> => {
let bodyContent = 'Hello World';
const requestURL = new URL(request.url);
if (requestURL.pathname === "/user") {
bodyContent = `
<h1> User: admin </h1>
<ul>
<li> Name: Roberto </li>
<li> Email: roberto@example.com </li>
</ul>
`
return new Response(bodyContent, {
status: 200,
headers: {
"content-type": "text/html"
}
})
} else {
return new Response(bodyContent, {
status: 200,
headers: {
"content-type": "text/html"
}
})
}
};
```
Ahora podemos implementar una función de redireccionamiento para que, cuando se envíen solicitudes a /?redirect=/user, nuestra aplicación web analice el parámetro de consulta redirect y redirija la solicitud a la página que gestiona los detalles del usuario.
Al principio de nuestra función httpHandler, ampliemos la variable requestURL para incluir también una comprobación condicional del parámetro de consulta de redireccionamiento y actuar en consecuencia, respondiendo con una respuesta HTTP que incluya un encabezado de redireccionamiento Location:
```js
const requestURL = new URL(request.url);
const redirectTo = requestURL.searchParams.get('redirect');
if (redirectTo) {
return new Response(null, {
status: 302,
headers: {
'location': redirectTo
}
})
}
```Para comprobar que la función de redireccionamiento funciona según lo previsto, redirige a la página de detalles del usuario desde la página de índice principal solicitando la página: /?redirect=/user. Así funciona con curl:
```bash
@lirantal ➜ /workspaces/deno-open-redirect-vulnerability-blog-post (main) $ curl "http://localhost:8080/?redirect=/user" -vv
v
* Trying ::1:8080...
* connect to ::1 port 8080 failed: Connection refused
* Trying 127.0.0.1:8080...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET /?redirect=/user HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.74.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 302 Found
< location: /user
< vary: Accept-Encoding
< content-length: 0
< date: Mon, 06 Nov 2023 14:19:36 GMT
<
* Connection #0 to host localhost left intact
```¿Todo listo para llevarlo a producción?
Quizás quieras echar un vistazo más de cerca…
Vulnerabilidad de seguridad de redireccionamiento abierto en una aplicación de Deno
Una vulnerabilidad de redireccionamiento abierto, también conocida como redireccionamiento y reenvío no validados, es un defecto de seguridad importante que se encuentra con frecuencia en las aplicaciones web. Puede provocar problemas graves de ciberseguridad, como ataques de phishing, robo de credenciales y distribución de contenido malicioso.
Te recomiendo visitar la lección de Snyk Learn sobre redireccionamientos abiertos para conocer más detalles y buenas prácticas de codificación segura en JavaScript y otros lenguajes, como Java y Python.
¿Qué es una vulnerabilidad de redireccionamiento abierto?
Una vulnerabilidad de redireccionamiento abierto ocurre cuando una aplicación toma un parámetro y redirige a un usuario al valor del parámetro sin validarlo. Esta vulnerabilidad puede permitir que un atacante redirija a las víctimas desde el sitio web original a un sitio malicioso de su elección. Este es un ejemplo sencillo de cómo podría verse un redireccionamiento abierto en una aplicación de Node.js:
```javascript
app.get('/dashboard, function(req, res){
var redirect = req.query.redirect;
res.redirect(redirect);
});
```
En un proyecto de Deno, se ve de forma similar:
```javascript
const httpHandler = async (request: Request): Promise<Response> => {
const requestURL = new URL(request.url);
const redirectTo = requestURL.searchParams.get('redirect');
if (redirectTo) {
return new Response(null, {
status: 302,
headers: {
'location': redirectTo
}
})
}
});
serve(httpHandler);
```En el código anterior, la aplicación redirige al usuario a la URL del parámetro de consulta redirect. Un atacante podría aprovecharse de esto proporcionando una URL maliciosa como destino y redirigiendo al usuario a un sitio no deseado.
Si necesitas un ejemplo completo y funcional del código de la aplicación de Deno que preparamos, lo encontrarás aquí: https://github.com/snyk-snippets/deno-open-redirect-vulnerability-blog-post
Cómo explotar una vulnerabilidad de redireccionamiento abierto
En nuestra sencilla aplicación web de Deno, un usuario malicioso podría aprovechar la función de redireccionamiento creando un enlace como este:
```
https://example.com/?dummyParameter1=value1&dummyParameter2=value2&redirect=https://attacker.com/
```El uso de un parámetro de consulta ficticio, como dummyParameter1, no afecta el código de la aplicación de Deno, pero genera una URL más larga, lo que dificulta que los usuarios noten el parámetro de redireccionamiento y que su valor es una señal de alerta.
Además, los usuarios maliciosos pueden ocultar sus intenciones mediante servicios para acortar URL. Es probable que los usuarios desprevenidos no expandan la URL para averiguar a qué dirección los redirige.
Cómo puede Snyk detectar una vulnerabilidad de redireccionamiento abierto en tu aplicación web de Deno
Snyk es una potente herramienta de seguridad diseñada para desarrolladores que puede ayudar a identificar y corregir vulnerabilidades en tu base de código y en dependencias de código abierto. Es especialmente útil para detectar debilidades de seguridad, como las vulnerabilidades de redireccionamiento abierto.
Actualmente, Snyk admite proyectos de TypeScript y Node.js, pero no específicamente de Deno. Dicho esto, si desarrollas aplicaciones con JavaScript, deberías analizar tanto el archivo package.json en busca de dependencias de código abierto vulnerables como tu propio código JavaScript, que podría introducir problemas de seguridad, como esta vulnerabilidad de redireccionamiento abierto.
Para detectar una vulnerabilidad de redireccionamiento abierto en una aplicación de JavaScript con Snyk, debes integrar Snyk en tu flujo de desarrollo e implementación. Para ello, instala Snyk CLI y ejecuta Snyk test en tu aplicación de JavaScript, TypeScript o Node.js. Este es un ejemplo:
1. Instala Snyk CLI de forma global:
```bash
npm install -g snyk
```2. Ejecuta Snyk test en el directorio de tu aplicación:
```bash
snyk code test
```Snyk analizará el código de tu aplicación y reportará las vulnerabilidades que encuentre, incluidas las de redireccionamiento abierto. También ofrece información detallada sobre cómo corregirlas, por lo que es una herramienta esencial para mantener la seguridad de una aplicación.

De hecho, Snyk puede detectar vulnerabilidades de código inseguro directamente en el IDE mientras escribes. En el siguiente código de una aplicación web de Node.js, escrito con la biblioteca Express y con un middleware de controlador para redirigir al usuario después de que inicia sesión como administrador, podemos ver que Snyk detecta varias vulnerabilidades de seguridad, incluida una de redireccionamiento abierto.
En el panel derecho, puedes ver la información que Snyk proporciona sobre la vulnerabilidad de redireccionamiento abierto:
Explica cómo los datos de entrada sin sanear fluyen entre distintos archivos y rutas de código, y detalla la línea de código específica que es vulnerable.
Incluye un enlace para aprender sobre esta vulnerabilidad de redireccionamiento abierto (¡encuentra la lección de Snyk aquí!)
Ofrece varios ejemplos de código que muestran cómo se corrigió esta vulnerabilidad de redireccionamiento abierto en otros proyectos de código abierto, junto con la diferencia de código correspondiente.

Recuerda: siempre es mejor prevenir que curar, sobre todo en ciberseguridad. Si comprendes la vulnerabilidad de redireccionamiento abierto y usas herramientas como Snyk, puedes asegurarte de que tus aplicaciones web sigan siendo seguras y confiables.
Configuración del contenedor de desarrollo de Deno
En esta sección, veremos la configuración del contenedor de desarrollo de Deno en GitHub Codespaces. Esto implica modificar configuraciones específicas, como postCreateCommand y forwardedPorts, en el archivo devcontainer.json. A lo largo de la sección, compartiremos ejemplos prácticos y sugerencias para ayudarte a configurar una aplicación web de Deno funcional en tu entorno de desarrollo.
Usar la configuración postCreateCommand de un Dev Container
postCreateCommand en el archivo devcontainer.json es un comando o una serie de comandos que se ejecutan después de crear e iniciar el contenedor de desarrollo. Esta configuración es importante porque te permite automatizar tareas que normalmente realizas de forma manual cada vez que inicias el contenedor.
Por ejemplo, podrías usar postCreateCommand para instalar las dependencias del proyecto, compilarlo o iniciar el servidor de la aplicación.
En un proyecto de Deno, puedes usar postCreateCommand para iniciar automáticamente la aplicación web dentro del contenedor de desarrollo. Este es un ejemplo de cómo podría verse la configuración de postCreateCommand:
```json
{
"postCreateCommand": "deno run --allow-net server.ts"
}
```Configuración de puertos reenviados en Deno
Como no se trata solo de un programa de línea de comandos de Deno, sino de una aplicación web propiamente dicha, debemos exponer los puertos en los que el contenedor de desarrollo recibe solicitudes para que el entorno anfitrión pueda acceder a ellos. Para eso sirve la configuración de puertos reenviados de un Dev Container.
La configuración forwardedPorts del archivo devcontainer.json especifica qué puertos del contenedor deben exponerse a la máquina anfitriona.
Por ejemplo, la aplicación web de Deno descrita en este artículo escucha en el puerto 8080, así que debemos reenviar ese puerto a la máquina anfitriona mediante la configuración forwardedPorts.
Para configurar un puerto reenviado para tu aplicación web de Deno, agrega la configuración forwardedPorts al archivo devcontainer.json. Este es un ejemplo:
```json
{
"forwardedPorts": [8080]
}
```Ahora, tu aplicación web de Deno se ejecuta en el puerto 8080 del contenedor y puedes acceder a ella en http://localhost:8080 desde la máquina anfitriona. Recuerda que, si ejecutas esto en un entorno de nube remoto como GitHub Codespaces, tendrás que acceder mediante la URL del Codespace, por ejemplo: https://orange-invention-pe8918638bd1nf81-8080.app.github.dev/
¿Qué sigue?
Aprendimos sobre Deno y los Dev Containers, y, lo más importante, sobre cómo evitar introducir una vulnerabilidad de seguridad al desarrollar una función. ¡Uf, fue mucho!
Puedes encontrar el código completo y funcional de este artículo en el repositorio de código Snyk Snippets en GitHub: https://github.com/snyk-snippets/deno-open-redirect-vulnerability-blog-post
Empieza a usar Snyk gratis
No necesitas tarjeta de crédito.
Crea una cuenta con Bitbucket y más opciones
Al usar Snyk, aceptas cumplir nuestras políticas, incluidos nuestros Términos del servicio y nuestra Política de privacidad.