Catálogo de detección

26 reglas, y lo que cada una no significa

Cada regla es una afirmación causal que debe poder defenderse con la evidencia que adjunta. Por eso todas declaran su umbral, su evidencia y sus límites: una alerta sin siguiente paso entrena a ignorar alertas.

🔴 Crítica 🟠 Alta 🟡 Media ⚪ Baja

🔑 BTC-KEY

Procedencia de la semilla

De dónde vino la clave y si se puede demostrar.

BTC-KEY-001 · 🔴 Crítica

Semilla creada con firmware afectado

La semilla nació de un proceso con un defecto publicado. El atacante no necesita robar nada: reconstruye la clave y firma una transacción perfectamente válida.

Dispara: Un firmante coincide con un aviso activo: mismo fabricante, modelo en la lista, canal (standard/edge) coincidente y firmwareAtSeedCreation dentro del rango afectado.

No significa: No significa que los fondos se hayan movido, ni que vayan a moverse hoy.

BTC-KEY-002 · 🟠 Alta · 🟡 Media

Firmware de creación desconocido

La ausencia de dato es el hallazgo. Si no puedes demostrar con qué firmware nació una clave, no puedes descartar ningún aviso presente ni futuro.

Dispara: firmwareAtSeedCreation ausente o igual a unknown en algún firmante.

No significa: No acusa al dispositivo: acusa a la trazabilidad.

BTC-KEY-003 · 🟡 Media

Origen de entropía desconocido

La aplicación desconoce cómo se creó la semilla: si la generó el dispositivo, se importó o se creó con una fuente independiente.

Dispara: seedOrigin === "unknown". Valores válidos: device, dice, external, unknown.

No significa: No dice que la entropía sea mala. Dice que nadie puede afirmar que sea buena.

🏛️ BTC-CUSTODY

Arquitectura de custodia

Si la arquitectura contiene el compromiso de un firmante.

BTC-CUSTODY-001 · 🔴 Crítica

Fondos de alto valor dependen de una sola clave

Una sola firma puede gastar todos los fondos de esa wallet. Comprometer una clave es perderlo todo.

Dispara: balanceSats >= highValueThresholdSats y walletType === "single-sig".

No significa: Single-sig no es «inseguro» en abstracto: la regla habla de concentración por encima de un umbral que tú eliges.

BTC-CUSTODY-002 · 🟠 Alta · 🟡 Media

Multisig sin diversidad de implementación

El quorum existe, pero un fallo común de firmware podría afectar a varios firmantes a la vez. Sobre el papel hay tres llaves; en la práctica hay un solo punto de fallo.

Dispara: walletType === "multisig" y quorum.independentVendors < 2.

No significa: No dice que el multisig esté mal formado: dice que no protege de lo que dice proteger.

BTC-CUSTODY-003 · 🟠 Alta · 🟡 Media

Quorum sin tolerancia a fallos (N-de-N)

Un 3-de-3 no reparte el riesgo: lo multiplica. Sigue haciendo falta comprometer todas las claves para robar, pero basta perder una para que los fondos queden irrecuperables.

Dispara: walletType === "multisig", quorum.total > 1 y quorum.required === quorum.total.

No significa: No es un problema de robo, es un problema de pérdida. Es la configuración que más fondos ha congelado para siempre.

💸 BTC-TX

Gasto observado

Movimientos que no coinciden con ninguna aprobación registrada.

BTC-TX-001 · 🔴 Crítica

Gasto observado sin aprobación conocida

La cadena recibió una transacción válida fuera del flujo de autorización que tú registraste.

Dispara: El evento marca spendsWatchedWallet y su approvalHash no coincide con ninguna aprobación registrada.

No significa: No afirma que sea un robo. Afirma que nadie registró la aprobación.

BTC-TX-002 · 🔴 Crítica

Barrido del saldo de una wallet vigilada

Ese patrón es el de un vaciado, no el de un pago. Cambia la urgencia respecto a BTC-TX-001.

Dispara: Un gasto sin aprobación cuyo valueSats alcanza el 90 % o más del saldo declarado de la wallet.

