Google search engine
Inicio Noticias y Actualidad Seguridad y Legal Permisos de Claude Code: las reglas que no cubrían .env

Permisos de Claude Code: las reglas que no cubrían .env

0
36
Permisos de Claude Code

Si tienes una regla Read(.env) en tus ajustes de Claude Code para que el agente no pueda leer tus credenciales, hasta la versión 2.1.259 esa regla protegía menos de lo que parecía. No fallaba: es que solo se aplicaba cuando el fichero se pedía de la forma más obvia. Cambiando la manera de escribir el comando, el mismo fichero se leía sin que la regla interviniera.

Es la segunda tanda de correcciones de este tipo en tres días, y el patrón se repite: reglas que existían, estaban bien escritas y no cubrían todas las formas de pedir lo mismo.

Cuatro maneras de leer el mismo fichero, una sola bloqueada

Los huecos que cierra esta versión son concretos y conviene verlos escritos, porque ninguno es rebuscado. Las reglas Read() de Bash no se aplicaban cuando el fichero llegaba como valor de una opción —los ejemplos del changelog son --ignore-revs-file=.env, -f.env y @file—, ni cuando aparecía como operando de git diff o git grep, ni dentro de un compuesto del tipo cd DIR && cat FILE. Además, grep -r o cp -r sobre un directorio que contiene un fichero denegado pasaban de largo; ahora preguntan.

El caso del cd es el más fácil de encontrarse sin buscarlo. Claude Code trata como de solo lectura un conjunto de comandos —ls, cat, head, tail, grep, find, cd y las formas de git que no escriben, entre otros— y los ejecuta sin pedir aprobación en todos los modos. Un compuesto en el que cada parte califica por separado se ejecuta igual, sin diálogo. Ahí es donde cd config && cat .env se colaba: dos operaciones inocuas por separado que juntas hacían exactamente lo que la regla debía impedir.

El de git diff es más incómodo todavía, porque no hay que idear nada raro: pedirle a Claude que te enseñe qué ha cambiado en un fichero es la petición más normal del mundo, y si ese fichero era el que no debía leer, lo leía.

La regla solo cubre lo que Claude Code sabe reconocer

Aquí está lo que de verdad hay que entender, y no es un fallo sino el diseño del sistema. Las reglas Read y Edit se aplican a las herramientas de fichero propias de Claude y a los comandos de fichero que Claude Code reconoce dentro de Bash, como cat, head, tail o sed. La palabra clave es reconoce: hay un analizador que mira el texto del comando e intenta averiguar qué ficheros va a tocar.

De ahí que estos fallos aparezcan de tanto en tanto. Cada forma nueva de nombrar un fichero en la línea de comandos —pegado a una opción corta, después de un igual, detrayéndolo de un operando de git— es una forma que el analizador tiene que aprender a ver. La 2.1.259 le ha enseñado cuatro más.

Una regla de denegación no es una barrera del sistema: es un analizador intentando adivinar qué va a abrir tu comando.

Y la consecuencia está dicha con todas las letras en la documentación de Anthropic: estas reglas no se aplican a subprocesos arbitrarios que lean o escriban ficheros por su cuenta, como un script de Python o de Node que abra el fichero desde dentro. No hay analizador que valga ahí, porque el nombre del fichero no aparece en el comando. Si Claude ejecuta python procesa.py y ese script lee tu .env, ninguna regla Read lo impide.

⚠️ Dónde acaba la regla y dónde empieza el sandbox

Las reglas de permiso son una capa de intención: expresan qué no quieres que el agente haga y funcionan bien contra el error. Si lo que necesitas es una garantía a nivel de sistema operativo, que ningún proceso pueda tocar una ruta pase lo que pase, la herramienta es el sandbox, no la lista de denegación. La propia documentación remite ahí para ese caso.

Cómo se escribe una regla que cubra lo que crees que cubre

Ya que toca revisar, merece la pena hacerlo con las reglas de emparejamiento delante, porque tienen trampas de alcance. Los nombres de fichero sueltos siguen semántica de gitignore y coinciden a cualquier profundidad, así que Read(.env) y Read(**/.env) son equivalentes: bloquean cualquier .env en el directorio actual o por debajo. Lo que no bloquean es un .env en un directorio superior ni el de otro proyecto. Para cubrir todo el sistema de ficheros hace falta anclar en la raíz con Read(//**/.env).

En Windows, las rutas se normalizan a formato POSIX antes de compararse: C:\Users\alice se convierte en /c/Users/alice, de modo que la regla para cualquier .env de esa unidad es //c/**/.env, y //**/.env para todas las unidades. Es un detalle que hace fallar silenciosamente muchas reglas escritas con rutas de Windows.

Tres comportamientos más que conviene tener claros. El orden de evaluación es deny, luego ask, luego allow, y la primera coincidencia decide: una denegación amplia gana siempre a un permiso más específico, porque la especificidad no altera el orden. Una regla Read de denegación bloquea también las herramientas Edit y Write sobre esa ruta, incluida la creación de un fichero nuevo ahí, pero no cubre NotebookEdit, que necesita su propia regla Edit. Y con los enlaces simbólicos, la denegación se aplica si coincide el enlace o su destino, así que un symlink apuntando a un fichero denegado queda denegado también.

Un último apunte que salva disgustos: si escribes la regla de ruta para Write, NotebookEdit, Glob o MultiEdit, Claude Code la acepta pero no la consulta nunca, y avisa al arrancar. Las comprobaciones de fichero se hacen solo contra Read(ruta) y Edit(ruta). Es decir: usa Edit(docs/**) en lugar de Write(docs/**), y Read(docs/**) en lugar de Glob(docs/**).

Qué hacer hoy con esto

Para un freelance que abre Claude Code en repositorios de clientes, con ficheros de entorno, claves de API de pasarelas de pago y credenciales de bases de datos repartidos por ahí, la conclusión práctica es corta. Actualiza, porque los cuatro huecos son reales y ninguno requiere mala intención para dispararse: basta con pedir un git diff del fichero equivocado.

Revisa después el ancla de tus reglas. Si las tienes en ajustes de usuario esperando que apliquen dentro de cada proyecto, comprueba que usan una ruta absoluta con // o relativa al home con ~/: una regla como Read(/secrets/**) en ajustes de usuario bloquea ~/.claude/secrets/**, no el directorio secrets de tu proyecto. Es el error de alcance más común y no da ningún aviso.

Y sobre todo, coloca la expectativa donde corresponde. Estas reglas son excelentes contra el accidente y flojas contra la determinación: impiden que el agente lea por descuido algo que no debía, pero no son una frontera del sistema operativo. Para el trabajo en el que esa frontera importe de verdad —un repositorio ajeno, una plantilla descargada, código que no has revisado—, la respuesta es el sandbox, y la lista de denegación es el complemento, no el plan.

DEJA UNA RESPUESTA

Por favor ingrese su comentario!
Por favor ingrese su nombre aquí