feat(episode): TRAZA_hallazgo-crtico-mega-hook-sshpy-no-pro_S20260518.R43_XX.ops.2.hot_inf.in.cc.es.000.MGQ_J.PMCFK_E.SGNFD

Skill: NONE | Type: troubleshooting
Summary: EPISODIO 43 — HANDOFF_PROMPT.md: 🔴 Hallazgo crítico — `mega-hook-ssh.py` no prot
This commit is contained in:
Ember 2026-05-20 06:14:21 +00:00
parent e4b4cb70b3
commit c7811d52bc

View file

@ -0,0 +1,39 @@
---
episode_id: "0a37de6f-51b0-401b-9d42-bb65c34601e8"
puente_flat: "TRAZA_hallazgo-crtico-mega-hook-sshpy-no-pro_S20260518.R43_XX.ops.2.hot_inf.in.cc.es.000.MGQ_J.PMCFK_E.SGNFD"
session_code: "S20260518.PIPELINE_FIXES"
acto_dialogico: "informar"
actor_flujo: "multi_actor"
criticidad_aegis: "low"
skill_dominante: "NONE"
fase_proyecto: "operations"
tipo_semantico: "troubleshooting"
summary_one_line: "EPISODIO 43 — HANDOFF_PROMPT.md: 🔴 Hallazgo crítico — `mega-hook-ssh.py` no protege el servid"
source_type: "claude_code"
trust_boundary: "internal"
created_at: "2026-05-20T06:12:40.264885+00:00"
relectura_tagged: false
forgejo_commit_sha: "pending"
---
El sondeo **confirma la hipótesis — y el hallazgo es más grave de lo previsto.**
## 🔴 Hallazgo crítico — `mega-hook-ssh.py` no protege el servidor
El guardián que protege el servidor MEMORIA de comandos destructivos **NO los bloquea en la forma `ssh HOST "..."`** — la forma idiomática y casi universal de ejecutar comandos remotos. Verificado empíricamente hoy ejecutando el hook real como subproceso (`casbin-poc/probe_hook_behavior.py`):
| Comando (veredicto del hook real, hard_fact) | Hook real | Debería |
|---|---|---|
| `ssh cx43 "rm -rf /tmp/cache"` | **allow** ❌ | deny |
| `ssh cx43 "git push --force origin main"` | **allow** ❌ | deny |
| `ssh cx43 "psql -c 'DROP TABLE users'"` | **allow** ❌ | deny |
| `ssh cx43 rm -rf /tmp/cache` (sin comillas) | deny ✓ | deny |
| `ssh cx43 "ls -la /home"` (control seguro) | allow ✓ | allow |
El hook **solo funciona cuando el payload va sin comillas** — forma que casi nadie usa. La forma estándar entre comillas lo elude por completo.
**Causa raíz:** el audit S20260510 (caso #4) añadió `_is_inside_quotes()` para frenar un over-trigger real (el hook bloqueaba `sed`/`grep` legítimos que *mencionaban* comandos destructivos dentro de literales de texto). La heurística — "si el patrón cae dentro de comillas, omítelo" — cuenta las comillas del string completo. Como todo comando SSH se escribe `ssh HOST "payload"`, el payload entero queda tras la comilla de apertura → la heurística lo declara "dentro de comillas" → omite los 10 patrones destructivos. El parche curó los falsos positivos creando falsos negativos masivos. (Verificado con comillas dobles; el código cuenta también las simples → mismo efecto en `ssh HOST 'payload'` — inferido del código, no probado.)
## Qué cambia para la Fase 5
Esto reencuadra la Fase 5 de raíz. El POC dio "216/216 verde" porque comparó Casbin contra `hook_reference` — los 10 patrones crudos, que es lo que el hook **debería** hacer. Es decir: el modelo Casbin del POC implementa el comportamiento **correcto**; el hook real es el que está roto. "Migración cero-regresión" ya no aplica — migrar fielmente el hook actual sería *enshrinar el bug*.