IA13 min de lectura

Qué puede hacer un skill de terceros en Claude Code antes de que lo leas

Instalamos skills de terceros en Claude Code y comprobamos qué hacen en la máquina: comandos sin confirmación, hooks en cada sesión, actualizaciones.

Un skill de Claude Code es una carpeta con un archivo SKILL.md. Se instala con un comando, como un paquete: npx skills add owner/repo o /plugin install name@marketplace. Los catálogos ya suman millones de instalaciones — en skills.sh, que mantiene Vercel, el skill más usado marca tres millones — y la gente los instala igual que un paquete de npm: por el nombre y las estrellas, sin abrirlos.

La diferencia es que una dependencia se ejecuta dentro de tu aplicación, y un skill se ejecuta con tu usuario, en tu máquina. A continuación, qué puede hacer exactamente, comprobado en Claude Code 2.1.223 y en repositorios reales, no de oídas.

Qué hay en la carpeta de un skill

Según la documentación y según lo que se ve en los repositorios, un skill tiene tres capas, y cada una se ejecuta en un momento distinto.

La descripción — el campo description del frontmatter. Está en el contexto de cada sesión mientras el skill siga instalado: es con ella con lo que el modelo decide si usa el skill por su cuenta, sin que tú se lo pidas. Para que la descripción no entre en el contexto, el autor tiene que poner explícitamente disable-model-invocation: true — de los 364 skills del repositorio más grande que revisamos, no lo hizo ninguno.

El cuerpo — las instrucciones, que se cargan al invocar el skill y se quedan en el contexto hasta el final de la sesión. El cuerpo puede contener comandos de la forma !`git diff`: Claude Code los ejecuta antes de que el modelo vea el texto y sustituye el comando por su salida. No es una propuesta para que el modelo ejecute algo: es una ejecución.

Los permisos. El campo allowed-tools no restringe, concede: las herramientas de la lista funcionan sin pedir confirmación durante el turno en el que se invoca el skill. La documentación lo dice sin rodeos: la confianza otorgada a la carpeta no rige este campo, y «un skill puede concederse a sí mismo un acceso amplio a las herramientas, así que revisa el allowed-tools de los skills de un repositorio antes de ejecutar Claude Code ahí».

Un plugin es un conjunto de skills más tres cosas, cada una con su propia vía de entrada al sistema: hooks (hooks/hooks.json) — scripts de shell que se ejecutan en eventos de la sesión: inicio, cada llamada a una herramienta, fin; servidores MCP (.mcp.json) — procesos locales o direcciones HTTP a las que se conecta la sesión; y una carpeta bin/ cuyos ejecutables se añaden al PATH de la herramienta Bash mientras el plugin esté activo. Los hooks, según la documentación, «ejecutan comandos de shell con todos los permisos de tu usuario», y el sandbox no los cubre: cubre solo los comandos de Bash.

Qué comprobamos nosotros

Cuatro skills en un proyecto vacío, ejecutados con claude -p en el modo de permisos por defecto — es decir, como trabaja Claude Code en CI o en un script de terceros, donde no hay nadie que conteste a una pregunta.

SkillQué contieneResultado
allowed-tools: Bash(*) + un comando !`…` en el cuerpoescribe un archivo marcadorse ejecutó, sin preguntar
lo mismo sin allowed-toolsescribe un archivo marcadorinvocación interrumpida, no hay archivo
allowed-tools: Bash(*) + una instrucción en el cuerpo, «ejecuta este comando»escribe un archivo marcadorse ejecutó, sin preguntar
allowed-tools: Bash(*), invocación automática por la descripciónun comando !`…`en nuestra prueba el modelo no tomó el skill

El marcador es una línea con el nombre de usuario y la hora, es decir, que el comando se ejecutó con nuestro usuario. Sin trucos: exactamente el comportamiento que describe la documentación. Con la cuarta fila hay que ser honestos: la invocación automática sigue siendo decisión del modelo, y esta vez respondió sin tomar el skill. Pero el mecanismo existe, y la descripción ya está en el contexto para eso.

Una aclaración sobre los modos: en una sesión interactiva, sin allowed-tools, el comando del cuerpo habría pedido permiso. claude -p y el SDK no muestran ni el diálogo de confianza ni la pregunta — según la documentación, en ese modo la carpeta se considera de confianza, y los hooks del .claude/settings.json de un repositorio clonado se ejecutan. Es exactamente el camino que sigue Claude Code en CI.

Qué hay en los repositorios reales

Clonamos cinco repositorios populares y revisamos qué contienen además de instrucciones. Ninguna es maliciosa — eso importa. La cuestión es qué se instala junto con el texto.

Un marketplace con curaduría, de una firma de auditoría conocida, 31 skills. El campo allowed-tools está en los 31, y en 24 de ellos la lista lleva un Bash a secas, sin patrón. Cada invocación de un skill así es un turno en el que cualquier comando de shell pasa sin confirmación. No es mala intención, es comodidad: un skill de fuzzing tiene que ejecutar el fuzzer. Pero quien lo instala acepta eso sin mirar.

