Seguridad en Deno
-
Oliver Servín
Deno tiene un enfoque donde la seguridad está habilitada por defecto, siendo una alternativa más cautelosa que Node.js en cuanto a la ejecución de código en servidores y entornos de producción.
#Comparación con Node.js
En Node.js, el código ejecutado tiene acceso completo al sistema, incluyendo el sistema de archivos, la red y las variables de entorno. Esto significa que debemos confiar plenamente en el código que ejecutamos, porque cualquier fragmento de código malicioso podría comprometer el servidor debido a la falta de restricciones de seguridad.
En cambio, Deno bloquea el acceso a cualquier API sensible a menos que el usuario otorgue permisos explícitos. De esta manera, se garantiza que el acceso a recursos críticos sea limitado, dando una mayor protección contra vulnerabilidades.
#Concediendo Permisos
Cuando ejecutas un script con Deno, puedes otorgar permisos de forma explícita utilizando flags de permisos. Si el script intenta acceder al sistema de archivos, Deno pedirá autorización antes de proceder. Este control de seguridad es especialmente útil en entornos de producción, donde cada permiso otorgado debe ser intencional.
Considera el siguiente archivo main.ts
:
const decoder = new TextDecoder("utf-8"); // Intentamos leer un archivo 'example.txt'try { const content = Deno.readFileSync("example.txt"); console.log("Contenido del archivo:", decoder.decode(content));} catch (error) { console.error("Error al intentar leer el archivo:", error.message);}
Si ejecutas este script sin otorgar permisos de lectura al sistema de archivos, Deno mostrará un error:
deno run main.ts# PermissionDenied: Requires read access to "example.txt", run again with the --allow-read flag
Para conceder acceso de lectura al sistema de archivos, puedes utilizar la flag --allow-read
:
deno run --allow-read main.ts# Contenido del archivo: ¡Hola, Deno!
En esta ocasión, el script podrá leer el archivo example.txt
.
#Permisos Globales
En situaciones donde otorgar permisos de forma granular puede ser tedioso, como en entornos de desarrollo, puedes usar la flag -A
para conceder todos los permisos de forma global:
deno run -A maint.ts
Esto es comparable al comportamiento que por defecto tiene Node.js, donde no existen restricciones de permisos. Sin embargo, es recomendable limitar el uso de esta flag en entornos sensibles, como el de producción, ya que anula las protecciones del modelo de seguridad de Deno.
#Acceso Granular
El modelo de permisos de Deno también permite definir específicamente el acceso. Supongamos que estás trabajando con dos archivos: public.txt
, que es público, y secret.txt
, que contiene información confidencial. El objetivo es permitir que el script acceda únicamente al archivo público y evitar que tenga acceso al archivo secreto.
Definimos un archivo main.ts
con el siguiente contenido:
const decoder = new TextDecoder("utf-8"); // Intentamos leer los archivos 'public.txt' y 'secret.txt'try { const publicContent = Deno.readFileSync("public.txt"); console.log("Contenido de public.txt:", decoder.decode(publicContent));} catch (error) { console.error("[public.txt] Error al intentar leer el archivo:", error.message);} try { const secretContent = Deno.readFileSync("secret.txt"); console.log("Contenido de secret.txt:", decoder.decode(secretContent));} catch (error) { console.error("[secret.txt] Error al intentar leer el archivo:", error.message);}
Si usas la flag --allow-read
para otorgar permisos de lectura, Deno podrá acceder a ambos archivos. Esto podría exponer información confidencial.
Para restringir el acceso, podemos limitarlo solo al archivo público con la flag --allow-read
:
deno run --allow-read=public.txt main.ts# Contenido de public.txt: Información pública# [secret.txt] Error al intentar leer el archivo: PermissionDenied: Requires read access to "secret.txt".
Además, si deseas denegar explícitamente el acceso al archivo confidencial, puedes utilizar la flag --deny-read
:
deno run --allow-read=public.txt --deny-read=secret.txt main.ts# Contenido de public.txt: Información pública# [secreto.txt] Error al intentar leer el archivo: PermissionDenied: Requires read access to "secret.txt".
Con este nivel de control granular, proteges los datos sensibles limitando el acceso exclusivamente a los recursos necesarios para que funcione el script. Incluso si un atacante logra inyectar código malicioso, ese código no podrá solicitar más privilegios de los que ya se han configurado explícitamente al ejecutar el script.
El sistema de permisos de Deno es un modelo sólido de seguridad que, por defecto, restringe el acceso a recursos sensibles y permite al desarrollador otorgar explícitamente los permisos necesarios. Aunque esta concesión de permisos podría parecer tediosa, herramientas como las tareas de Deno permiten automatizar y simplificar su gestión, manteniendo el control sobre los recursos que los scripts pueden utilizar.