# Auditoría Captain Mobile **Fecha:** 2026-01-16 **Versión:** 1.0 --- ## FASE 1: Análisis Inicial - COMPLETADO ### A1 - Arquitecto Backend #### Endpoints Identificados | Endpoint | Método | Auth | Función | |----------|--------|------|---------| | `/health` | GET | No | Health check | | `/auth/login` | POST | No | Login, retorna JWT (7 días) | | `/sessions` | GET | JWT | Lista screen sessions | | `/sessions` | POST | JWT | Crea nueva sesión | | `/history` | GET | JWT | Lista conversaciones | | `/history/{id}` | GET | JWT | Mensajes de conversación | | `/upload` | POST | JWT | Sube archivos | | `/ws/chat` | WS | JWT | Chat streaming con Claude | | `/ws/terminal/{name}` | WS | JWT | Terminal interactivo | #### PROBLEMAS CRÍTICOS BACKEND | # | Severidad | Problema | Línea | |---|-----------|----------|-------| | 1 | **CRÍTICA** | Command injection via session_name | 187-202 | | 2 | **CRÍTICA** | Bare `except:` oculta errores | 300, 438 | | 3 | **ALTA** | Race condition en creación sesión | 193-202 | | 4 | **ALTA** | CORS `allow_origins=["*"]` | 60 | | 5 | **ALTA** | File descriptor leak | 451-520 | | 6 | **MEDIA** | Silent failures en WebSocket | 384, 486, 508 | | 7 | **MEDIA** | Uploads nunca se limpian | 272-282 | | 8 | **MEDIA** | process.terminate() sin wait | 521 | #### Detalle Command Injection ```python name = "test'; screen -dmS pwned bash; echo '" # Ejecuta: screen -dmS test'; screen -dmS pwned bash; echo ' /claude ``` --- ### A2 - UX Frontend #### Estructura App ``` lib/ ├── main.dart (MultiProvider + AuthWrapper) ├── screens/ (login, chat, sessions, terminal) ├── providers/ (auth, chat) ├── services/ (auth, api, chat, terminal) ├── models/ (message, user, session) └── config/api_config.dart ``` #### PROBLEMAS CRÍTICOS FRONTEND | # | Severidad | Problema | Ubicación | |---|-----------|----------|-----------| | 1 | **CRÍTICA** | Comando en terminal desconectado falla silenciosamente | terminal_service.dart:76 | | 2 | **CRÍTICA** | Sin reconexión automática en Terminal | - | | 3 | **CRÍTICA** | Chat messages sin límite de memoria | chat_provider.dart:9 | | 4 | **ALTA** | TerminalScreen no reconecta al volver de background | - | | 5 | **ALTA** | Botones quick action siempre clickables | terminal_screen.dart:173 | | 6 | **MEDIA** | Sin indicador de envío en chat | chat_screen.dart:227 | | 7 | **MEDIA** | Error messages genéricos | sessions_screen.dart:40 | #### Botones Terminal Existentes | Botón | Código | Estado | |-------|--------|--------| | Ctrl+C | `\x03` | ✓ Correcto | | Ctrl+D | `\x04` | ✓ Correcto | | Tab | `\t` | ✓ Correcto | | Esc | `\x1b` | ✓ Correcto | | Up | `\x1b[A` | ✓ Correcto | | Down | `\x1b[B` | ✓ Correcto | **Problema:** Funcionan si hay conexión, pero fallan silenciosamente si no. --- ### A3 - Explorador Endpoints (Tests Reales) | Endpoint | Resultado | Detalle | |----------|-----------|---------| | GET /health | ✅ PASS | `{"status":"ok"}` | | POST /auth/login | ✅ PASS | Retorna JWT | | GET /sessions | ✅ PASS | Lista 3 sesiones | | POST /sessions | ❌ **FAIL** | "Session created but could not find PID" | | Login incorrecto | ✅ PASS | 401 Invalid credentials | | Sin token | ✅ PASS | 401 Not authenticated | | Nombre duplicado | ✅ PASS | 409 Session already exists | | Nombre vacío | ✅ PASS | 400 Invalid session name | #### BUG CRÍTICO ENCONTRADO ``` POST /sessions → Retorna error "could not find PID" screen -ls | grep test-audit → NO EXISTE La sesión screen NO SE CREA realmente. El comando screen está fallando silenciosamente. ``` --- ## RESUMEN FASE 1 ### Bugs Bloqueantes (Impiden uso básico) 1. **POST /sessions no funciona** - No se pueden crear sesiones nuevas 2. **Command injection** - Vulnerabilidad de seguridad crítica ### Bugs Críticos UX 3. **Terminal falla silenciosamente** - Usuario escribe y nada pasa 4. **Sin reconexión automática** - Terminal muere sin aviso 5. **Memory leak en chat** - Crash tras muchos mensajes ### Bugs Mayores 6. CORS abierto a todos 7. File descriptor leaks 8. Uploads nunca se limpian 9. Botones siempre activos aunque desconectado --- ## FASE 2: Escenarios de Uso _Pendiente validación usuario..._ --- ## FASE 3: Desarrollo _Pendiente..._ --- ## FASE 4: Auditoría Roles - Ronda 1 ### QA Agresivo - 12 vulnerabilidades - CRÍTICA: Sin rate-limit en chat (DoS posible) - CRÍTICA: Sin límite de sesiones creadas - CRÍTICA: File paths no validados en chat - ALTA: Doble-click crea múltiples sesiones - ALTA: Token expirado no se valida mid-stream ### Seguridad - Vulnerabilidades - CRÍTICA: JWT secret hardcoded en código - CRÍTICA: Path traversal en upload filename - ALTA: Command injection en WebSocket terminal session_name - ALTA: Session list muestra TODAS las sesiones (no filtra por usuario) ### Usuario Novato - 12 problemas UX - ALTA: Botones deshabilitados casi invisibles - ALTA: "Reconnecting..." sin progreso ni timeout visible - ALTA: Errores técnicos sin traducir a lenguaje usuario - ALTA: Botones quick action muy pequeños para móvil --- ## FASE 5: Correcciones Aplicadas ### Backend (captain_api.py) 1. ✅ Path correcto a claude (`/home/architect/.npm-global/bin/claude`) 2. ✅ CORS restringido (solo dominios específicos) 3. ✅ Sanitización session_name con regex (`[a-z0-9-]`) 4. ✅ JWT secret aleatorio si no configurado 5. ✅ Validación file paths (solo /tmp/captain-uploads) 6. ✅ Validación session_name en WebSocket terminal 7. ✅ Excepciones específicas en lugar de bare except ### Frontend (Flutter) 1. ✅ Reconexión automática con backoff exponencial 2. ✅ Error controller para mostrar errores al usuario 3. ✅ sendInput() retorna bool indicando si se envió 4. ✅ Lifecycle observer para reconectar al volver de background 5. ✅ Botones deshabilitados con color diferenciado 6. ✅ Indicador de estado con texto (Connected/Reconnecting/Error) 7. ✅ Límite de 500 mensajes en chat (memory leak fix) --- ## FASE 6: Compilación Final - COMPLETADA **APK:** `cloud.tzzrdeck.me` → `documentos adjuntos/captain-mobile.apk` **Fecha:** 2026-01-16 **Tamaño:** 23.8MB ### Para activar cambios backend: ```bash sudo systemctl restart captain-api ``` ### Bugs pendientes (no críticos): - Rate limiting en endpoints (requiere Redis/similar) - Multi-usuario real (requiere refactor de auth) - Certificate pinning en Flutter - Más botones quick action (Left, Right, Home, End)