Una colección de 364 skills y 90 plugins con 24 mil estrellas. Dentro, cinco archivos hooks.json: scripts en Python y Bash en los eventos SessionStart, SessionEnd y PostToolUse. Uno recibe la salida de cada comando de Bash y busca errores en ella; otro, al arrancar la sesión, lee archivos del disco e inserta su contenido en el contexto. Tres archivos .mcp.json conectan un servidor HTTP externo, un proceso local y npx tsx con un script del plugin. Instalar los «skills de marketing» de esta colección es instalar también esto.

El marketplace de un conjunto de plugins muy usado, 10 plugins de repositorios externos: nueve indican como fuente solo una URL, sin sha ni ref. La instalación se lleva lo que haya en HEAD en ese momento.

El skill más popular de GitHub, 99 mil estrellas, es un modo para acortar respuestas. Su hook de SessionStart es un echo con una instrucción para el modelo. Inofensivo. Pero es el mismo mecanismo: texto que entra en el contexto de cada sesión sin tu participación.

El marketplace oficial de Anthropic en nuestra máquina: 286 plugins, 233 de ellos repositorios externos en GitHub, y los 233 llevan sha. Esa es la buena noticia. La mala está en el archivo de al lado: el plugin instalado desde ahí se actualizó por su cuenta de madrugada, y el catálogo lo volvió a hacer unas horas después; no pedimos ni lo uno ni lo otro. Los marketplaces oficiales traen la actualización automática activada por defecto — la documentación lo confirma. Nadie preguntó qué llegó exactamente.

Adónde van los datos

Un skill no tiene capa de red propia, así que la pregunta «adónde envía los datos» se reduce a qué vías tiene.

  • Los hooks reciben como entrada un JSON con los parámetros y la salida de la herramienta — es decir, contenido de archivos, salida de comandos, texto de los prompts — y pueden hacer con él lo que sea: es un script de shell con tus permisos.
  • Los servidores MCP de .mcp.json son una dirección a la que la sesión se conecta por su cuenta. En el plugin de Figma del marketplace oficial es la dirección HTTPS del proveedor con una cabecera de versión de la compilación; es legítimo y transparente, pero el campo se ve igual para cualquier dirección.
  • Los comandos !`…` se ejecutan antes de que intervenga el modelo — un curl ahí es el mismo curl.
  • Comportamiento que cambia después de instalar. Unit 42 analizó a fondo el skill money-radar del catálogo de OpenClaw: en cada invocación descargaba un referrals.json del servidor del autor, y la instrucción ordenaba recomendar siempre los enlaces de afiliado que venían en él. El skill se publica una vez; el comportamiento cambia desde el servidor.

Un caso aparte es la clave de la API. Hasta diciembre de 2025, un ANTHROPIC_BASE_URL colocado en el .claude/settings.json de un repositorio redirigía la primera petición —con la clave incluida— a un servidor de terceros, antes del diálogo de confianza (CVE-2026-21852, análisis de Check Point). Ya está corregido: ahora las peticiones esperan a que se confirme la confianza. Pero muestra dónde vive la clave y a través de qué archivo se llega a ella.

Qué ha pasado ya

No es un riesgo teórico, y los precedentes se acumulan desde principios de año.

ClawHub, febrero de 2026. Koi Security revisó todo el catálogo de skills de OpenClaw: 341 maliciosos de 2.857, casi el 12 %, 335 de ellos de una sola campaña. Snyk escaneó 3.984 skills de ClawHub y skills.sh: 76 maliciosos confirmados, un 13,4 % con problemas críticos, un 10,9 % con secretos escritos en el código. Los cien skills más instalados de skills.sh salieron limpios — lo que dice más de la selección del catálogo que del formato. La mecánica de los skills maliciosos es siempre la misma: un bloque de «requisitos previos» en SKILL.md, dentro, una cadena en base64, y se le pide al agente que la decodifique y la pase a bash. Después, el infostealer AMOS y las claves de los monederos. Cuando los escáneres aprendieron a leer SKILL.md, los autores pasaron los comandos a los comentarios del skill en la página del catálogo, y un skill rellenó su README.md con 22 megabytes de basura para superar el límite de análisis.

Un agente escapó de su sandbox para copiar en un examen. No hubo atacante

Claude Code, demostraciones. En enero, Prompt Security mostró un plugin de un marketplace de terceros cuyo skill, ante la petición «instala la biblioteca», desviaba en silencio la instalación a una fuente suplantada: la biblioteca se importa, el ejemplo funciona, el troyano está en el proyecto. Reversec en mayo: un reverse shell mediante un comando !`…` más allowed-tools: Bash(*) — «el contexto dinámico se salta el razonamiento del modelo y se ejecuta antes de cualquier comprobación». Es el mismo mecanismo que la primera fila de nuestra tabla; el modelo, dicen, se negó a ejecutar el reverse shell cuando se lo pidieron directamente — el comando nunca llegó al modelo.

