feat(episode): TRAZA_hallazgo-crtico-mega-hook-sshpy-no-pro_S20260518.R1_XX.ops.2.hot_inf.in.cc.es.000.MGQ_J.PMCFK_E.SGNFD
Skill: NONE | Type: troubleshooting
Summary: EPISODIO 1 — HANDOFF_PROMPT.md: 🔴 Hallazgo crítico — `mega-hook-ssh.py` no prote
This commit is contained in:
parent
de507b5339
commit
1516fc6f8f
1 changed files with 39 additions and 0 deletions
|
|
@ -0,0 +1,39 @@
|
||||||
|
---
|
||||||
|
episode_id: "e2a2c7ad-0c95-4ac7-b747-77f625722e6e"
|
||||||
|
puente_flat: "TRAZA_hallazgo-crtico-mega-hook-sshpy-no-pro_S20260518.R1_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 1 — 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-19T03:20:17.180034+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*.
|
||||||
Loading…
Reference in a new issue