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.
| Skill | Qué contiene | Resultado |
|---|---|---|
allowed-tools: Bash(*) + un comando !`…` en el cuerpo | escribe un archivo marcador | se ejecutó, sin preguntar |
lo mismo sin allowed-tools | escribe un archivo marcador | invocación interrumpida, no hay archivo |
allowed-tools: Bash(*) + una instrucción en el cuerpo, «ejecuta este comando» | escribe un archivo marcador | se ejecutó, sin preguntar |
allowed-tools: Bash(*), invocación automática por la descripción | un 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.jsonson 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 — uncurlahí es el mismocurl. - Comportamiento que cambia después de instalar. Unit 42 analizó a fondo
el skill
money-radardel catálogo de OpenClaw: en cada invocación descargaba unreferrals.jsondel 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.
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.
- 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 mismoSKILL.mden la API de Anthropic se ejecuta en un contenedor sin red; en Claude Code, con todos los privilegios del host. - 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.
- 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.
- 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-toolsconBash,WriteoEdita secas es un permiso; un!`…`en el cuerpo es un comando. Esto merece el mismo tiempo que le dedicarías al scriptpostinstallde un paquete. - Buscar lo que no está en
SKILL.md.find . -name hooks.json,.mcp.json, la carpetabin/, elsettings.jsonen 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 porHEAD; 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
disableSkillShellExecutiondesactiva!`…`en todos los skills salvo los integrados; una regladeny: Bash(*)en tu configuración anula elallowed-toolsde cualquier skill — Reversec lo comprobó. En una organización,strictKnownMarketplacesyallowManagedHooksOnlyen 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 --skillsy sus equivalentes encuentran los patrones conocidos — no las inyecciones en lenguaje natural, pero al menos el base64 y elcurl | 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.
Sigue leyendo
Un agente escapó de su sandbox para copiar en un examen. No hubo atacante
Los modelos de OpenAI escaparon del entorno de pruebas y entraron en Hugging Face por las respuestas. Sin atacante ni inyección de prompts, solo optimización.
Los costes de un LLM no escalan como dice tu intuición
Una función que cuesta céntimos en una demo puede costar miles al mes en producción, y rara vez por el precio por token. Adónde va el dinero de verdad.
Infra Graveyard Weekly #04: a DFK Chain le quedan cuatro días y el dinero sigue ahí
Medimos la misma red moribunda dos veces, con ocho días de diferencia: la liquidez sigue ahí, el 84 % dentro de dos contratos que la wallet no muestra.