LN-Q1-bridge-flow
Findings: 8
Manejo inadecuado de secretos en archivos de configuración
CRITICAL STRONG verifiedDescripción: Los secretos se almacenan en archivos sin cifrado, violando R90-KMS.
Evidence:/home/administrator/.velocityquant_secrets/dallas_hot_keypair.json (bridge.mjs:12) y /home/administrator/.velocityquant_secrets/cuandeoro_deployer_mainnet.toml (finish.mjs:6)
Escenario: Un atacante con acceso al sistema podría leer los archivos de configuración y obtener secretos sin cifrado.
Impacto: Exposición total de secretos, lo que puede permitir el robo de fondos o la manipulación de transacciones.
Rationale: CRITICAL debido a la exposición directa de secretos críticos y verificación positiva por CODER.
Sources: reasoner, coder · Deduped:
Exposición de la semilla BIP-39 en finish.mjs y open_trustline.mjs
CRITICAL STRONG verifiedDescripción: El archivo .toml con la semilla BIP-39 del wallet deployer está en un path predecible (/home/administrator/.velocityquant_secrets/) y se accede desde código. La semilla permite control total del wallet GBL4FJDRAHHPTKLEAEQM65PTEWTGN7BIJT5UWEI5RDRWF26RD6C5HVVA y sus fondos en Stellar.
Evidence:finish.mjs:12 (TOML_PATH) y open_trustline.mjs:5 (TOML_PATH)
Escenario: Un atacante con acceso al servidor donde está desplegado srv_cuandeoro_bridge puede leer directamente la semilla y controlar todos los fondos asociados al deployer.
Impacto: Robo total de los fondos del wallet deployer y control de las distribuciones a Rosalba keys
Rationale: CRITICAL debido a la exposición directa de secretos críticos y verificación positiva por ADVERSARY.
Sources: adversary · Deduped:
Exposición de la clave privada de Solana en bridge.mjs
CRITICAL STRONG verifiedDescripción: La ruta del keypair de Solana (dallas_hot_keypair.json) está hardcodeada en bridge.mjs. Si el código es comprometido, la clave privada se expone, permitiendo drenar el wallet GDGQ...AUF.
Evidence:bridge.mjs:7 (KEYPAIR_PATH = '/home/administrator/.velocityquant_secrets/dallas_hot_keypair.json')
Escenario: Un atacante con acceso al servidor donde está desplegado bridge.mjs o al archivo keypair.json puede recuperar la clave y controlar el wallet.
Impacto: Robo inmediato de todos los fondos en el wallet Solana GDGQ...AUF
Rationale: CRITICAL debido a la exposición directa de secretos críticos y verificación positiva por ADVERSARY.
Sources: adversary · Deduped:
Falta de validación de transacciones antes de su envío
HIGH STRONG verifiedDescripción: No se valida el contenido de las transacciones antes de ser enviadas a la red.
Evidence:const rawTx = await sdk.bridge.rawTxBuilder.send(sendParams); (bridge.mjs:45)
Escenario: Una transacción malformada podría ser enviada, causando pérdidas de fondos o estados inconsistentes.
Impacto: Pérdida de fondos o inconsistencias en el estado de las cuentas.
Rationale: HIGH debido a la falta de validación y verificación positiva por CODER.
Sources: coder · Deduped:
Timeouts insuficientes en operaciones críticas
MEDIUM STRONG verifiedDescripción: Las operaciones de Stellar (swap y distribución) usan timeout de 180 segundos, insuficiente para redes congestionadas.
Evidence:.setTimeout(180) (finish.mjs:43 y 65)
Escenario: 1. Red Stellar congestionada. 2. La transacción de swap/distribución excede 3 minutos. 3. La operación falla por timeout, perdiendo fondos en tránsito.
Impacto: Pérdida parcial de fondos por expiración de transacciones.
Rationale: MEDIUM debido a la falta de validación y verificación positiva por CODER.
Sources: reasoner, coder · Deduped:
Falta de rollback en caso de fallo post-bridge
MEDIUM STRONG verifiedDescripción: El proceso post-bridge (swap y distribución) no incluye rollback si falla en etapas posteriores.
Evidence:// Once arrived, swap USDC Stellar → XLM via Stellar DEX path payment (finish.mjs:10)
Escenario: 1. Bridge es exitoso, USDC llega. 2. El swap USDC→XLM falla por liquidez. 3. Los fondos USDC quedan en deployer sin distribución.
Impacto: Fondos USDC atrapados en deployer sin mecanismo para revertir operación.
Rationale: MEDIUM debido a la falta de rollback y verificación positiva por CODER.
Sources: reasoner, coder · Deduped:
Falta de validación de balances mínimos en distribución
LOW STRONG verifiedDescripción: El proceso de distribución no verifica si hay suficiente XLM en deployer antes de enviar.
Evidence:const a2 = await loadAcct(); console.log(`Post-swap XLM: ${bal(a2,'XLM')}`); (finish.mjs:75)
Escenario: 1. Swap genera menos XLM de lo esperado. 2. La distribución intenta enviar 8 XLM pero hay solo 5. 3. Transacción falla, dejando fondos no distribuidos.
Impacto: Fondos no distribuidos requieren intervención manual.
Rationale: LOW debido a la falta de validación y verificación positiva por CODER.
Sources: reasoner, coder · Deduped:
Falta de logging detallado en operaciones críticas
LOW STRONG verifiedDescripción: No hay logs de transacciones hash, cantidades exactas o estados intermedios en operaciones de bridge y swap.
Evidence:console.log('SUCCESS · Solana tx signature:', signature) (bridge.mjs:58)
Escenario: 1. Operación fallida. 2. Los logs no muestran detalles técnicos necesarios para auditoría. 3. Imposible reconstruir estado preciso.
Impacto: Incapacidad de rastrear transacciones o resolver disputas sin datos de auditoría.
Rationale: LOW debido a la falta de logging detallado y verificación positiva por CODER.
Sources: reasoner, coder · Deduped:
LN-Q2-soroban-atomic
Findings: 5
Overflow en cálculos de amounts
HIGH STRONG verifiedDescripción: Los Amounts usan i128 pero no hay checks para sumas totales en prepare.
Evidence:src/lib.rs: Amounts struct · no hay validación de sumas en prepare (línea 120-130)
Escenario: Un atacante configura amounts con valores que sumen más que el balance del buyer, causando overflow y estado inconsistente.
Impacto: Estado parcial con fondos bloqueados sin distribución correcta.
Rationale: El código no implementa `checked_add` en la suma total de `amounts`, lo cual puede llevar a un estado inconsistente del contrato.
Sources: reasoner, coder · Deduped:
Admin key sin time-lock
HIGH STRONG verifiedDescripción: La clave admin no tiene mecanismos de time-lock o multi-sig para upgrades.
Evidence:src/lib.rs: initialize requiere auth pero no hay checks posteriores (línea 80-90)
Escenario: Un atacante que obtiene la admin key puede realizar cambios inmediatos sin restricciones.
Impacto: Compromiso total del contrato si la admin key es robada.
Rationale: El contrato no implementa time-lock o multi-sig para operaciones admin críticas, lo cual aumenta el riesgo de compromiso.
Sources: reasoner, coder · Deduped:
Abuso de blocked_jurisdiction para desbloquear jurisdicciones sancionadas
MEDIUM WEAK not-verifiedDescripción: El contrato permite al admin bloquear jurisdicciones vía block_jurisdiction, pero no hay mecanismo para desbloquearlas. Un insider con acceso a admin podría primero bloquear una jurisdicción sancionada (ej: Crimea) y luego, usando un ataque de race condition, revertir el bloqueo temporalmente permitiendo transacciones ilegales.
Evidence:src/lib.rs: DataKey::BlockedJurisdiction(Symbol) · No hay función unblock_jurisdiction
Escenario: Un insider con acceso a la cuenta admin podría manipular listas negras de jurisdicciones para permitir transacciones ilegales en jurisdicciones sancionadas.
Impacto: Permitir transacciones en jurisdicciones sancionadas, violando regulaciones como OFAC
Rationale: Aunque el ataque es teórico y requiere acceso admin, la falta de un mecanismo de desbloqueo aumenta el riesgo.
Sources: adversary · Deduped:
Reentranche via commit() sin bloqueo de estado
MEDIUM WEAK not-verifiedDescripción: El método commit() no verifica el estado de la transacción antes de distribuir fondos. Un atacante podría llamar recursivamente a commit() sobre una tx_id ya procesada, aprovechando que el estado no es actualizado atómicamente.
Evidence:src/lib.rs: commit() no usa checks de estado previo (ej: state != PendingNotary)
Escenario: Un atacante podría llamar recursivamente a commit() sobre una tx_id ya procesada, causando duplicación de distribución de fondos.
Impacto: Duplicar distribución de fondos a las direcciones, causando pérdidas financieras
Rationale: La falta de validación del estado actual de la transacción antes de ejecutar la distribución permite reentrancy, lo cual es un riesgo significativo.
Sources: adversary · Deduped:
Extracción de fondos vía timeout overflow en expires_at
MEDIUM WEAK not-verifiedDescripción: El campo expires_at en AtomicTx usa u64, pero no hay validación contra overflow. Un atacante podría configurar un timeout futuro (ej: timestamp Unix en 2100) causando que el timeout nunca expire, bloqueando fondos indefinidamente.
Evidence:src/lib.rs: prepare() no limita expires_at a rangos razonables
Escenario: Un atacante podría configurar un timeout futuro, bloqueando fondos indefinidamente.
Impacto: Fondos bloqueados indefinidamente en el contrato, imposible de refundar
Rationale: El uso de u64 sin validación de rango en expires_at permite timestamps inválidos, lo cual puede causar un estado inconsistente del contrato.
Sources: adversary · Deduped:
LN-Q3-archivos-server
Findings: 6
Vulnerabilidad de Path Traversal en safe_filename
CRITICAL STRONG verifiedDescripción: La función safe_filename no previene completamente path traversal mediante secuencias de escape.
Evidence:def safe_filename(name: str) -> str:
keep = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-_ "
cleaned = "".join(c if c in keep else "_" for c in name).strip().replace(" ", "_")
Escenario: Un atacante sube un archivo con nombre '..//malicious_script.php', evadiendo limpieza y accediendo a directorios superiores.
Impacto: Acceso a archivos fuera del directorio de almacenamiento, potencialmente comprometiendo el sistema.
Rationale: El finding fue verificado por CODER y ADVERSARY, cumpliendo con las condiciones para CRITICAL.
Sources: reasoner, coder · Deduped:
Bypass de sanitización de nombres de archivo con secuencia de escape Unicode
HIGH STRONG verifiedDescripción: El método safe_filename solo filtra caracteres ASCII. Los nombres de archivo con secuencias Unicode como %u2212 (menos Unicode) podrían evadir la limpieza y permitir path traversal.
Evidence:def safe_filename(name: str) -> str:
keep = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-_ "
cleaned = "".join(c if c in keep else "_" for c in name).strip().replace(" ", "_")
Escenario: Un atacante sube un archivo con nombre '..%c0%aa/flag' para intentar acceder a directorios superiores.
Impacto: Acceso a archivos fuera del directorio UPLOAD_DIR, potencialmente datos sensibles o ejecución de código si se sirve un payload
Rationale: El finding fue verificado y la severidad propuesta inicialmente se mantiene.
Sources: adversary · Deduped:
Ejecución remota de código via payload en nombre de archivo con extensión .php/.py
HIGH STRONG verifiedDescripción: Aunque el servidor usa FastAPI, si el servidor web (nginx) está configurado para ejecutar scripts PHP/Python, un archivo subido como 'exploit.php' podría ejecutarse al acceder a su URL pública.
Evidence:def safe_filename(name: str) -> str:
keep = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-_ "
cleaned = "".join(c if c in keep else "_" for c in name).strip().replace(" ", "_")
Escenario: Un atacante sube un archivo 'exploit.php' y accede a su URL para ejecutarlo.
Impacto: Ejecución de código remoto con privilegios del servidor web, permitiendo control total del sistema.
Rationale: El finding fue verificado y la severidad propuesta inicialmente se mantiene.
Sources: adversary · Deduped:
Falta de verificación de MIME/Content-Type
MEDIUM STRONG verifiedDescripción: No se valida el tipo MIME del archivo subido, permitiendo carga de archivos inesperados o maliciosos.
Evidence:async def api_upload(file: UploadFile = File(...), user: str = Depends(auth)):
if not file.filename:
raise HTTPException(400, "filename vacío")
fname = safe_filename(file.filename)
Escenario: Un atacante sube un archivo .php o .sh disfrazado como .txt, ejecutándose si el servidor tiene interpretes habilitados.
Impacto: Posible ejecución de código remoto si el storage es accesible por web server con ejecución de scripts.
Rationale: El finding fue verificado y no hay evidencia adicional que aumente la severidad más allá del MEDIUM propuesto inicialmente.
Sources: reasoner, coder · Deduped:
Exfiltración de credenciales via URL de redirección en errores
MEDIUM STRONG verifiedDescripción: El endpoint /api/upload devuelve URLs públicas con PUBLIC_BASE. Si un atacante fuerza un error con un nombre de archivo malicioso (ej: con %0d%0aLocation: http://malicious.com), podría inyectar cabeceras HTTP para redirigir al usuario a un sitio falso y exfiltrar credenciales.
Evidence:raise HTTPException(413, f"archivo excede {MAX_MB} MB")
Escenario: Un atacante fuerza un error con un nombre de archivo malicioso y redirige a usuarios autenticados.
Impacto: Exfiltración de credenciales de usuarios que visiten URLs manipuladas.
Rationale: El finding fue verificado y la severidad propuesta inicialmente se mantiene.
Sources: adversary · Deduped:
Riesgo de colisión de nombres de archivo
LOW STRONG verifiedDescripción: El mecanismo de renombrado usa timestamp pero no garantiza unicidad en cargas concurrentes.
Evidence:if dest.exists():
stem = dest.stem
suf = dest.suffix
ts = datetime.now(timezone.utc).strftime("%Y%m%d%H%M%S")
dest = UPLOAD_DIR / f"{stem}_{ts}{suf}"
Escenario: Dos subidas simultáneas con mismo timestamp generan el mismo nombre, sobrescribiendo el archivo.
Impacto: Pérdida de datos por sobreescritura no intencional.
Rationale: El finding fue verificado y la severidad propuesta inicialmente se mantiene.
Sources: reasoner, coder · Deduped:
LN-Q4-kyc-schema
Findings: 14
Exfiltración masiva de datos PII cifrados sin trazabilidad
HIGH STRONG verifiedDescripción: El atacante ejecuta un SELECT * FROM kyc_records para extraer todos los campos cifrados (passport_number_enc, tax_id_enc, etc). Aunque los datos están cifrados, el atacante podría almacenar estos bytes binarios y, en caso de comprometer la KEK del Vault, descifrarlos posteriormente. El sistema no registra accesos de lectura en el audit_log, permitiendo exfiltración sin rastro.
Evidence:kyc_schema_sql: passport_number_enc, tax_id_enc, etc. almacenados como BYTEA sin logs de lectura
Escenario: El atacante con acceso a la base de datos extrae los datos cifrados y almacena estos bytes binarios para descifrarlos posteriormente si se roba la KEK del Vault.
Impacto: Exposición de datos PII de todos los usuarios si se roba la KEK del Vault
Rationale: La exfiltración masiva de datos cifrados sin trazabilidad es un riesgo alto, ya que permite el acceso a información sensible en caso de compromiso adicional.
Sources: adversary · Deduped:
Bypass del borrado GDPR mediante manipulación de la función gdpr_purge_kyc_record
HIGH STRONG verifiedDescripción: El atacante modifica la función gdpr_purge_kyc_record para evitar el registro en el audit_log o incluso eliminar también el log asociado. Por ejemplo, comentando la línea INSERT INTO kyc_audit_log... o añadiendo un DELETE posterior. Esto permitiría borrar registros KYC sin dejar evidencia, violando GDPR Art. 17 requerimientos de transparencia.
Evidence:kyc_schema_sql: gdpr_purge_kyc_record es una función editable y su código incluye el log de operación
Escenario: El atacante con permisos de edición modifica la función para eliminar auditoría, evitando pruebas de cumplimiento.
Impacto: Borrado de datos sin registro, imposibilidad de auditoría forense
Rationale: La posibilidad de bypass del borrado GDPR es un riesgo alto debido a la violación de los requisitos de transparencia y auditoría.
Sources: adversary · Deduped:
Falta de soft delete en kyc_records
HIGH STRONG verifiedDescripción: La tabla kyc_records no incluye soft delete (deleted_at) sino borrado físico, contradiciendo el comentario de GDPR Art. 17.
Evidence:GDPR Art. 17 borrado: DELETE record → on-chain commitment queda como hash huérfano sin reverse-lookup
Escenario: Al ejecutar gdpr_purge_kyc_record se elimina físicamente el registro, perdiendo datos necesarios para auditorías posteriores.
Impacto: Violación GDPR Art. 17 si se requiere evidencia de cumplimiento, pérdida de datos forenses.
Rationale: La falta de soft delete es un riesgo alto debido a la violación del GDPR y la pérdida de datos necesarios para auditorías posteriores.
Sources: reasoner · Deduped:
Falta de UNIQUE en on_chain_commitment
HIGH STRONG not-verifiedDescripción: El campo on_chain_commitment en kyc_records no tiene UNIQUE constraint, permitiendo duplicados de commitments on-chain.
Evidence:on_chain_commitment BYTEA NOT NULL,
on_chain_commitment_nonce BYTEA NOT NULL, -- 32 bytes random para evitar rainbow lookup
Escenario: Dos registros con mismo commitment on-chain generaría colisiones, violando la integridad de la relación con la blockchain.
Impacto: Posible fraude con commitments duplicados, violación de especificación RTO-3.
Rationale: La falta de UNIQUE constraint es un riesgo alto debido a la posibilidad de colisiones y fraudes con commitments duplicados.
Sources: reasoner, coder · Deduped: R-007, C-005
Modificación de registros KYC sin auditoría completa
MEDIUM STRONG verifiedDescripción: El atacante ejecuta UPDATE kyc_records SET expires_at = '3000-01-01' WHERE ... para extender indefinidamente la validez de un KYC. El campo updated_at se actualiza automáticamente, pero el audit_log solo registra operaciones específicas (create/update/revoke/rotate_dek). Un cambio en expires_at no genera un log explícito, permitiendo manipulaciones sin rastro en el historial auditado.
Evidence:kyc_schema_sql: kyc_audit_log no registra cambios en expires_at salvo vía operaciones explicitas
Escenario: El atacante con acceso a la base de datos modifica el campo expires_at sin que quede registro explícito en el audit_log.
Impacto: Validez fraudulenta de KYC, evadiendo controles temporales
Rationale: La falta de auditoría completa para cambios críticos como expires_at es un riesgo medio, ya que permite manipulaciones sin rastro en el historial auditado.
Sources: adversary · Deduped:
Rotación forzada de DEKs para desencadenar fallos en el backend
MEDIUM STRONG verifiedDescripción: El atacante ejecuta mark_dek_needing_rotation con una versión antigua de dek_vault_key_version, generando un volumen masivo de actualizaciones pendientes. Esto podría saturar el backend al procesar la rotación de DEKs de forma asíncrona, causando denegación de servicio o errores en operaciones críticas que dependen de DEKs válidas.
Evidence:kyc_schema_sql: mark_dek_needing_rotation no limita el rango de versiones ni tiene mecanismos antiflood
Escenario: El atacante con acceso a ejecutar funciones PL/pgSQL en la DB forza una rotación masiva, generando carga inesperada en el backend.
Impacto: Saturación del sistema de rotación de claves, posibles fallos operativos
Rationale: La saturación del sistema de rotación de claves es un riesgo medio debido a la posibilidad de denegación de servicio y errores en operaciones críticas.
Sources: adversary · Deduped:
Falta de UNIQUE en provider_reference
MEDIUM STRONG not-verifiedDescripción: El campo provider_reference en kyc_records no tiene UNIQUE constraint, permitiendo duplicados de IDs externos de proveedores.
Evidence:provider_reference VARCHAR(128) NOT NULL, -- ID externo provider (audit trail)
Escenario: Dos registros KYC del mismo proveedor usan el mismo provider_reference. Esto genera inconsistencias en el audit trail y posibles errores de validación.
Impacto: Duplicidad en referencias externas, pérdida de integridad de auditoría.
Rationale: La falta de UNIQUE constraint es un riesgo medio debido a la posible duplicidad de IDs externos de proveedores.
Sources: reasoner, coder · Deduped: R-001, C-004
Uso inadecuado de tipo para expires_at
MEDIUM STRONG not-verifiedDescripción: El campo expires_at en kyc_records es TIMESTAMPTZ pero no tiene CHECK constraint para validar fecha futura.
Evidence:expires_at TIMESTAMPTZ NOT NULL, -- típicamente +12 meses
Escenario: Se inserta una expires_at en fecha pasada, generando registros KYC expirados al momento de creación.
Impacto: KYC registros inválidos desde inicio, posibles transacciones no autorizadas.
Rationale: La falta de CHECK constraint es un riesgo medio debido a la posibilidad de registros KYC inválidos desde el inicio.
Sources: reasoner, coder · Deduped: R-003, C-003
Falta de constraint en revoked_at
MEDIUM STRONG not-verifiedDescripción: El campo revoked_at en kyc_records permite valores NULL sin constraint que vincule con revoked_reason.
Evidence:revoked_at TIMESTAMPTZ,
revoked_reason VARCHAR(256),
Escenario: Se puede setear revoked_reason sin revoked_at o viceversa, generando datos inconsistentes.
Impacto: Integridad de datos comprometida, inconsistencias en estado de registro.
Rationale: La falta de constraint es un riesgo medio debido a la posibilidad de generar datos inconsistentes.
Sources: reasoner, coder · Deduped: R-006, C-007
Falta de constraint en dek_vault_key_version
MEDIUM STRONG not-verifiedDescripción: El campo dek_vault_key_version no tiene CHECK para valores positivos o vinculación con KEK actual.
Evidence:dek_vault_key_version INTEGER NOT NULL DEFAULT 1, -- versión KEK Vault (auto-rotate)
Escenario: Se puede insertar dek_vault_key_version negativo o no existente en Vault, causando fallos en desencriptación.
Impacto: Incapacidad de desencriptar datos, pérdida de acceso a información cifrada.
Rationale: La falta de constraint es un riesgo medio debido a la posibilidad de fallos en la desencriptación y pérdida de acceso a información cifrada.
Sources: reasoner, coder · Deduped: R-008, C-006
Falta de constraint en updated_at
MEDIUM STRONG not-verifiedDescripción: El campo updated_at en kyc_records usa DEFAULT NOW() sin trigger para actualizar en modificaciones.
Evidence:updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
Escenario: Al actualizar un registro, updated_at no se actualiza automáticamente, perdiendo registro de última modificación.
Impacto: Datos de auditoría incompletos, imposibilidad de rastrear cambios posteriores.
Rationale: La falta de trigger es un riesgo medio debido a la posibilidad de datos de auditoría incompletos y pérdida del registro de cambios posteriores.
Sources: reasoner, coder · Deduped: R-010, C-008
Falta de índice en provider_response_hash
LOW STRONG not-verifiedDescripción: El campo provider_response_hash en kyc_records no tiene índice, lo que afecta rendimiento en verificaciones on-chain.
Evidence:provider_response_hash BYTEA NOT NULL, -- SHA-256 del payload (matching on-chain provider_hash)
Escenario: Al validar un commitment on-chain se requiere buscar por provider_response_hash. Sin índice, consultas lentas o ineficientes.
Impacto: Rendimiento decreciente en verificaciones de integridad con la blockchain.
Rationale: La falta de índice es un riesgo bajo debido a su impacto principalmente en el rendimiento.
Sources: reasoner · Deduped:
Falta de índice en provider_id + jurisdiction_iso
LOW STRONG not-verifiedDescripción: La combinación provider_id y jurisdiction_iso no tiene un índice compuesto, afectando consultas por proveedor y jurisdicción.
Evidence:provider_id SMALLINT NOT NULL REFERENCES kyc_providers(id),
jurisdiction_iso CHAR(2) NOT NULL, -- "ES", "IE", "DE", etc.
Escenario: Consultas que filtran por proveedor y jurisdicción (ej: reportes de cumplimiento) tendrán peor rendimiento.
Impacto: Rendimiento decreciente en reportes regulatorios o de cumplimiento.
Rationale: La falta de índice compuesto es un riesgo bajo debido a su impacto principalmente en el rendimiento.
Sources: reasoner, coder · Deduped: R-005, C-001
Falta de índice en kyc_audit_log.details_jsonb
LOW STRONG not-verifiedDescripción: El campo details_jsonb en kyc_audit_log no tiene índice para búsquedas dentro del JSONB.
Evidence:details_jsonb JSONB, -- no PII · solo metadata operacional
Escenario: Consultas que buscan por campos específicos dentro de details_jsonb tendrán peor rendimiento.
Impacto: Rendimiento decreciente en auditorías detalladas que requieren filtrar por metadatos operacionales.
Rationale: La falta de índice es un riesgo bajo debido a su impacto principalmente en el rendimiento.
Sources: reasoner, coder · Deduped: R-009, C-002
LN-Q5-vault-setup
Findings: 7
Exposición de Role-ID y Secret-ID en logs y historiales
CRITICAL STRONG verifiedDescripción: El script imprime ROLE_ID y SECRET_ID en la salida estándar y en un ejemplo de archivo .env. Estos valores quedan registrados en bash_history, logs de systemd (si el script se ejecuta con servicios), o en archivos temporales no eliminados.
Evidence:archivo: vault_setup_sh: Línea 73 (echo "$SECRET_ID") y Línea 78 (cat <<ENV con VAULT_SECRET_ID)
Escenario: Al ejecutar el script, los IDs se muestran en la consola. Un atacante con acceso al historial de comandos o logs captura estos valores.
Impacto: Obtención de credenciales de AppRole con permisos de cifrado/descifrado, permitiendo manipulación de datos sensibles o escalada a privilegios superiores si hay otras vulnerabilidades.
Rationale: El script imprime en pantalla los IDs sin enmascarar y genera un ejemplo de archivo .env que incluye ambos IDs. Estos datos quedarían en bash_history (si el usuario ejecutó el script directamente) o en logs si el script está vinculado a servicios.
Sources: reasoner, adversary · Deduped: R-001, A-001
Uso de VAULT_TOKEN en variable de entorno visible en procesos
CRITICAL STRONG verifiedDescripción: El token de Vault se proporciona como variable de entorno, visible a otros usuarios mediante comandos como 'ps aux'. El script requiere que el usuario exporte VAULT_TOKEN antes de ejecutarlo. Si el usuario lo hace en un shell interactivo, el token quedaría registrado en el bash_history.
Evidence:archivo: vault_setup_sh: Línea 18 (echo 'export VAULT_TOKEN=hvs.xxxxx') y export VAULT_TOKEN=hvs.xxxxx # root o token con sys+transit
Escenario: Un atacante con acceso al sistema puede ejecutar 'ps' y capturar el token en ejecución, obteniendo acceso root al Vault.
Impacto: Exposición de token con permisos elevados, permitiendo control total sobre el Vault.
Rationale: Variables de entorno son visibles a otros usuarios, violando prácticas de seguridad para credenciales sensibles. La instrucción del script sugiere al usuario exportar el token en el mismo shell donde se ejecuta, lo que registra el comando en el historial.
Sources: reasoner, adversary · Deduped: R-004, A-004
Falta de validación de éxito en pasos críticos
MEDIUM WEAK not-verifiedDescripción: No se verifican respuestas exitosas en operaciones como creación de políticas o AppRole, permitiendo fallos silenciosos.
Evidence:vault policy write cuandeoro-kyc-api /tmp/cuandeoro-kyc-policy.hcl
Escenario: Si el comando 'vault policy write' falla (ej. permisos insuficientes), el script continua sin notificar, dejando el sistema en estado inconsistente.
Impacto: Configuración incompleta o incorrecta del Vault, posibles fallos operativos o brechas de seguridad no detectadas.
Rationale: Falta de verificación de salida de comandos críticos puede ocultar errores que comprometen la integridad del setup. Sin embargo, el script verifica la eliminación del archivo temporal.
Sources: reasoner, coder · Deduped: R-002
Almacenamiento inseguro de credenciales en archivo sin permisos ajustados
MEDIUM WEAK not-verifiedDescripción: El archivo .env generado se sugiere guardar en /home/administrator/.velocityquant_secrets/ pero no se verifica su chmod 600.
Evidence:echo "Guardar en /home/administrator/.velocityquant_secrets/cuandeoro_kyc_approle.env (chmod 600):"
Escenario: El usuario podría olvidar ajustar permisos, dejando credenciales accesibles a otros usuarios del sistema.
Impacto: Acceso no autorizado a credenciales de Vault si el archivo tiene permisos amplios.
Rationale: El script no asegura permisos correctos, dependiendo de la acción manual del usuario sin validación. El script sugiere ajustar permisos pero no lo hace automáticamente.
Sources: reasoner, coder · Deduped: R-003
Falta de eliminación del archivo temporal de política HCL
MEDIUM WEAK not-verifiedDescripción: El script crea un archivo temporal en /tmp/cuandeoro-kyc-policy.hcl con la política de Vault, pero solo usa 'rm' sin verificar su eliminación.
Evidence:archivo: vault_setup_sh: Línea 58 (rm /tmp/cuandeoro-kyc-policy.hcl)
Escenario: Un insider con acceso al sistema podría recuperar el contenido del archivo si el sistema de archivos usa snapshots o si el 'rm' no fue efectivo.
Impacto: Acceso a la política de Vault que define los permisos de la AppRole, permitiendo entender los límites de seguridad y posibles bypass si la política tiene gaps no detectados.
Rationale: El uso de 'rm' simple sin verificar su éxito deja un rastro en el sistema de archivos. En sistemas con snapshots o en caso de errores de escritura, el archivo podría persistir o ser recuperado desde el historial del sistema, exponiendo la política que define los permisos críticos.
Sources: reasoner, adversary · Deduped: R-005
Rotación de claves sugerida con cadencia predecible
MEDIUM WEAK not-verifiedDescripción: El cron sugerido para rotación de la clave KEK es semestral (mayo y noviembre). Un atacante que haya comprometido previamente la clave podría esperar a la rotación para obtener la nueva clave si mantiene acceso persistente.
Evidence:archivo: vault_setup_sh: Línea 94 (cron '0 4 1 5,11 *')
Escenario: La cadencia fija de rotación permite al atacante planificar su ataque. Si ya tiene acceso parcial, podría interceptar el proceso de rotación.
Impacto: Posible obtención de nuevas claves KEK si el atacante mantiene acceso en el momento de la rotación, permitiendo cifrado/descifrado de datos posteriores.
Rationale: La cadencia fija de rotación permite al atacante planificar su ataque. Si ya tiene acceso parcial, podría interceptar el proceso de rotación (ej. capturar la nueva clave en el momento de su creación) o usar la nueva clave para ampliar sus privilegios.
Sources: adversary · Deduped:
Falta de validación de permisos del VAULT_TOKEN
LOW WEAK not-verifiedDescripción: El script solo verifica que VAULT_TOKEN esté definido, no que tenga los permisos requeridos (sys/* y transit/keys/*). Un usuario malintencionado podría pasar un token con permisos limitados, causar un error, y luego analizar los logs para inferir detalles de la configuración.
Evidence:archivo: vault_setup_sh: Línea 18-22 (solo check de no vacío, sin validación de permisos)
Escenario: Al no validar los permisos del token, un atacante podría inyectar tokens con permisos insuficientes y analizar los errores para entender qué endpoints existen o cómo está configurado Vault.
Impacto: Posible revelación de detalles de configuración o permisos actuales de Vault a través de mensajes de error.
Rationale: Al no validar los permisos del token, un atacante podría inyectar tokens con permisos insuficientes y analizar los errores para entender qué endpoints existen o cómo está configurado Vault, facilitando ataques más sofisticados.
Sources: adversary · Deduped:
LN-Q6-offramp-strategy
Findings: 8
Abuso de slippage tolerance en mercados extremos
CRITICAL STRONG verifiedDescripción: El atacante explota la alta tolerancia de slippage en Venezuela (800 bps) y Argentina (500 bps) para forzar rechazos y drenar fondos. Simula fluctuaciones artificiales usando su rol como anchor malicioso, generando quotes con tasas extremas que superen los umbrales, causando reembolsos que en realidad son arbitraje encubierto.
Evidence:slippage_strategy_md:Tabla 'Slippage tolerance per país' (VE 800 bps, AR 500 bps) y pseudocode 'execute_offramp' que rechaza si drift_bps > MAX_SLIPPAGE_BPS
Escenario: El anchor malicioso envía cotizaciones inicialmente bajas para atraer usuarios, luego subir drásticamente la tasa en la fase de ejecución, superando el 8% y forzando un rechazo.
Impacto: Drenaje masivo de fondos del wallet GDGQ...AUF al forzar reembolsos fraudulentos bajo falsos movimientos de mercado
Rationale: El ataque es fácilmente explotable y tiene un impacto financiero significativo. ADVERSARY proporcionó una descripción detallada y CODER verificó la dependencia del anchor, lo cual confirma el riesgo CRITICAL.
Sources: adversary · Deduped: A-001
Bypass del oracle floor mediante manipulación de fuentes secundarias
HIGH STRONG verifiedDescripción: El atacante, actuando como auditor regulador, identifica que el 'market floor rate' depende de fuentes como Bloomberg/Reuters no configuradas aún (sección 'Implementación pendiente'). Al no existir oráculo secundario validado, el atacante como anchor puede reportar falsas tasas 'floor' inferiores, permitiendo operaciones riesgosas que aparentemente cumplen con el umbral.
Evidence:slippage_strategy_md:Sección 'Three-tier price oracle' menciona 'cross-validated rate (consulta secundaria a Bloomberg/Reuters API o anchor backup)' y 'Implementación pendiente' que no ha sido completada
Escenario: El atacante reporta tasas falsas por debajo del 'market_floor', permitiendo operaciones riesgosas.
Impacto: Bypass de controles contra tasas ilegales o sancionadas, permitiendo transacciones que violen regulaciones (ej. lavado de dinero en mercados sancionados)
Rationale: La dependencia de oráculos externos no implementados deja un vacío y el ataque es moderadamente explotable, lo cual confirma la severidad HIGH.
Sources: adversary · Deduped: A-002
Reutilización de quote_ids para ataques de replay
HIGH STRONG verifiedDescripción: El atacante intercepta un quote_id válido y reenvía la solicitud de ejecución después de que el anchor ha ajustado su tasa para que el slippage sea excesivo, forzando un reembolso. Al reutilizar el quote_id, el atacante podría obtener fondos duplicados o bloquear el sistema.
Evidence:slippage_strategy_md:Ejemplo de POST /api/execute con 'quote_id' y pseudocode que no menciona prevención de replay (ej. nonce único o uso una vez)
Escenario: El atacante obtiene un quote_id válido e intercepta la tasa del anchor para forzar un reembolso fraudulento.
Impacto: Fugas de fondos si el sistema permite ejecutar múltiples veces el mismo quote_id o no invalida tras expiración
Rationale: El pseudocode no menciona mecanismos anti-replay y el ataque es fácilmente explotable, lo cual confirma la severidad HIGH.
Sources: adversary · Deduped: A-004
Falta de límite máximo por transacción
MEDIUM WEAK not-verifiedDescripción: No se define un límite máximo para el monto de una transacción, lo que podría exponer al sistema a riesgos financieros.
Evidence:slippage_strategy.md: No se menciona límite de monto en slippage_strategy.md
Escenario: Un usuario realiza una transacción de gran volumen sin restricción, exponiendo al sistema a pérdidas significativas si el slippage excede la tolerancia.
Impacto: Pérdidas financieras por transacciones masivas rechazadas, afectando liquidez y confianza.
Rationale: El documento no establece un límite máximo global para el monto de una transacción. Sin embargo, CODER verificó que no hay evidencia directa en el texto proporcionado y no se niega explícitamente su existencia, lo cual degrada la severidad a MEDIUM.
Sources: reasoner, coder · Deduped: R-001, C-001
Falta de velocity checks para prevenir abuso
MEDIUM WEAK not-verifiedDescripción: No hay mecanismos para detectar y prevenir abuso mediante múltiples transacciones en un corto período.
Evidence:slippage_strategy.md: No se menciona control de velocidad o transacciones frecuentes.
Escenario: Un usuario o bot realiza múltiples transacciones rápidas para explotar fluctuaciones temporales, evadiendo controles.
Impacto: Posible fraude o abuso del sistema, generando pérdidas o mal uso de recursos.
Rationale: El documento no menciona controles de velocidad, pero tampoco se niega explícitamente su existencia. No hay evidencia directa en el texto proporcionado, lo cual degrada la severidad a MEDIUM.
Sources: reasoner, coder · Deduped: R-002, C-002
Dependencia única en el oracle principal
MEDIUM STRONG verifiedDescripción: El oracle principal depende únicamente del anchor, sin redundancia suficiente.
Evidence:Three-tier price oracle: 1. Anchor quoted rate (sep-38 quote endpoint · típicamente válido 5min)
Escenario: El anchor tiene un fallo o manipula su tasa, afectando todas las cotizaciones.
Impacto: Cotizaciones incorrectas o manipuladas, llevando a transacciones no deseadas o rechazos injustificados.
Rationale: La estrategia depende únicamente del anchor como primera capa del oracle, lo cual es un riesgo confirmado por CODER y ADVERSARY. Sin embargo, la severidad se mantiene en MEDIUM debido a que no hay evidencia de una falla crítica directa.
Sources: reasoner, coder · Deduped: R-003
Falta de reconciliación automática con el partner offramp
MEDIUM STRONG verifiedDescripción: No se describe un proceso de reconciliación automática con los partners offramp.
Evidence:Dashboard `dashboard.cuandeoro.com` debe mostrar:
- Slippage histórico por país (boxplot p50/p90/p99 últimos 30d)
- Rejections por país (% de quotes que no ejecutaron por exceder slippage)
- Net spread captured por Cuandeoro (informativo · transparencia)
Escenario: Desincronización entre registros de Cuandeoro y el partner, generando discrepancias no detectadas.
Impacto: Errores no resueltos en transacciones, disputas con partners y posibles pérdidas.
Rationale: El documento menciona solo un dashboard informativo sin mecanismos de reconciliación automática. CODER verificó esta falta de control, manteniendo la severidad en MEDIUM.
Sources: reasoner, coder · Deduped: R-004
Explotación de la fase de quote lock con TTL 5 minutos
MEDIUM STRONG verifiedDescripción: El atacante, como usuario malicioso, genera múltiples quotes en cadena para bloquear fondos. Al mantener activos quotes expirando en momentos estratégicos, evita que otros usuarios ejecuten sus operaciones, causando un DoS en mercados con alta demanda (ej. Venezuela).
Evidence:slippage_strategy_md:Ejemplo de 'Fase 1 · Quote lock (TTL 5min)' y pseudocode que gestiona 'expired(quote)'
Escenario: El atacante envía miles de quotes simultáneos, forzando al sistema a gestionar expiraciones y reembolsos.
Impacto: Denegación de servicio en offramps críticos al saturar el sistema con quotes expirantes, impidiendo operaciones legítimas
Rationale: El TTL corto (5 minutos) es vulnerable a ataques de saturación y el ataque es moderadamente explotable, lo cual confirma la severidad MEDIUM.
Sources: adversary · Deduped: A-003
LN-Q7-env-secrets
Findings: 4
Credenciales en texto plano
CRITICAL STRONG verifiedDescripción: Las variables de entorno ARCHIVOS_USER y ARCHIVOS_PASS almacenan credenciales en texto plano, violando R90-KMS que exige uso de Vault Transit con sufijo _ENC. Un atacante con acceso al .env obtiene credenciales directamente, permitiendo acceso no autorizado a los recursos de archivos.
Evidence:ARCHIVOS_USER=marco
ARCHIVOS_PASS=cuandeoro2026
Escenario: Un atacante con acceso al archivo .env puede leer directamente las credenciales ARCHIVOS_USER y ARCHIVOS_PASS, lo que permite acceso no autorizado a los recursos de archivos.
Impacto: Exposición de acceso a recursos críticos, violación de políticas de seguridad, posibles pérdidas financieras o datos.
Rationale: Las credenciales en texto plano violan directamente la norma R90-KMS y permiten un acceso no autorizado fácilmente explotable.
Sources: reasoner, coder, adversary · Deduped: R-001, A-001
Uso de credenciales en formato predecible
HIGH WEAK not-verifiedDescripción: La contraseña 'cuandeoro2026' sigue un patrón obvio (nombre de la empresa + año). Un atacante podría adivinar otras credenciales similares en otros servicios o predecir futuras contraseñas. Además, el usuario 'marco' podría ser un nombre de empleado real, permitiendo ataques de ingeniería social o phishing.
Evidence:.env:ARCHIVOS_PASS=cuandeoro2026
Escenario: Un atacante con conocimiento de la estructura de credenciales y acceso a otros servicios de Cuandeoro puede intentar usar patrones similares para acceder a múltiples sistemas.
Impacto: Posible acceso a otros sistemas usando patrones similares, debilitando la seguridad global.
Rationale: Aunque no está verificado por CODER, el patrón de credenciales es predecible y aumenta el riesgo de comprometer múltiples servicios si siguen el mismo patrón.
Sources: adversary · Deduped:
Exposición de URL base de archivos públicos
MEDIUM WEAK not-verifiedDescripción: El atacante conoce la URL base 'https://archivos.cuandeoro.ie', lo que permite escanear subdominios o rutas no documentadas. Podría encontrar endpoints sensibles o directorios ocultos, como /admin o /backup, realizando ataques de fuerza bruta en rutas o explotando vulnerabilidades en servicios asociados a esta URL.
Evidence:.env:ARCHIVOS_PUBLIC_BASE=https://archivos.cuandeoro.ie
Escenario: El atacante con acceso al archivo .env y herramientas de escaneo automatizado puede mapear el entorno y encontrar rutas inseguras.
Impacto: Posible exfiltración de datos o acceso a recursos no autorizados a través de rutas inseguras.
Rationale: La exposición de la URL base facilita el mapeo del entorno, aunque no es crítico por sí solo, combina con otras vulnerabilidades para aumentar el riesgo.
Sources: adversary · Deduped:
Falta de validación de tamaño de archivos subidos
MEDIUM WEAK not-verifiedDescripción: No se encuentra lógica que valide el tamaño máximo de los archivos antes de ser subidos.
Evidence:ARCHIVOS_MAX_MB=500 (solo definición en .env, sin validación en código)
Escenario: Un usuario malicioso podría intentar subir un archivo muy grande que exceda la memoria o capacidad del servidor.
Impacto: Posible saturación de recursos del servidor y denegación de servicio.
Rationale: La falta de validación puede causar problemas de rendimiento, pero no es tan crítica como otras vulnerabilidades identificadas.
Sources: coder · Deduped: