6.4 KiB
6.4 KiB
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
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)
- POST /sessions no funciona - No se pueden crear sesiones nuevas
- Command injection - Vulnerabilidad de seguridad crítica
Bugs Críticos UX
- Terminal falla silenciosamente - Usuario escribe y nada pasa
- Sin reconexión automática - Terminal muere sin aviso
- Memory leak en chat - Crash tras muchos mensajes
Bugs Mayores
- CORS abierto a todos
- File descriptor leaks
- Uploads nunca se limpian
- 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)
- ✅ Path correcto a claude (
/home/architect/.npm-global/bin/claude) - ✅ CORS restringido (solo dominios específicos)
- ✅ Sanitización session_name con regex (
[a-z0-9-]) - ✅ JWT secret aleatorio si no configurado
- ✅ Validación file paths (solo /tmp/captain-uploads)
- ✅ Validación session_name en WebSocket terminal
- ✅ Excepciones específicas en lugar de bare except
Frontend (Flutter)
- ✅ Reconexión automática con backoff exponencial
- ✅ Error controller para mostrar errores al usuario
- ✅ sendInput() retorna bool indicando si se envió
- ✅ Lifecycle observer para reconectar al volver de background
- ✅ Botones deshabilitados con color diferenciado
- ✅ Indicador de estado con texto (Connected/Reconnecting/Error)
- ✅ 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:
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)