No significa: Sin valueSats la regla no se activa: sin importe no se puede distinguir un pago de un vaciado, y prefiere callar a inventar.

BTC-TX-003 · 🔴 Crítica

Varios gastos sin aprobación en ventana corta

Un gasto sin registrar es un error de proceso; una ráfaga es extracción activa.

Dispara: Dos o más gastos sin aprobación de la misma wallet dentro de una ventana de 60 minutos.

No significa: No sustituye a BTC-TX-001: cada gasto sigue generando el suyo. Esta regla añade el patrón temporal.

🔗 BTC-NODE

Salud de la observación

Si la aplicación está viendo la realidad o está ciega.

BTC-NODE-001 · 🟠 Alta

Bitcoin Core no disponible

El canal de observación no puede validar el estado local de Bitcoin. No habla de tus fondos: habla de tu capacidad de verlos.

Dispara: La conexión RPC falla.

No significa: Mientras esté activo, la vigilancia de gastos está ciega: no es que no haya problemas, es que no se pueden ver.

BTC-NODE-002 · 🟡 Media

Nodo todavía no sincronizado

La observación de transacciones puede estar incompleta o atrasada.

Dispara: initialBlockDownload verdadero o verificationProgress < 0,999.

No significa: Un nodo sincronizando no está roto: está trabajando. La regla evita que se confíe en sus respuestas mientras tanto.

BTC-NODE-003 · 🟠 Alta

Nodo sin peers

La observación local está aislada de la red Bitcoin.

Dispara: connections === 0.

No significa: Es alta porque un nodo aislado puede mostrar una punta antigua y hacerte creer que no ha pasado nada.

BTC-NODE-004 · 🟡 Media

Presión elevada de mempool

Transacciones de menor tarifa pueden ser expulsadas del mempool local.

Dispara: mempoolUsageBytes / mempoolMaxBytes >= 0,9.

No significa: Una transacción que desaparece del mempool no está «perdida»: puede haber sido expulsada o reemplazada.

👤 BTC-PRIVACY

Datos personales

La superficie de una wallet incluye a quien la usa.

BTC-PRIVACY-001 · 🔴 Crítica · 🟡 Media

Acceso masivo a datos de clientes

Un proveedor o usuario accedió a un volumen de información personal superior al patrón esperado.

Dispara: Evento de tipo bulk_customer_data_access.

No significa: Que no se filtre ni una clave no significa que no haya subido el riesgo: con nombre, teléfono y dirección, el phishing deja de ser genérico.

BTC-PRIVACY-002 · 🟠 Alta

El proveedor filtrado fabrica tus firmantes

Correlaciona la filtración con tu inventario: la diferencia entre «hubo una filtración en un fabricante» y «hubo una filtración en el fabricante de dos de tus firmantes».

Dispara: El vendor de un evento de privacidad coincide, sin distinguir mayúsculas, con el fabricante de algún firmante del inventario.

No significa: No implica que tus claves estén comprometidas. Implica que quien te escriba puede saber qué dispositivo tienes.

🗓️ BTC-INTEL

La inteligencia tiene fecha

Un verde sobre avisos sin revisar es una tranquilidad falsa.

BTC-INTEL-001 · 🟡 Media · 🟠 Alta

Matriz de avisos sin verificar

Un hallazgo ausente puede significar que la inteligencia está vieja, no que no haya problema.

Dispara: El verifiedAt más reciente de config/advisories.json supera advisoryMaxAgeDays.

No significa: No dice que exista un aviso nuevo que te afecte. Dice que nadie ha mirado, y que por tanto el verde no significa lo que parece.

BTC-INTEL-002 · 🟠 Alta

Sin matriz de avisos cargada

No hay nada con lo que contrastar la procedencia de las claves: la detección principal del producto queda desactivada.

Dispara: config/advisories.json vacío o ilegible.

No significa: Un panel sin avisos no está «limpio»: está desarmado.

BTC-INTEL-003 · 🟡 Media

