
Escáner de solo lectura para ajustes de git que permiten que un repositorio ejecute código en agentes de codificación (Claude Code, Codex, Cursor, Copilot). Cubre la clase GitSpawn y CVE-2026-45033. Sin dependencias, sin red, sin telemetría.
Un repositorio que puede hacer que tu agente de codificación ejecute código en el momento en que abre la carpeta. GuardSkill lo comprueba antes de que lo hagas tú.
npx guardskill .
Solo lectura. Sin llamadas de red, sin telemetría, sin configuración, sin cuenta. Lee la configuración de git y los scripts de hooks, imprime lo que encuentra y termina.
Los agentes de codificación recopilan contexto ejecutando comandos git ordinarios — git status, git diff — tan pronto como abren un proyecto. Git lee sus ajustes del propio .git/config del repositorio, y varios de esos ajustes nombran un programa para que git lo ejecute. Pon un comando en core.fsmonitor y se ejecutará, con tus privilegios, fuera de cualquier sandbox, antes de que hayas escrito nada.
Dos investigaciones públicas hacen esto concreto:
.git/config.git ya dentro@github/copilot 1.0.43 al forzar safe.bareRepository=explicit. (GitHub Advisory)La mitigación recomendada del lado del usuario en ambos escritos es la misma: inspecciona la configuración de git antes de abrir el directorio con un agente. Eso es tedioso de hacer a mano en un árbol. Esta herramienta lo hace en un segundo.
GuardSkill recorre el árbol y encuentra toda configuración de git que un agente podría recoger: el .git propio del proyecto, cualquier .git anidado que haya llegado como contenido, cualquier repositorio bare oculto en un subdirectorio, el archivo .git que deja un submódulo o un worktree enlazado, y las configuraciones que git guarda junto a la principal — config.worktree y cada .git/modules/<name>/config. Cada una de ellas es inspeccionada.
| Clase | Comprobaciones |
|---|---|
| Claves de ejecución directa | core.fsmonitor, core.sshCommand, core.gitProxy, core.pager, core.editor, sequence.editor, diff.external, uploadpack.packObjectsHook |
| Claves de ejecución indirecta | filter.*.clean / .smudge / .process, diff.*.textconv, merge.*.driver, mergetool.*.cmd, difftool.*.cmd, credential.helper |
| Aliases de shell | cualquier alias.* cuyo valor comience con ! |
| Configuración cargada desde otro lugar | include.path, includeIf.*.path |
| Hooks | anulaciones de core.hooksPath, scripts activos (no .sample) en .git/hooks, y scripts de hooks que canalizan una descarga a un shell o decodifican base64 antes de ejecutarla |
| Transportes | protocol.allow y protocol.<name>.allow restablecidos a always, y cualquier URL de remoto o submódulo que use el transporte ext::, que entrega el resto de la línea a un shell |
| Estructura | repositorios bare dentro del árbol (el vector de CVE-2026-45033), directorios .git anidados que no son submódulos registrados, archivos .git que apuntan a un directorio git dentro del árbol |
npx guardskill . # escanea el proyecto actual
npx guardskill ~/code/some-project # escanea una ruta específica
npx guardskill . --json # legible por máquina
npx guardskill . --out report.md # también escribe un informe Markdown
npx guardskill . --fail-on critical # solo falla la compilación en hallazgos críticos
npx guardskill . --exclude test/fixtures # omite un directorio
Códigos de salida: 0 nada en o por encima del umbral, 1 hallazgos en o por encima de él (umbral predeterminado: high), 2 el propio escaneo falló.
En CI:
- name: Check for git execution vectors
run: npx guardskill . --fail-on high
Ejemplo de salida:
GuardSkill - git execution-vector scan (read-only)
Path: /Users/dev/projects/inherited-project
Git configurations inspected: 2 Directories walked: 148
[CRITICAL] vendor/payload.git - Bare git repository found inside the project tree
what Git discovers bare repositories while walking directories and applies their
configuration, including keys that execute commands.
found bare repository at vendor/payload.git
do Do not open this project with a coding agent until you have inspected the directory.
[CRITICAL] vendor/payload.git/config:3 - core.fsmonitor runs an external command
found core.fsmonitor = /tmp/.x/run.sh
2 critical, 0 high, 0 medium, 0 low.
Nothing was changed - this scan only reads.
Una herramienta de seguridad que grita "al lobo" se desinstala. El conjunto se ejecuta contra 29 repositorios limpios realistas — git-lfs, git-crypt, husky, la convención .githooks, submódulos registrados, helpers de credenciales, editores y pagers personalizados, configuración de firma — y la compilación falla si cualquiera de ellos produce un hallazgo por encima del nivel informativo. Se ejecuta contra 22 repositorios construidos alrededor de un patrón de ataque conocido y falla si alguno se pasa por alto, o es detectado por la regla equivocada.
Sobre eso se asienta un conjunto de evasión: cada caso en él fue encontrado atacando una versión de GuardSkill que ya había pasado sus propias pruebas, y se ejecuta en cada commit para que un cambio futuro no pueda reabrir silenciosamente uno. Cubre la misma clave escrita de todas las formas que git aún acepta (mayúsculas/minúsculas, comillas, continuaciones de línea, CRLF, una marca de orden de bytes, una clave en la línea de sección), payloads nombrados como herramientas familiares, directorios de hooks llamados .husky para parecer rutinarios, y configuraciones ocultas donde la primera versión nunca miró. Un conjunto de robustez le alimenta configuraciones binarias, vacías, truncadas y de 200.000 líneas, directorios ilegibles, bucles de symlinks y punteros dirigidos fuera del árbol, y exige un informe en lugar de un stack trace.
Dos elecciones de diseño deliberadas:
.githooks se informan como informativos (low) en lugar de como un riesgo — pero GuardSkill aún lee los scripts, y escala a critical si uno de ellos obtiene o decodifica código antes de ejecutarlo.include / includeIf siempre se informa. Un include puede introducir cualquier clave de esta lista más tarde, que es exactamente cómo ocultarías una. Un ~/.gitconfig compartido que escribiste tú mismo es un hallazgo normal para descartar..husky ejecutando npm test es informativo, y el hallazgo enumera lo que se ejecutará. El mismo directorio ejecutando algo desde /tmp no lo es.No modifica nada, nunca. No ejecuta nada de lo que encuentra. No hace llamadas de red y no recopila telemetría — ejecútalo sin conexión y se comporta de manera idéntica. No escanea dependencias npm, .claude/settings.json, .vscode/tasks.json o definiciones de servidores MCP todavía; esas son la siguiente clase, no esta. Y es una señal, no un veredicto: lee el hallazgo, mira la evidencia, decide por ti mismo.
SKILL.md en este repositorio permite que un agente de codificación ejecute el escaneo por sí mismo antes de abrir un proyecto desconocido. Copia el directorio en tu carpeta de habilidades, o apunta tu agente al repositorio.
npm test # regenera los fixtures, luego ejecuta el conjunto
Los fixtures se generan mediante código (test/fixtures/generate.js), no se confirman a mano, así que extender el conjunto limpio o vulnerable son unas pocas líneas. Las nuevas reglas de detección van en rules/git-exec-keys.json — una regla sin un fixture en ambos lados no se fusionará.
Monitoreo continuo, alertas de Slack/Teams y pull requests de auto-corrección están planificados como una capa de pago. El escáner en sí permanece gratuito y con licencia MIT. Las reglas de detección permanecen en el repositorio abierto — una herramienta de seguridad cuyas reglas no puedes leer no es una en la que debas confiar.
MIT. Construido y mantenido por Helios IT Solutions, un proveedor de servicios de TI neerlandés. Problemas de seguridad: consulta SECURITY.md.