Ocho hallazgos de seguridad un sábado por la mañana
Las auditorías sacan cosas a la luz. La decisión honesta es darles la bienvenida, corregirlo todo, y enviar barreras permanentes, que es exactamente cómo un runtime se gana la confianza empresarial.
La auditoría llegó a la bandeja de entrada a finales de la semana pasada. Para el sábado por la mañana tenía el informe abierto en una pantalla y la base de código abierta en la otra. Ocho hallazgos críticos o altos. El tipo de contenido de bandeja de entrada que define un fin de semana.
Esto era debida diligencia empresarial. Un socio potencial le había pedido a su equipo de seguridad que hiciera un pase sobre la superficie pública de la API antes de dejar que sus abogados avanzaran. Los hallazgos eran específicos, bien explicados, y completamente justos. También eran el tipo de cosas ante las que un flujo de trabajo impulsado por agentes te hace especialmente vulnerable si no eres deliberado sobre defenderte de ellas.
Para el final del sábado, cada hallazgo tenía un PR que lo resolvía. Este es el post sobre qué fue cada uno.
Cuáles fueron las categorías
Voy a hablar de categorías en lugar de detalles específicos de exploits porque los detalles específicos ya están corregidos y no son interesantes para un competidor; las categorías son lo que otros equipos querrán defender.
Uno: validación de entrada en la superficie pública de REST. Varios endpoints confiaban en sus entradas más de lo que deberían. Específicamente, límites de longitud en entradas de cadena, límites de rango en entradas numéricas, y validación estructural en payloads JSON. Ninguna de las validaciones faltantes era catastrófica por sí sola. La combinación de “sin límite de longitud aquí más sin límite de tasa allá más sin verificación de auth en este endpoint de administración” es el tipo de pila que se vuelve catastrófica una vez que un atacante ha descubierto la superficie.
Dos: una credencial fija en código en un archivo de configuración. Distinto del hallazgo de HMAC de hace unos fines de semana. Este era una plantilla de configuración que tenía una credencial real confirmada en la versión de ejemplo. La intención había sido distribuir una credencial de ejemplo que fuera un marcador de posición; lo que se distribuyó fue una credencial de ejemplo que era un valor real del entorno local de un desarrollador. Rotación, eliminación del ejemplo, incorporación al pase de escaneo de secretos en CI.
Tres: negociación insegura de cipher suites. Un subsistema que negocia TLS con un servicio externo estaba aceptando cipher suites que no deberían ser aceptables en 2026. Específicamente, varias suites previas a TLS 1.3 con debilidades conocidas. La corrección fue restringir la lista de cipher suites a un conjunto exclusivo de TLS 1.3, con una vía de escape documentada (una bandera explícita) para pruebas contra sistemas heredados de socios.
Cuatro: un use-after-free en el límite de la API en C. La API en C de una de las DLLs del runtime tenía una función que devolvía un puntero a estado interno, que el llamador podía seguir usando después de que el estado interno hubiera sido liberado por una llamada posterior en el mismo handle. Trampa clásica de API en C. La corrección fue cambiar de semántica de “puntero en poder del llamador” a semántica de “handle opaco en poder del llamador con un accesor get-by-handle”. El accesor devuelve una copia fresca del puntero durante la llamada y la memoria subyacente no queda expuesta.
Cinco: un agujero de thread-safety en la capa de licencias. Dos hilos podían competir por el mismo objeto de estado de licencia durante llamadas de verificación concurrentes. Bajo carga, un hilo podía ver un estado parcialmente actualizado y llegar a conclusiones incorrectas sobre la validez de la licencia. La corrección fue un lock de lectura-escritura adecuado alrededor del estado, con la ruta de verificación optimizada para el caso común (licencia válida, sin necesidad de cambio de estado).
Seis: un bypass de autorización en un endpoint de administración. Uno de los endpoints de administración tenía una verificación de autenticación pero no una verificación de autorización. Cualquier usuario autenticado podía llamarlo, incluidos usuarios sin el rol de administrador. La corrección fue añadir la verificación de rol, escribir una prueba unitaria que ejercite tanto la ruta “autenticado-como-admin permitido” como la ruta “autenticado-pero-no-admin denegado”, y auditar cada otro endpoint de administración en busca del mismo patrón. Otros tres endpoints tenían el mismo problema. Los cuatro ahora son correctos.
Siete: registro insuficiente en fallos de autenticación. Cuando un usuario intentaba autenticarse y fallaba, el runtime registraba el intento pero no registraba suficiente contexto para investigar un patrón de fuerza bruta o credential stuffing. La corrección fue añadir registro estructurado en cada fallo de autenticación con la dirección IP, el contador de límite de tasa para esa IP, y el método de autenticación intentado. Preservando la privacidad (no se registra contenido de contraseñas), pero con suficiente contexto para investigar cuando una investigación se vuelve necesaria.
Ocho: retraso en la actualización de dependencias. Varias de las dependencias de terceros que el runtime incorpora tenían versiones con vulnerabilidades conocidas fijadas en el manifiesto. La corrección fue actualizar cada una a la última versión parcheada, ejecutar la suite de pruebas contra las actualizaciones, y resolver el pequeño número de cambios de forma de API que las actualizaciones requirieron. Dos de las ocho actualizaciones requirieron cambios de adaptador en nuestro código; las otras seis fueron directas. Dependabot ahora está configurado para señalar esto automáticamente.
Qué aprendí de un fin de semana de trabajo de seguridad
Tres cosas. No sorprendentes. Vale la pena decirlas.
Los hallazgos de seguridad se agrupan. Ocho hallazgos es mucho para salir a la luz de una vez. El patrón, mirando hacia atrás, es que todos comparten una raíz común: el runtime había estado creciendo rápido en un flujo de trabajo impulsado por agentes, con los agentes implementando cosas correctas de forma aislada. Las preocupaciones transversales como la seguridad son exactamente el tipo de cosa que se escapa de la revisión por PR. La auditoría detecta lo que la revisión pasó por alto. Programa las auditorías.
Algunos hallazgos son modos de fallo impulsados por agentes. El use-after-free en la API en C es el tipo de cosa que un agente escribe cuando el prompt dice “expón este estado interno al llamador” sin especificar la semántica de propiedad. El agujero de thread-safety en la capa de licencias es similar. Ambos detectan el mismo patrón: los agentes a los que no se les pregunta sobre propiedad y concurrencia producirán código que ignora ambas cosas.
Algunos hallazgos son modos de fallo impulsados por el ritmo. El retraso en la actualización de dependencias no es un problema de agentes. Es un problema de “enviar rápido y no tener a una persona cuyo trabajo sea mantener las dependencias frescas.” La corrección es proceso (Dependabot) y disciplina (actuar sobre las alertas de Dependabot). La corrección no es “ser más inteligente.”
Las nuevas defensas
Barreras permanentes que se establecieron este fin de semana.
Un pase de escáner de seguridad en CI. Análisis estático para validación de entrada, escaneo de secretos, y política de cipher suites. Cada PR ejecuta el escaneo. Los PRs que introducen nuevos hallazgos se marcan para revisión.
Un patrón de prueba para endpoints de administración. Cada endpoint de administración en la API ahora tiene una prueba emparejada que ejercita tanto la ruta admin-permitido como la ruta no-admin-denegado. El patrón se hace cumplir mediante una verificación en CI que escanea en busca de decoradores @admin_required y falla el build si el decorador está presente sin una prueba emparejada correspondiente.
Una anotación de thread-safety en el estado compartido. Cada objeto de estado compartido en el runtime ahora tiene una anotación explícita sobre su modelo de concurrencia: inmutable, protegido por lock, sin lock con happens-before explícito, o de un solo hilo. La anotación es parte del tipo. El código que toca el estado tiene que satisfacer la anotación. El compilador la hace cumplir para los casos protegidos por lock e inmutables; el resto queda en manos de la revisión.
Una auditoría de seguridad mensual en el calendario. Sin esperar a que un socio la pida. La auditoría es un ítem fijo el segundo sábado de cada mes. La primera se ejecuta en abril.
Qué deberían llevarse los socios y constructores de esto
Si estás evaluando un motor para una asociación y estás a punto de pedir una auditoría, este equipo la recibirá con gusto. Las auditorías sacan cosas a la luz. Las cosas se corrigen. La base de código mejora. La relación con el socio mejora. La disciplina de dar la bienvenida a la auditoría es más importante que cualquier hallazgo específico.
Si eres un profesional de seguridad empresarial leyendo esto, estoy abierto a sugerencias sobre la cadencia de la auditoría y sobre las cosas específicas que desearías que más equipos de motores auditaran. Los hallazgos de este fin de semana fueron los obvios. Los no obvios son los próximos que quiero encontrar.
Si estás ejecutando un flujo de trabajo impulsado por agentes y no has hecho una auditoría de seguridad recientemente, hazla. El patrón de “el agente escribe código correcto de forma aislada que pasa por alto preocupaciones transversales” es universal en esta forma de flujo de trabajo. La auditoría es cómo detectas las preocupaciones transversales. No hay otra forma que haya encontrado.
Verificación de fin de semana. Ocho hallazgos cerrados. Seis nuevas defensas establecidas. La próxima auditoría está en el calendario. La relación con el socio avanza.
De vuelta a construir.
Un runtime espacial que pasa la debida diligencia
RakuAI está construido para socios empresariales y fabricantes de gafas inteligentes: auditado, endurecido, y honesto al respecto. Descubre cómo diseñamos para el estándar de seguridad que tu equipo tiene que superar.