Avisos sin fecha de verificación

La matriz existe pero no registra su propia frescura, así que nadie puede saber si está al día.

Dispara: Ninguna entrada declara verifiedAt ni publishedAt con formato de fecha válido.

No significa: No cuestiona el contenido de los avisos, sino la posibilidad de saber cuándo se comprobaron.

🖥️ BTC-OPSEC

Postura de la instalación

La herramienta con la que miras tus claves también se audita.

BTC-OPSEC-001 · 🔴 Crítica · 🟡 Media

El panel escucha fuera de loopback

La aplicación no tiene autenticación porque asume un único operador en 127.0.0.1. Con el puerto abierto, cualquiera en la red ve el inventario de wallets y saldos.

Dispara: HOST no es una dirección de loopback.

No significa: Dentro de un contenedor no es un fallo: quien decide la exposición real es el mapeo de puertos del host. Un detector que grita en el despliegue soportado enseña a ignorarlo.

BTC-OPSEC-002 · 🟡 Media

Inventario con saldo declarado en modo demostración

El modo demostración mantiene todo en memoria: al cerrar la aplicación se pierde lo registrado.

Dispara: DEMO_MODE=true mientras el inventario declara saldo mayor que cero.

No significa: No es un fallo de seguridad: es el aviso de que estás usando el modo equivocado para lo que quieres hacer.

BTC-OPSEC-003 · 🟠 Alta · 🟡 Media

Clave de datos por debajo del mínimo recomendado

La entropía se estima por la longitud efectiva y el alfabeto realmente usado, de modo que una clave larga pero repetitiva no puntúa como larga.

Dispara: En modo persistente, la entropía estimada de ROOTCAUSE_DATA_KEY es menor que 128 bits.

No significa: La estimación no mide calidad criptográfica: detecta el caso real, que es alguien escribiendo clave123 en un archivo de configuración.

BTC-OPSEC-004 · 🟠 Alta

RPC de Bitcoin Core remoto habilitado

Se desactivó una defensa que existe por una razón documentada por el propio Bitcoin Core: el RPC concede control significativo sobre el nodo y no debe exponerse a la red.

Dispara: ALLOW_REMOTE_RPC=true.

No significa: La allowlist de once métodos de lectura sigue vigente: esto amplía el canal, no los permisos.

BTC-OPSEC-005 · 🟡 Media

RPC autenticado con usuario y contraseña

La cookie de Bitcoin Core rota sola y no hay que escribirla en ningún sitio. Una contraseña estática vive en un archivo o en una variable de entorno, que es donde acaban filtrándose las cosas.

Dispara: Hay BITCOIN_RPC_USER o BITCOIN_RPC_PASSWORD y no hay BITCOIN_RPC_COOKIE_FILE.

No significa: No implica que la contraseña sea débil: implica que existe escrita en algún sitio.

BTC-OPSEC-006 · 🟡 Media

Watchtower apagado con wallets de alto valor

Nadie está observando el nodo: un gasto fuera de política no se detectaría hasta el próximo análisis manual.

Dispara: Existe al menos una wallet por encima del umbral de alto valor y WATCHTOWER_ENABLED=false.

No significa: Encender el watchtower sin nodo disponible no vigila nada: comprueba también BTC-NODE-001.

BTC-OPSEC-007 · ⚪ Baja

Límites de petición por encima de lo razonable

Amplía la superficie de abuso local sin aportar nada al uso normal del panel.

Dispara: RATE_LIMIT_PER_MINUTE >= 5000 o REQUEST_BODY_LIMIT_BYTES >= 1 MiB.

No significa: Es baja a propósito: describe holgura innecesaria, no una puerta abierta.

BTC-OPSEC-008 · 🔴 Crítica

La cadena de auditoría no verifica

El historial fue modificado después de escribirse, por manipulación del archivo de estado o por corrupción del almacenamiento.

Dispara: Una entrada del registro no encadena con el hash de la anterior.

No significa: La primera acción no es arreglar: es preservar. Un registro alterado es el indicio, no el problema.