Resumen
Las herramientas MCP del paquete faf-mcp aceptan un argumento path controlado por el llamador y lo resuelven (expansión de ~ más path.resolve()) directamente en operaciones de lectura y escritura sobre el sistema de archivos, sin confinarlo a un directorio de proyecto de confianza. Una ruta absoluta o una secuencia de traversal ../ se resuelve y se utiliza tal cual, de modo que el proceso servidor puede ser inducido a leer y, mediante las herramientas de archivo, a escribir ficheros fuera del contexto previsto del proyecto .faf. El único límite restante son los permisos del sistema operativo.
Herramientas afectadas
El punto de control compartido getProjectPath() (que alimenta las herramientas .faf) y las herramientas de propósito general faf_read y faf_write resolvían una ruta suministrada por el llamador directamente en una operación de lectura o escritura sin confinamiento real (solo lista de denegación). Una ruta absoluta seguía alcanzando secretos del directorio home, y faf_write podía escribir fuera del proyecto.
Impacto
Un cliente MCP, o un LLM al que se le haya inyectado un prompt malicioso a través de contenido controlado por un atacante (una página web, un README, un ticket o un fichero .faf), puede leer cualquier archivo que el proceso servidor tenga permiso para leer. Entre los archivos accesibles se encuentran:
- Claves SSH (
~/.ssh/id_rsa) - Credenciales cloud (
~/.aws/credentials) - Archivos
.envcon secretos de aplicación - Código fuente del proyecto
- Archivos del sistema como
/etc/passwd
Además, faf_write podría escribir fuera del proyecto, lo que abre la puerta a modificación de archivos de configuración o inyección de contenido malicioso en rutas arbitrarias del sistema.
Esta vulnerabilidad constituye una primitiva de divulgación de información sensible (CWE-200) que excede ampliamente el alcance declarado del contexto de proyecto .faf. El servidor opera sobre stdio, por lo que la lectura y escritura se alcanza mediante una llamada a herramienta manipulada, por ejemplo un agente con prompt injection procesando contenido controlado por el atacante.
Parches
Corregido en la versión 2.1.3 mediante el confinamiento de cada path suministrado por el llamador antes de cualquier acceso al sistema de archivos, implementado en safe-path.ts. Los cambios incluyen:
- Las lecturas quedan restringidas a los archivos de contexto
.fafy.fafm, de modo que los archivos fuera de ese contexto (secretos, credenciales) son rechazados independientemente del directorio. - Las operaciones generales de archivo (
faf_readyfaf_write) quedan confinadas a la raíz del proyecto (directorio de trabajo actual más directorio temporal del sistema; configurable mediante la variableFAF_ALLOWED_ROOTS). - Las rutas se canonizan a través de enlaces simbólicos, cerrando el bypass por symlink. Las rutas absolutas y las secuencias de escape
../son rechazadas. La funcióncallTool()incorpora una guardia central PATH-DENIED.
Para actualizar:
npm install -g faf-mcp@2.1.3
O bien mediante ejecución directa:
npx faf-mcp
Mitigaciones temporales
Si no es posible actualizar de inmediato, se recomienda ejecutar el servidor únicamente contra proyectos locales de confianza y configurar la variable FAF_ALLOWED_ROOTS (disponible en versiones parcheadas) apuntando a un único directorio de proyecto, estableciendo así un límite de directorio estricto.
Créditos
Vulnerabilidad identificada por los propios mantenedores del proyecto durante una auditoría de servidores relacionados, motivada por la divulgación coordinada de una clase de problema equivalente en grok-faf-mcp por parte de Zhihao Zhang (Worcester Polytechnic Institute).
