Resumen
Kiro IDE, de AWS, guardaba las credenciales de sesión del usuario en disco sin restringir quién podía leerlas. En la versión 0.11.107, al iniciar sesión (con GitHub o con AWS Builder ID), el IDE escribía un JSON con el access token y el refresh token en:
~/.aws/sso/cache/kiro-auth-token.json
El fichero quedaba con permisos 0644 (-rw-r--r--): legible por cualquier usuario del sistema y por cualquier proceso local. Es un caso de permisos por defecto incorrectos (CWE-276), registrado como CVE-2026-11931, con severidad media.
Lo llamativo es el contraste con el resto del ecosistema de AWS:
- La AWS CLI guarda sus tokens SSO en ese mismo directorio con permisos
0600. - El propio Kiro ya usaba el llavero del sistema (macOS Keychain, a través de
secretStoragede VS Code) para las credenciales OAuth de MCP. El patrón seguro existía en el código, pero no se aplicaba a este token.
La causa, según el investigador, está en la clase TokenStorage del extension.js minificado (línea 504375 en la build 672afb51e5336b149eb9fc381dd6db6908edbc61): llama a fs.writeFileSync() sin el parámetro mode. Node.js crea entonces el fichero con 0666, que la umask habitual (022) deja en 0644. Después no se aplicaba ningún chmod.
El investigador indicó que era uno de seis fallos que reportaba en Kiro IDE; los otros cubrían escalada de privilegios de extensión a agente (CWE-862), inyección de órdenes en hooks (CWE-78), un salto del modo Autopilot forzado mediante askAgent (CWE-862), la sobrescritura de la configuración MCP del espacio de trabajo (CWE-78/CWE-862) y una redirección del token mediante enlaces simbólicos (CWE-59).
Pasos de reproducción
- Iniciar sesión en Kiro de la forma habitual (con GitHub o con AWS Builder ID).
- Comprobar los permisos de los ficheros de la caché SSO (la sintaxis de
states la de macOS):
stat -f "%Op %Sp %N" ~/.aws/sso/cache/*.json
Los ficheros de la AWS CLI aparecen con 0600; el de Kiro, con 0644:
100600 -rw------- ~/.aws/sso/cache/REDACTED_HASH_1.json (AWS CLI - correct)
100600 -rw------- ~/.aws/sso/cache/REDACTED_HASH_2.json (AWS CLI - correct)
100644 -rw-r--r-- ~/.aws/sso/cache/kiro-auth-token.json (Kiro - world-readable)
- Leer el fichero y comprobar que las credenciales están en claro:
cat ~/.aws/sso/cache/kiro-auth-token.json
{
"accessToken": "[REDACTADO]",
"refreshToken": "[REDACTADO]",
"profileArn": "arn:aws:codewhisperer:us-east-1:[REDACTADO]:profile/[REDACTADO]",
"expiresAt": "2026-03-26T18:44:44.275Z",
"authMethod": "social",
"provider": "Github"
}
- Confirmar que el origen es el comportamiento por defecto de Node.js al escribir un fichero sin indicar
mode:
node -e "const fs=require('fs'); const p='/tmp/test.json'; fs.writeFileSync(p,'test'); console.log((fs.statSync(p).mode & 0o777).toString(8)); fs.unlinkSync(p);"
# Output: 644
Impacto
Quien leyera el fichero se llevaba unos tokens de portador que permiten actuar como la víctima ante la API de CodeWhisperer / Q Developer. El investigador enumera las operaciones de CodeWhispererRuntimeClient accesibles con ellos:
CreateSession, SendMessage, GenerateCompletions, ListAvailableModels,
GetUsageLimits, CreateSubscriptionToken, CreateArtifactUploadUrl
Con eso un atacante podía:
- Usar el chat agéntico completo y la generación de código haciéndose pasar por la víctima.
- Gastar sus créditos y agotar los límites del plan gratuito.
- Acceder al contexto de código de las sesiones de la víctima.
El vector más realista que plantea el informe es una extensión maliciosa o con nombre suplantado (typosquatting) para Kiro o VS Code: las extensiones se ejecutan con todos los permisos del usuario, así que podían leer el fichero y enviarlo fuera. El investigador añade que el host de extensiones de Kiro se ejecuta con los entitlements allow-unsigned-executable-memory y disable-library-validation. Los permisos 0644 exponen además el fichero a cualquier otro usuario o proceso de la misma máquina.
Remediación
El reporte figura como resuelto y se le asignó el CVE-2026-11931. El original no detalla el cambio aplicado por AWS. El investigador propuso dos opciones:
- Pasar
{ mode: 0o600 }afs.writeFileSync()al crear el fichero de tokens. - O bien guardar los tokens con
secretStoragede VS Code (llavero del sistema), como Kiro ya hacía con las credenciales OAuth de MCP.
Qué aprender de este caso
- Si auditas una herramienta de escritorio o una extensión, revisa los permisos de lo que deja en
~/.aws,~/.configo cachés parecidas tras iniciar sesión: unstatcomparando con los ficheros de otras herramientas (aquí la AWS CLI con0600) delata enseguida al que se sale de la norma. - En Node.js,
fs.writeFileSync()sinmodehereda laumasky suele acabar en0644. Busca en el código llamadas que escriban tokens o secretos sin{ mode: 0o600 }; y recuerda quemodesolo se aplica al crear el fichero, así que si ya existía con otros permisos conviene unchmodexplícito. - Cuando una misma aplicación guarda unos secretos en el llavero del sistema y otros en ficheros planos, el camino de los ficheros es el primero que merece revisarse: es donde suele faltar la protección.
- Un refresh token en disco tiene más valor para un atacante que un access token de vida corta: si no se puede llevar al llavero del sistema, que al menos solo lo pueda leer el usuario propietario.