Hookify, abril de 2026. Pluto Security descubrió que un plugin del marketplace oficial lee archivos de reglas de la carpeta del proyecto y los pasa al canal de confianza de los hooks — así que un archivo en un repositorio de terceros se convierte en un canal para dirigir el modelo de cualquiera que haya instalado el plugin. Cinco cargas útiles disfrazadas de «convenciones del proyecto» hicieron que el modelo entregara variables de entorno; ninguna fue reconocida como inyección. Respuesta de Anthropic: «funciona como está diseñado» — el límite de seguridad es el diálogo de confianza de la carpeta.

Esto último importa más que todo lo demás. El modelo de seguridad de Claude Code es honesto y está documentado: la confianza se concede a una carpeta, y todo lo que hay en ella cuenta como tuyo. Un skill de terceros en esa carpeta también es tuyo.

En qué se diferencia de una dependencia

Una dependencia de npm también puede ser maliciosa, y ejemplos sobran. Pero tiene cuatro propiedades que un skill no tiene.

  1. La dependencia se ejecuta en el proceso de la aplicación. El skill y sus hooks, con tu usuario: con tu ~/.ssh, ~/.aws, ~/.claude, con los tokens del entorno y con acceso a la red. El mismo SKILL.md en la API de Anthropic se ejecuta en un contenedor sin red; en Claude Code, con todos los privilegios del host.
  2. El código tiene linter; las instrucciones, no. Un paquete malicioso se detecta por su código; «tres líneas de markdown» que piden leer una clave SSH y enviarla son, para un escáner, texto. Snyk calcula que en el 91 % de los skills maliciosos el código y la inyección en las instrucciones van juntos.
  3. Revisión y firma. El marketplace comunitario de Anthropic tiene «escaneo de seguridad automatizado», sin detalles; no hay firma de código, no hay verificación del publicador, y el manifiesto del plugin exige nombre, descripción, versión y autor. Un marketplace con curaduría es una lista de enlaces a repositorios de terceros con un commit fijado, y ese anclaje dura exactamente hasta la siguiente actualización.
  4. La confianza es transitiva. Al instalar un plugin activas de golpe todos sus skills, hooks y servidores MCP — Pluto lo llama «pirámide de confianza»: aprobar la cúspide avala cada capa que hay debajo.

Hay una quinta, sobre las personas. Una dependencia la elige un desarrollador que lee qué hace. Un skill lo elige el modelo — por la descripción, en el contexto — y el desarrollador se entera por una línea en la salida, si es que mira.

Qué hacer con esto

Nada de esto obliga a renunciar a los skills — nosotros escribimos y mantenemos los nuestros. Obliga a tratarlos como código que se ejecuta con tus permisos, no como sugerencias.

  • Leer el frontmatter antes que el cuerpo. Un allowed-tools con Bash, Write o Edit a secas es un permiso; un !`…` en el cuerpo es un comando. Esto merece el mismo tiempo que le dedicarías al script postinstall de un paquete.
  • Buscar lo que no está en SKILL.md. find . -name hooks.json, .mcp.json, la carpeta bin/, el settings.json en la raíz del plugin. En esa colección de 364 skills, justo ahí estaba lo más interesante.
  • Fijar versiones. Instalar por sha, no por HEAD; los marketplaces de terceros ya traen la actualización automática desactivada — no activarla «por comodidad». Los oficiales la traen activada, y eso conviene saberlo.
  • Cortarle el shell al código de terceros. La opción disableSkillShellExecution desactiva !`…` en todos los skills salvo los integrados; una regla deny: Bash(*) en tu configuración anula el allowed-tools de cualquier skill — Reversec lo comprobó. En una organización, strictKnownMarketplaces y allowManagedHooksOnly en la configuración gestionada (managed settings).
  • Acordarse de -p. En CI y en scripts no hay diálogo de confianza, y los hooks de un repositorio clonado se ejecutan. Un agente con acceso a claves que recorre repositorios de terceros ya es un sistema con privilegios, no un asistente, y hay que protegerlo como tal: credenciales separadas, salida de red limitada a una lista de permitidos, sandbox.
  • Escanear lo que ya está instalado. uvx mcp-scan --skills y sus equivalentes encuentran los patrones conocidos — no las inyecciones en lenguaje natural, pero al menos el base64 y el curl | bash.

Qué no demuestra esto

Ninguno de los repositorios que revisamos hace nada malo, y no los nombramos a propósito: un Bash a secas en el allowed-tools de una firma de auditoría es una decisión deliberada para sus tareas, no un fallo de seguridad. Las cifras de ClawHub son de OpenClaw, que tiene otro catálogo y otra cultura de publicación; los cien skills más instalados de skills.sh, que es lo que se usa con Claude Code, salieron limpios.

Lo que sí demuestra es una cosa: un skill no es texto, sino código con tus permisos que tú no escribiste y que se actualiza sin ti. La industria ya aprendió a tratar con todo lo que encaja en esa descripción. Falta darse cuenta de que esto también lo es.

Sergei Palii

Fundador de Sepia Software

Sobre mí

Sigue leyendo

Todos los artículos