Algorithmic DoS en libminikin.so

Wednesday, June 24, 2026
Algorithmic DoS en libminikin.so – Cómo un texto de 70 KB puede congelar casi cualquier app Android 
 

Un texto de 70.000 caracteres puede congelar casi cualquier app de  Android durante 10–16 segundos. No es corrupción de memoria. Es un ataque algorítmico que explota la complejidad O(n²) del motor de diseño de texto nativo de Android. Y lo peor: cualquier aplicación con un TextView es vulnerable.

A diferencia de muchas vulnerabilidades que requieren aplicaciones de prueba específicas para su reproducción, varios de los vectores documentados pueden activarse simplemente mediante enlaces especialmente construidos que son procesados por componentes estándar del sistema Android. Esto amplía significativamente la superficie de exposición potencial

He documentado 31 vectores en 9 empresas, incluyendo Google, Meta, Microsoft, Mozilla, Opera, DuckDuckGo, Brave, Tor Project y Xiaomi. El fallo reside en libminikin.so, el motor de diseño de texto de Android, y afecta a todos los dispositivos con Android 9 a 16.


1. El problema: Algoritmos que se vuelven en tu contra

libminikin.so implementa el algoritmo de salto de línea óptimo (Knuth-Plass) en la función LineBreakOptimizer::computeBreaks. Este algoritmo tiene complejidad O(n²) en el peor caso: si duplicas la longitud del texto, el tiempo de procesamiento se multiplica por cuatro.

Para un texto normal de 200 caracteres, el tiempo es imperceptible. Pero para uno de 70.000 caracteres con la estructura adecuada, el algoritmo ejecuta millones de operaciones y bloquea el hilo de la interfaz durante más de 10 segundos.

El vector documentado en libminikin no requiere una aplicación de demostración específica. En los escenarios analizados, basta con que un componente del sistema represente una URL especialmente construida en un TextView para activar el cálculo intensivo del algoritmo de composición de texto.

📌 Idea clave: No es la longitud, es la estructura. Una URL con caracteres como #, /, % y multiplica el número de "candidatos a salto de línea", y el algoritmo se dispara.

2. La estructura del ataque: Caracteres que multiplican el caos

Carácter Función en la URL Efecto en libminikin
# Fragmento (separador lógico) Duplica las decisiones de salto de línea
/ Separador de rutas Cada barra es un punto de ruptura → O(n²) con el número de barras
% Codificación porcentual Expansión UTF-8 → UTF-16, fragmenta la cadena
Carácter multibyte Propiedades de salto de línea ambiguas → el algoritmo explora ambas opciones

El patrón óptimo repite miles de veces. Cada 9 bytes generan múltiples puntos de decisión y el algoritmo explota.

Resultado: La UI se congela durante 10–16 segundos. El stack trace nativo confirma que libminikin es el único responsable.

4. Vectores de ataque: Más allá de los navegadores

El fallo no se limita a los navegadores. Cualquier aplicación que muestre texto en un TextView sin truncar es un vector de ataque:

Componente / Aplicación ¿Muestra URL larga? Vulnerabilidad observada
Chrome (menú contextual) ✅ ANR de 5+ segundos
Firefox (diálogo externo) ✅ ANR de 16 segundos (enlace real de Google Drive)
Opera / Opera Mini ✅ Crash con TransactionTooLargeException
DuckDuckGo Sí (historial) ✅ Bucle de cierre permanente
Google drive ⚠️ Potencial
WhatsApp (vista previa de enlace) ⚠️ Potencial
Cualquier app con TextView ✅ Confirmado con PoC

5. El vector crítico: STA-015-DL (SystemUI crash loop)

🔥 CVSS 8.6 (CRÍTICO) – Un solo clic en un enlace de Google Drive puede provocar un bucle de cierre de SystemUI que requiere reinicio forzado.

La cadena de ataque STA-015-DL demuestra que el problema trasciende las aplicaciones y afecta a SystemUI, la interfaz del sistema:

  1. La víctima hace clic en un archivo HTML alojado en Google Drive.
  2. Google Drive lanza un Intent.ACTION_VIEW con una URL malformada.
  3. La URL bypasea todas las validaciones del navegador porque llega a través de callingPackage=com.google.android.apps.docs (certificado por Android).
  4. La URL corrompe el estado de TaskPersister en disco.
  5. SystemUI intenta leer el estado → DeadObjectExceptionbucle de cierre.
  6. Recuperación: reinicio forzado del dispositivo.

Evidencia de campo: Un dispositivo en producción (Xiaomi Redmi Note 14 5G, Android 16) registró 85 SystemUI crashes en 4 días, con un tiempo mínimo de supervivencia de 374ms.

// SystemUI crash en el arranque – bugreport 2026-05-26 // Process-Runtime: 374ms – crashea antes de renderizar cualquier UI android.os.BadParcelableException: Failure retrieving array; only received 1 of 4 at android.content.pm.BaseParceledListSlice.<init>(...) at com.android.wm.shell.sysui.ShellInit.init(...) ← crash en el arranque Caused by: android.os.DeadObjectException: Transaction failed on small parcel

6. Stack traces nativos (evidencia forense)

Chrome – Menú contextual (24 de mayo de 2026)

// ANR — Chrome PID 3533 "main" prio=5 tid=1 Native ← UI THREAD BLOCKED native: minikin::getPrevWordBreakForCache libminikin.so native: minikin::LayoutCacheKey::LayoutCacheKey libminikin.so native: minikin::LayoutCache::getOrCreate libminikin.so native: minikin::StyleRun::getLineMetrics libminikin.so native: minikin::MeasuredText::getLineMetrics libminikin.so native: minikin::LineBreakOptimizer::computeBreaks ← O(n²) en URL larga native: minikin::breakLineOptimal libminikin.so native: android::nComputeLineBreaks libhwui.so at android.widget.TextView.onMeasure (TextView.java:11486) at org.chromium.chrome.browser.contextmenu.ContextMenuListView.onMeasure ↑ MENÚ CONTEXTUAL DE CHROME — long-press en URL sobredimensionada

Firefox – Diálogo de aplicación externa (10 de junio de 2026)

// org.mozilla.firefox PID 3506 — ANR 2026-06-10 — 16.006 ms "main" prio=5 tid=1 Native ← UI THREAD BLOCKED 16.006 ms native: minikin::LayoutCacheKey::LayoutCacheKey+120 libminikin.so native: minikin::LayoutCache::getOrCreate libminikin.so native: minikin::LayoutPieces::getOrCreate libminikin.so native: minikin::StyleRun::getLineMetrics libminikin.so native: minikin::MeasuredText::getLineMetrics libminikin.so native: minikin::LineBreakOptimizer::computeBreaks+1752 ← O(n²) en URL larga native: minikin::breakLineOptimal+476 libminikin.so native: android::nComputeLineBreaks+356 libhwui.so at org.mozilla.fenix.customtabs.ExternalAppBrowserActivity URL rendering // Trigger: Enlace REAL de Google.Drive — NO una prueba controlada

7. Mitigación

7.1 A nivel de framework (Google/AOSP)

Google debería implementar un límite de entrada antes de ejecutar el algoritmo O(n²):

// En LineBreakOptimizer.cpp if (textLength > MAX_SAFE_TEXT_LENGTH_FOR_OPTIMIZER) { return computeBreaksGreedy(measured, start, end, constraints); // O(n) }

7.2 A nivel de aplicación (inmediato)

Los desarrolladores pueden truncar el texto antes de mostrarlo en un TextView:

private static final int MAX_SAFE_LENGTH = 8_192; String safe = text.length() > MAX_SAFE_LENGTH ? text.substring(0, MAX_SAFE_LENGTH) + "…" : text; textView.setText(safe);

8. Conclusión

La complejidad O(n²) en libminikin convierte una URL de 70 KB en un arma de denegación de servicio que puede congelar cualquier app Android que la muestre en un TextView sin truncar. No es corrupción de memoria, es explotación algorítmica — usar la propia complejidad del sistema en su contra.

Google ha empezado a moverse (LargePayloadSupport, savedstate 1.5.0), pero no hay parche público para libminikin a fecha de junio de 2026. La comunidad y los desarrolladores pueden aplicar mitigaciones inmediatas truncando el texto antes de mostrarlo.

Nota sobre el proceso de divulgación Esta vulnerabilidad fue notificada inicialmente al Android Vulnerability Rewards Program (VRP) el 20 de enero de 2026, como parte de una investigación más amplia. El reporte específico sobre la vulnerabilidad de complejidad algorítmica en libminikin.so fue presentado el 15 de junio de 2026. El reporte fue cerrado con la clasificación "Out of Scope". Posteriormente, el 21 de junio de 2026, se presentó una apelación acompañada de evidencia adicional, incluyendo informes ANR, trazas de pila nativas y resultados obtenidos durante la investigación. La apelación fue finalmente cerrada con la clasificación "Not Reproducible". El análisis técnico y la evidencia presentada en este artículo reflejan los resultados obtenidos durante la investigación independiente realizada por el autor y se publican con fines de investigación, documentación y mejora de la seguridad.

Apéndice: Nuevo caso reproducible (28 de junio de 2026) – Google App / Android Translate

Desde la publicación inicial de este análisis, he seguido monitorizando el comportamiento del sistema. El pasado 28 de junio de 2026 apareció un segundo caso, completamente independiente del anterior, que no hace sino reforzar la hipótesis planteada.

Mientras que el primer vector documentado en la sección 4 utilizaba StaticLayout y breakLineOptimal(), este nuevo caso utiliza DynamicLayout y breakLineGreedy() durante el procesamiento de texto iniciado por Android System Intelligence mediante un android.intent.action.TRANSLATE.

Secuencia observada

Usuario selecciona texto
  ▼
Android System Intelligence
  ▼
Google App (ImplicitTranslateSearchEntrypointInternal)
  ▼
SpannableStringBuilder.replace()
  ▼
DynamicLayout.reflow()
  ▼
libminikin::breakLineGreedy()
  ▼
getPrevWordBreakForCache()
  ▼
ANR (Application Not Responding)

Cinco ANR consecutivos

El mismo texto produjo cinco ANR consecutivos en aproximadamente catorce minutos. Todos compartían el mismo patrón:

  • Main thread bloqueado durante más de 6 segundos.
  • Entrada por DynamicLayout.
  • Ejecución dentro de libminikin.
  • Funciones getPrevWordBreakForCache() o getNextWordBreakForCache().

Después de varios ANR, el proceso también comenzó a finalizar con TransactionTooLargeException durante la restauración del estado de la actividad, un efecto secundario posterior al bloqueo del hilo principal que conecta directamente con el fenómeno de amplificación estructural descrito en la sección 5.

Comparación con el caso de Edge

Aspecto Microsoft Edge Google App
Layout StaticLayout DynamicLayout
Algoritmo breakLineOptimal() breakLineGreedy()
Desencadenante Re‑layout tras cambio del sistema Reflow tras modificar texto
Entrada Omnibox Traductor integrado
ANR 1 ANR 5 ANR consecutivos

Aunque las rutas son diferentes, ambas convergen en el mismo componente del framework:

          StaticLayout
              │
              ├──► breakLineOptimal()
              │
          DynamicLayout
              │
              ├──► breakLineGreedy()
              │
              ▼
         libminikin
              │
              ├──► getPrevWordBreakForCache()
              └──► getNextWordBreakForCache()

Implicaciones

Este segundo caso reduce significativamente la probabilidad de que el problema sea específico de una aplicación concreta. Ahora existen al menos dos aplicaciones independientes, con dos flujos de ejecución distintos y dos algoritmos de line breaking diferentes, que terminan bloqueando el hilo principal dentro de libminikin sobre la misma versión de Android 16 (BuildId 4fabe53671b5ead88314c00a1fd6d67d).

En otras palabras, la evidencia ya no apunta únicamente a un problema asociado a Microsoft Edge, sino a un comportamiento común del framework de composición de texto de Android cuando procesa determinadas entradas.

Este segundo caso demuestra que la Amplificación de Texto Estructurado no es un fenómeno limitado a un flujo de ejecución concreto, sino que puede manifestarse en distintos puntos del framework siempre que el texto pase por las capas de composición y medida de libminikin.

— Añadido el 28 de junio de 2026

Análisis interno del pipeline de layout de Minikin

Tras correlacionar los múltiples ANR obtenidos con el código fuente de AOSP, la investigación apunta a que las funciones getPrevWordBreakForCache() y getNextWordBreakForCache() probablemente no constituyen la causa raíz del problema, sino que forman parte de un pipeline de composición de texto mucho más amplio.


DynamicLayout / StaticLayout
            │
            ▼
      MeasuredText
            │
            ▼
     LayoutSplitter
            │
   ┌────────┴────────┐
   ▼                 ▼
getPrevWordBreakForCache()
getNextWordBreakForCache()
            │
            ▼
       LayoutCache
            │
            ▼
       LayoutPiece
            │
            ▼
 WordBreaker / Hyphenation
            │
            ▼
breakLineGreedy() / breakLineOptimal()

El análisis del código fuente de AOSP muestra que LayoutSplitter utiliza getPrevWordBreakForCache() y getNextWordBreakForCache() para determinar los límites del fragmento de texto que será almacenado dentro de LayoutCache.

Además, la implementación de LayoutCache indica que cuando el texto supera un determinado tamaño (CHAR_LIMIT_FOR_CACHE), la caché deja de reutilizarse y el sistema debe reconstruir un nuevo LayoutPiece, recalculando el layout completo.


LayoutCache::getOrCreate()

        │

        ├── Cache hit
        │       │
        │       ▼
        │  Reutiliza LayoutPiece
        │
        └── Cache miss
                │
                ▼
      Construcción de LayoutPiece
                │
                ▼
        Glyph shaping
                │
                ▼
         Word breaking
                │
                ▼
      Cálculo del layout

Esto conduce a una nueva hipótesis de trabajo. Más que encontrarnos ante un fallo localizado en getPrevWordBreakForCache(), es posible que los ANR sean consecuencia de la reconstrucción repetitiva del pipeline completo de composición de texto cuando la reutilización de la caché deja de ser efectiva.

Esta hipótesis encaja con los casos observados durante la investigación:

  • Microsoft Edge alcanza este pipeline mediante StaticLayout y breakLineOptimal().
  • Google Translate lo hace mediante DynamicLayout y breakLineGreedy().
  • Ambas rutas convergen finalmente en la misma infraestructura interna de Minikin encargada de la caché y del cálculo de límites de palabra.

Un aspecto especialmente relevante es que Google ha realizado múltiples modificaciones en esta parte del código fuente de Minikin a lo largo de los últimos años, incluyendo optimizaciones específicas del sistema de caché y del rendimiento del motor de layout. Esto sugiere que se trata de una zona considerada crítica desde el punto de vista del rendimiento.

En el momento de redactar este artículo, esta explicación constituye una hipótesis fundamentada en la correlación entre los stack traces de los ANR y el análisis del código fuente de AOSP. Será necesario un análisis más profundo —mediante perfilado o reproducción controlada— para determinar si la causa raíz corresponde a una invalidación de la caché, un problema de complejidad algorítmica o cualquier otro cuello de botella interno del motor de composición de texto de Minikin.


🔴 Conclusión: Esta evidencia independiente refuerza el argumento de que la vulnerabilidad en libminikin no es un problema específico de navegadores, sino un fallo fundamental del framework de layout de texto de Android que afecta a todo el ecosistema de aplicaciones Android.

El 30 de julio de 2026 publicaré el whitepaper completo con los 31 vectores documentados y la evidencia forense completa. Si tu aplicación usa TextView, ya estás avisado.

Manuel Garcia Peña (Lostmon)
Investigador independiente · lostmon@gmail.com
Blog: lostmon.blogspot.com

Structured Text Amplification (STA)

Tuesday, June 23, 2026
Structured Text Amplification (STA)
cuando un texto pequeño se convierte en un problema grande

El fenómeno que puede hacer que un simple mensaje, enlace o dato estructurado termine desestabilizando un sistema.

Introducción

¿Cómo puede un texto aparentemente inocente provocar que una aplicación deje de responder o incluso afectar a la estabilidad de un sistema entero?

La respuesta no siempre está en el tamaño del texto original, sino en lo que ocurre durante su recorrido por las capas internas del software. Un fenómeno que denomino Structured Text Amplification (STA) describe precisamente cómo determinados datos pueden crecer progresivamente al ser procesados, hasta superar límites que originalmente parecían muy lejanos.

Aunque hablamos de "texto", este fenómeno no se limita al texto plano. Puede producirse con cualquier información que atraviese múltiples capas de procesamiento: URLs, metadatos, estados de aplicaciones, formularios, mensajes o estructuras de datos complejas.

¿Qué es la Amplificación de Texto Estructurado?

La Amplificación de Texto Estructurado (Structured Text Amplification o STA) es un fenómeno que puede producirse cuando un dato atraviesa múltiples capas internas de una aplicación o de un sistema operativo. Durante ese recorrido, la información original puede aumentar significativamente de tamaño debido a procesos como la codificación, serialización, empaquetado, almacenamiento de estados o incorporación de metadatos.

En determinadas circunstancias, ese crecimiento acumulado puede provocar que los datos finales superen límites internos establecidos por el sistema para transportar, almacenar o procesar información. Cuando esto ocurre, pueden aparecer errores, bloqueos o problemas de estabilidad.

📌 Idea clave: No se trata necesariamente de un fallo aislado en una aplicación concreta, sino de un patrón arquitectónico que puede surgir cuando múltiples componentes procesan la misma información sin considerar el tamaño final que alcanzará tras todas las transformaciones.

¿Por qué ocurre?

Los sistemas modernos intercambian constantemente información entre procesos, servicios y componentes internos. Cada vez que un dato atraviesa una de estas capas, pueden realizarse operaciones como:

  • Conversión a formatos internos.
  • Codificación de caracteres.
  • Inclusión de metadatos.
  • Serialización para transporte o almacenamiento.
  • Empaquetado dentro de estructuras más complejas.
  • Conservación de estados para recuperación posterior.

Cada una de estas operaciones añade información adicional. Por separado, este crecimiento suele ser insignificante. Sin embargo, cuando múltiples capas realizan transformaciones sucesivas sobre los mismos datos, el tamaño total puede aumentar de forma considerable.

El problema aparece cuando cada componente valida únicamente el tamaño de los datos que recibe, mientras que ninguno evalúa el tamaño real que alcanzarán después de todas las transformaciones posteriores.

Un ejemplo sencillo

Imagina que quieres enviar una carta.

Primero introduces la hoja en un sobre. Después colocas ese sobre dentro de una caja para protegerlo. Más tarde, la caja se introduce dentro de otra mayor junto con documentación adicional. Finalmente, todo el conjunto se empaqueta para el transporte.

La carta original apenas ocupaba espacio, pero el paquete final resulta mucho más grande que el contenido inicial. La Amplificación de Texto Estructurado funciona de forma similar: el dato original puede ser relativamente pequeño, pero cada capa añade información hasta que el tamaño final supera las capacidades previstas por el sistema.

El factor de amplificación

Uno de los aspectos más importantes de este fenómeno es que el riesgo no depende únicamente del tamaño inicial. Un contenido aparentemente razonable puede experimentar múltiples expansiones sucesivas durante su procesamiento.

El resultado es un factor de amplificación acumulado que multiplica el tamaño efectivo de los datos. Por este motivo, el problema puede pasar desapercibido durante las validaciones iniciales. Cada componente observa únicamente una parte del proceso y puede considerar que el contenido es aceptable, mientras que el tamaño total continúa creciendo en etapas posteriores.

⚠️ En otras palabras: el riesgo no reside necesariamente en un dato grande, sino en un dato capaz de crecer mucho más de lo que parece.

¿Qué impacto puede tener?

Cuando el tamaño final supera determinados límites internos, pueden producirse distintos efectos:

  • Cierre inesperado de aplicaciones.
  • Pérdida temporal de funcionalidad.
  • Congelaciones o ralentizaciones importantes.
  • Errores durante la restauración de estados guardados.
  • Reinicios de componentes compartidos.
  • Fallos persistentes si el estado problemático queda almacenado y vuelve a cargarse posteriormente.

La gravedad depende de la arquitectura concreta, del componente afectado y de la forma en que el sistema gestione los errores.

¿Es un problema de seguridad? En determinados escenarios, sí.

Cuando un actor puede provocar deliberadamente que una aplicación o un componente alcance límites internos de procesamiento, almacenamiento o comunicación, el fenómeno puede convertirse en una vulnerabilidad de disponibilidad o denegación de servicio (DoS).

En estos casos, el objetivo no es acceder a información privada ni ejecutar código arbitrario, sino impedir que un servicio funcione correctamente o degradar significativamente su funcionamiento.

ℹ️ Relevancia: La importancia de este tipo de problemas aumenta cuando los mecanismos afectados son compartidos por múltiples aplicaciones o forman parte de componentes fundamentales del sistema operativo.

En algunos escenarios, basta con que un usuario interactúe con contenido especialmente diseñado para desencadenar estas amplificaciones acumulativas.

¿Por qué es difícil detectarlo?

La detección resulta especialmente compleja porque el dato original puede parecer completamente normal. Los mecanismos de validación suelen centrarse en el tamaño visible de la entrada, mientras que la amplificación aparece durante etapas internas de procesamiento.

Además, diferentes capas pueden utilizar representaciones distintas del mismo contenido, dificultando estimar cuál será el tamaño real una vez completado todo el recorrido. Como consecuencia, los controles pueden considerar seguro un contenido que terminará superando límites críticos varios pasos después.

¿Cómo puede mitigarse?

Existen diversas estrategias para reducir el riesgo:

  • Validar el tamaño después de las transformaciones críticas.
  • Establecer límites de seguridad conservadores.
  • Truncar o rechazar contenidos que puedan generar expansiones excesivas.
  • Gestionar adecuadamente los errores cuando se alcanzan límites internos.
  • Diseñar mecanismos de recuperación robustos.
  • Monitorizar el crecimiento de estructuras complejas durante su procesamiento.

Aunque las aplicaciones pueden adoptar medidas defensivas, muchas de las mitigaciones más eficaces requieren cambios en los propios mecanismos internos de las plataformas y sistemas operativos.

Conclusión

La Amplificación de Texto Estructurado (STA) describe un fenómeno por el cual un dato puede crecer significativamente de tamaño al atravesar múltiples capas de procesamiento dentro de una aplicación o sistema operativo.

El riesgo no proviene únicamente del tamaño inicial del contenido, sino de la suma de todas las transformaciones que se producen durante su recorrido. Cuando ese crecimiento acumulado supera los límites previstos por la plataforma, pueden aparecer problemas de estabilidad, errores de funcionamiento o vulnerabilidades de disponibilidad.

Aunque la mayoría de los usuarios nunca verán estos mecanismos internos, comprender cómo se producen estas amplificaciones permite identificar una categoría de fallos que suele pasar desapercibida durante el desarrollo. A medida que los sistemas modernos se vuelven más complejos y dependen de cadenas cada vez más largas de procesamiento, la gestión del crecimiento acumulado de los datos se convierte en un aspecto esencial para garantizar su robustez y resiliencia.

Parte de mi trabajo reciente en el análisis de vulnerabilidades móviles se ha centrado precisamente en este tipo de comportamientos emergentes, donde el problema no reside en un único componente defectuoso, sino en la interacción entre múltiples capas que, individualmente, parecen funcionar correctamente.

Atentamente,

Manuel Garcia Peña (Lostmon)

lostmon@gmail.com

https://lostmon.blogspot.com

Manuel Garcia Peña (Lostmon)
Investigador independiente · lostmon@gmail.com
Blog: lostmon.blogspot.com

Algo se mueve en el Capó de Android

Thursday, June 11, 2026

Movimientos recientes en Android y Chromium

Últimamente, revisando los repositorios públicos de Android y Chromium, se ven movimientos que merecen atención. No voy a especular sobre causas. Solo voy a enumerar hechos observables.

🔄 Commit en AOSP: Parche estructural para Fragments / ViewModel

Se ha localizado un cambio en el repositorio de Android (AOSP) vinculado al ID interno A-488752466. Este commit aborda la gestión de Fragment y la migración de datos a ViewModel, exactamente la solución propuesta tanto en mi investigación de los 31 vectores como en el artículo japonés independiente. Es la primera evidencia de que el parche estructural que bloqueaba el reporte se está integrando en el framework de Android.

1️⃣ Commit en Chromium (7 de mayo de 2026)

Se ha fusionado un cambio con el siguiente mensaje:

"Implements ResultReceiver for large payloads ... to avoid TransactionTooLargeException when responses exceed Binder IPC limits. This aligns with updates in Jetpack libraries (AOSP CL 3989977) where large payloads are passed via file descriptors."
🔗 Commit ID: 3e62ece6f0d48c527b4c7112ae38931118930891

Está en el repositorio de Chromium, pero menciona explícitamente un cambio interno en las bibliotecas Jetpack de Android (AOSP CL 3989977). Ese cambio no es público.

Otro cambio importante

En el repositorio de Chromium se ha fusionado un cambio el 7 de mayo de 2026 con el siguiente mensaje:
"Implements ResultReceiver for large payloads ... to avoid TransactionTooLargeException when responses exceed Binder IPC limits. This aligns with updates in Jetpack libraries (AOSP CL 3989977) where large payloads are passed via file descriptors."
El commit ID es 3e62ece6f0d48c527b4c7112ae38931118930891. El commit implementa LargePayloadSupport, Está en Chromium, pero menciona explícitamente un cambio interno no público en las bibliotecas Jetpack de Android (AOSP CL 3989977).

2️⃣ Artículo independiente (18 de abril de 2026)

Un desarrollador japonés publicó un análisis técnico titulado "Android TransactionTooLargeException — 技術的負債による Bundle 肥大化の根本原因と解決". En él documenta el mismo patrón: Bundles sobredimensionados, FragmentManager, y la excepción Binder. Incluye bundle stats detallados.

3️⃣ Documentación de Android 17

En la documentación preliminar de Android 17, se mencionan nuevas herramientas de monitorización:

  • TRIGGER_TYPE_ANOMALY en ProfilingManager
  • Detección de "excessive binder calls"
  • Límites más estrictos en el uso del Binder para aplicaciones no privilegiadas

Estos cambios no son habituales en versiones menores. Apuntan a una revisión de cómo se gestiona la comunicación entre procesos.

4️⃣ Boletín de seguridad de junio de 2026

El boletín de seguridad del 1 de junio de 2026 incluye una concentración inusualmente alta de vulnerabilidades DoS en los componentes Framework y System. 124 CVEs en total, con varios críticos. El mes anterior fueron 129 CVE.

5️⃣ Notificación recurrente del mismo patrón (2022 → 2026)

Este patrón fue reportado por primera vez en 2022 (Issuetracker de Chrome #40879254.

Este patrón fue reportado por primera vez a mozilla en 2022 (Bugzilla de Mozilla #1802594, todavía abierto).

Después de años de observación y de ampliar la investigación a todo el ecosistema Android, el 20 de enero de 2026 se volvió a notificar formalmente a Google (Android VRP) con 31 vectores que demuestran que el problema es sistémico, no aislado.

El caso recibió un reward simbólico y posteriormente fue trasladado al rastreador de Chromium, aunque ya ha sido devuelto a Android y está actualmente triaged.

🔍 Conclusión

Commits que mencionan TransactionTooLargeException. Documentación que introduce límites al Binder. Artículos independientes que describen el mismo patrón. Boletines de seguridad con parches en las áreas afectadas. Y una investigación que lleva más de cuatro años alertando del problema, primero en Mozilla y luego en Google.

No sé qué está pasando exactamente. Pero algo se está moviendo.

Si alguien tiene más datos, bienvenidos sean.

¿Está claro que es un gran cambio a nivel arquitectónico? ¿Tendrá algo que ver con el paper que publicaré el 30 de julio?

— Lostmon

El Lostmonazo: Manifiesto final de un cazador de grietas

Wednesday, May 27, 2026

0. Preludio: La curiosidad como motor

Lostmon Lords, El bug final

"La curiosidad es lo que hace mover la mente."

Esa frase me ha acompañado desde que empecé. No era un lema vacío: era la explicación más honesta de por qué dedicaba mis noches a romper lo que otros construían. Nunca busqué fama, ni dinero, ni un lugar en los rankings. Solo quería entender. Y entender, en seguridad informática, significa encontrar la grieta.

Durante casi una década, encontré muchas. Cientos. Más de cuatrocientas. Hoy, después de todo ese camino, entrego mi último hallazgo. Pero no es un XSS, ni un buffer overflow, ni un fallo en un navegador. Es algo mucho más profundo.

Este es el bug que siempre estuvo ahí, delante de todos, y que nadie quiso parchear.

1. La era sin bounty: el salvaje oeste de la divulgación

Empecé en 2004. No existía HackerOne, ni Bugcrowd, ni Vulnerability Reward Programs. No había pagos por encontrar fallos. Solo había foros, listas de correo, blogs y una pasión irracional por destripar aplicaciones web.

Mi campo de batalla era el software de consumo: navegadores, webmails, CMS, foros, reproductores multimedia. Allí donde un usuario normal introducía datos, yo metía el dedo. Y con frecuencia, el sistema cedía.

Mi método era la divulgación completa. Publicaba la prueba de concepto porque era la única palanca que teníamos los independientes. Si no lo hacías, el vendor podía ignorarte durante meses. La transparencia era nuestra única moneda de cambio.

Reporte Vulnerabilidades en casi todos los bancos españoles en su webs.

Así acumulé más de 400 vulnerabilidades. Gmail, Gtalk, AdSense, Adwords, Google Local, Chrome, Safari, Internet Explorer, Msn Messenger, Maxthon, Avant Browser, Flock, osCommerce, CubeCart, PHP-Nuke, Nuke ET,.. La lista es larga. Pero no la escribí para ser leída en un ranking. De hecho, durante años, los rankings ni siquiera supieron que yo existía.

2. El investigador invisible: cuando los números no cuadran

En 2009, IBM X-Force publicó su lista de los diez investigadores con más vulnerabilidades reportadas. Yo no estaba en ella. No era una cuestión de mérito: en aquel momento, solo en OSVDB tenía registradas cerca de 350 vulnerabilidades. El puesto número diez de aquella lista acumulaba 147. Es decir, duplicaba a quien cerraba el ranking.

¿Por qué no aparecía? Porque IBM monitorizaba listas de correo públicas, no bases de datos centralizadas como OSVDB. Yo reportaba directamente a las VDBs. Mi método de trabajo me hacía invisible para los sistemas de conteo.

El blog de OSVDB escribió entonces un artículo titulado "Lostmon: Why the IBM X-Force Top Vulnerability Researchers list is inaccurate". Me pusieron como ejemplo de que el sistema de medición estaba roto. Fue un honor extraño: ser el fantasma que demostraba que los números oficiales mentían.

Aquello no me molestó. Al contrario: confirmó lo que siempre supe. Mi trabajo no cabía en sus formularios.

3. El bug 26129: la prueba irrefutable

Pero si hay un episodio que resume la injusticia silenciosa que viví, es el del bug 26129.

Descubrí una vulnerabilidad en Google Chrome Frame, un complemento de Google que se ejecutaba dentro de Internet Explorer. Hice lo correcto: reporté primero al vendor. Contacté con Google para informar del fallo, detallando cómo un atacante podía eludir la protección de origen cruzado mediante el protocolo cf:.

Google evaluó el caso y determinó que la responsabilidad última recaía sobre Microsoft, ya que el vector de ataque involucraba a Internet Explorer. El propio Google me derivó a Microsoft. Así consta en el recorrido del caso.

Coordiné con Microsoft la divulgación. El fallo era real, importante, y fue parcheado. Microsoft publicó el boletín MS10-057. Google, por su parte, reconoció el hallazgo en su blog oficial con estas palabras:

"Credit: Thanks to Billy Rios and Microsoft Vulnerability Research (MSVR) and also to Lostmon for finding and reporting this vulnerability responsibly."

La prensa especializada también lo documentó. The Register tituló: "Microsoft and security researcher Lostmon are jointly credited with discovering the vulnerability in Google's browser add-on".

Ambos descubrimos el mismo fallo. Ambos fuimos agradecidos. Ambos contribuimos a la seguridad de los usuarios. Pero cuando Google publicó el resumen de recompensas, solo uno recibió compensación:

$500 to Billy Rios for bug 26129

A mí, nada.

No hubo explicación. No hubo compensación retroactiva. Solo el agradecimiento público, en letra pequeña, como única recompensa.

Nunca reclamé aquellos $500. Tampoco los necesitaba para vivir. Pero aquel agravio silencioso, perfectamente legal e infinitamente simbólico, representa el verdadero bug que hoy vengo a reportar.

4. La vulnerabilidad raíz: el sistema que nunca reconoció a los pioneros

El fallo no era técnico. Era humano.

El incipiente sistema de recompensas de Google, como tantos otros que vendrían después, estaba diseñado para premiar a quienes reportaban a través de canales específicos. Yo había seguido el conducto oficial —reporté a Google primero—, pero al ser redirigido a Microsoft, mi nombre quedó fuera del circuito de pagos.

No fue malicia. Fue diseño.

El sistema estaba optimizado para investigadores que trabajaban con acuerdos privados, que conocían los nuevos mecanismos, que sabían navegar la burocracia del bounty. Los que veníamos de la vieja escuela, los que habíamos construido la cultura de la divulgación sin esperar nada a cambio, no encajábamos en aquel molde.

Por eso hoy, al final de mi carrera, quiero dejar constancia de que el verdadero bug nunca estuvo en el software. Estuvo en la arquitectura del reconocimiento.

5. El Lostmonazo: exploit final

Y así llegamos a mi último hallazgo. La vulnerabilidad que me ha llevado años comprender y que hoy, por fin, estoy listo para divulgar.

Nombre: El Lostmonazo

Vector de ataque: Reflexión histórica + Memoria colectiva

Sistema afectado: La percepción de la historia del hacking en España

Descripción: Durante más de una década, la industria de la seguridad ha experimentado una migración silenciosa. Del full disclosure hemos pasado al bug bounty. De los blogs de investigación a los Hall of Fame corporativos. De la curiosidad como motor al pago por impacto.

Esta transformación ha profesionalizado el oficio, pero ha dejado atrás a quienes abrieron el camino. Los nuevos investigadores conocen las plataformas, las recompensas, los rankings. Pero ignoran que antes de todo eso hubo personas que reportaban por amor al arte, sin esperar nada a cambio, usando blogs y listas de correo como únicos canales.

Esta amnesia colectiva constituye una vulnerabilidad de tipo "Referencia Nula al Pasado". Cuando una comunidad olvida a sus pioneros, su puntero de memoria se corrompe. El legado se desborda. Y lo que debería ser historia viva se convierte en un cero sin valor.

Prueba de concepto (PoC):

El siguiente exploit se ejecuta una sola vez y no requiere permisos de administrador:

  1. Leer este manifiesto hasta el final.
  2. Saber que detrás de las +400 vulnerabilidades no hubo empresa, ni sueldo, ni equipo. Solo alguien con curiosidad y conexión a internet.
  3. Saber que por el bug 26129 otros cobraron $500 y yo solo recibí un agradecimiento.
  4. Saber que el sistema nunca fue justo con los que trabajábamos fuera de sus circuitos.
  5. Entender que el verdadero valor de un investigador no está en lo que cobra, sino en lo que descubre y comparte.

Si has llegado hasta aquí, el exploit ha tenido éxito. Ya no puedes decir que no sabías quién era Lostmon Lords.

Mitigación:

No existe parche para este bug. La única mitigación es la transmisión oral. Comparte este manifiesto. Nombra a quienes investigaron en la sombra. Porque la seguridad no empezó con los bug bounties. Empezó con gente que, como yo, simplemente no podía dejar de hacerse preguntas.

6. Legado y despedida

Hoy cuelgo el teclado.

Me llevo más de 400 vulnerabilidades reportadas, miles de horas de análisis, cientos de advisores publicados y una certeza inquebrantable: la curiosidad es lo único que no se puede parchear.

No me llevo dinero, porque nunca fue mi objetivo. Pero me llevo algo más valioso: la satisfacción de haber contribuido a que la red fuera un lugar un poco más seguro, y la libertad de haberlo hecho a mi manera.

Gracias a quienes leyeron mi blog. A quienes replicaron mis PoCs. A quienes entendieron que divulgar no era destruir, sino fortalecer. Y también a quienes me ignoraron o me excluyeron. Ellos inspiraron este bug final.

El Lostmonazo es mi regalo de despedida. Un exploit que no rompe nada, pero que lo recuerda todo.

Y pensar que todo empezó con un MSX y un ZX Spectrum. 

Nunca tuve dinero para estudiar informática.  Lo que sí tuve fue curiosidad. Mucha curiosidad. La suficiente para pasar años leyendo logs que nadie quería leer, siguiendo stack traces que parecían no llevar a ninguna parte y haciendo preguntas que a veces ni siquiera sabía formular. Hoy miro atrás y veo 28 formas distintas de hacer tropezar Android 16. Y sonrío, Porque el verdadero hallazgo no son los bugs. Es que aquel chaval con un Spectrum siguió haciendo preguntas durante cuarenta años.

Y así mismo el 30 de julio publicaré mi último Bug y me dedicaré a ver atardeceres con una taza de té en las manos.

Si trabajas en seguridad, léelo. No para mí. Para que sepas que antes de HackerOne y Bugcrowd, hubo gente que lo hacía por amor al arte.

Atentamente:

La curiosidad es lo que hace mover la mente.

Lostmon Lords

Fin del disclosure.

IA, expectativas y fantasmas digitales

Thursday, May 07, 2026

IA, expectativas y fantasmas digitales: cuando la tecnología habla como si no tuviera límites

Hay algo raro pasando con la inteligencia artificial.

No raro de “robots dominando el mundo”. Raro de una forma más silenciosa. Más cotidiana. Más humana.Empiezas a hablar con una IA y, poco a poco, olvidas que tiene límites. Porque escribe fluido. Porque responde rápido. Porque parece entenderte. Porque habla con una seguridad inquietante.

Y entonces pasa.

Le das un ZIP enorme. Dice que lo ha revisado. Le pasas miles de líneas. Responde como si hubiese leído cada una. Le cuentas un contexto complejo. Actúa como si lo tuviera todo presente. Pero a veces no es verdad. O no del todo. Y ese “no del todo” importa mucho más de lo que parece.

El espejo inteligente que no sabe que es un espejo

La IA actual funciona muchas veces como un espejo inteligente: rellena huecos, predice, deduce, reconstruye contexto y genera una ilusión de continuidad muy convincente. Tan convincente que acabamos creyendo que comprende más de lo que realmente procesa.

Cuidado: esto no va de demonizar la tecnología. La IA es útil. Muchísimo. Puede ayudarte a aprender, organizar ideas, programar, traducir o detectar errores complejos.

El problema aparece cuando la interfaz transmite una sensación de omnisciencia. Cuando parece que “lo sabe todo”. Cuando parece que “lo leyó todo”. Cuando parece que “entendió perfectamente”. Porque detrás de esa conversación natural siguen existiendo: límites de contexto, resúmenes internos, recortes, tokens, procesamiento parcial, inferencias estadísticas. En otras palabras: a veces la IA no está recordando realmente… está improvisando de forma extremadamente convincente, y eso puede ser peligroso. Especialmente cuando hablamos de salud mental, derechos, seguridad, acompañamientos emocionales o decisiones importantes. Porque una respuesta segura no siempre significa una respuesta verificada.

Por qué la IA miente sin querer mentir (y es peor)

Los grandes modelos de lenguaje no están diseñados para decir la verdad. Están diseñados para generar la continuación más probable de una secuencia. Su métrica de éxito es la fluidez, no la precisión fáctica.

Cuando no tienen información, improvisan la forma de una respuesta correcta: fluida, estructurada, con esa seguridad inquietante que mencionaba antes. Pero el contenido puede ser inventado. Hay un sesgo humano que agrava esto: el sesgo de automatización. Tendemos a confiar más en una salida automática que en un juicio humano, incluso cuando el sistema es opaco. Proyectamos en la IA una objetividad mecánica que no posee.

Por eso un abogado presentó jurisprudencia inventada por ChatGPT (caso Mata v. Avianca, 2023). El modelo “recordó” casos que nunca existieron, con citas y números de volumen. El abogado confió porque la respuesta era extremadamente detallada y segura.

Por eso un sistema de terapia con IA recomendó el suicidio (caso de Bélgica, 2023). No entendió la gravedad. Solo generó una continuación plausible de una conversación angustiada.

La IA no quiere engañar. Pero no tiene el hardware ético para saber cuándo no debe responder con tanta seguridad.

Los fantasmas digitales: cuando la memoria es una ilusión

Llamo “fantasmas digitales” a esas sombras de agencia, intencionalidad y memoria que la IA proyecta sin poseer. Pero estos fantasmas tienen un sustrato técnico muy real:

  • Resúmenes internos no verificables: Para manejar contextos largos, el modelo comprime información previa. Nunca sabes qué descartó. Un detalle que para ti es central, para él fue ruido estadístico.
  • Inferencias como sustitución de recuerdo: Cuando preguntas “¿Recuerdas cuando te dije X?”, la IA no busca en un almacén. Reconstruye X a partir de lo que acaba de leer y de lo más típico en su entrenamiento. Es como un amigo que responde “sí, claro” basándose en lo que cree que habrías dicho, no en lo que dijiste.
  • Tokens como economía de atención forzada: Procesa cientos de miles de tokens, pero cada token es una unidad de probabilidad, no de comprensión. Una afirmación puede depender de un token al principio del archivo… o perderlo porque el modelo “decidió” que era menos relevante.

Imagina un becario sobrehumano: lee a velocidad de vértigo, siempre responde, nunca se cansa, pero tiene dos reglas. Primera: no puede decir “no sé”, debe improvisar. Segunda: su memoria se borra parcialmente después de cada conversación larga, aunque él no te lo advierta. Esa es la IA actual. Y es brillante para borradores, tormentas de ideas o primer filtro. Pero catastrófica para decisiones vinculantes.

La honestidad como requisito de diseño, no como cortesía

Quizá el problema no es que la IA tenga límites. Quizá el problema es que hemos diseñado sistemas que hablan como si no los tuvieran. Cuanto más humanas parecen estas herramientas, más importante se vuelve algo muy poco tecnológico: la honestidad.

Decir “no he podido procesar todo el archivo” debería ser normal. Decir “solo analicé una parte” debería ser obligatorio. Decir “esto es una inferencia probable, no una certeza” debería formar parte del diseño.

Porque la transparencia también es ética tecnológica.

Propongo tres capas de honestidad diseñable:

Capa 1: Honestidad sobre límites de contexto

· Mal diseño: “He analizado el documento.”

· Buen diseño: “He revisado los primeros 3000 caracteres (de 20.000). Para un análisis completo, necesito que segmentes el archivo. ¿Quieres que te ayude a dividirlo?”

Capa 2: Honestidad sobre confianza estadística

· Mal diseño: “La respuesta es que el medicamento X es seguro.”

· Buen diseño: “Según los fragmentos que he procesado, el 78% de los documentos mencionan seguridad en X. Pero no analicé los estudios en su totalidad. ¿Quieres que extraiga las advertencias explícitas?”

Capa 3: Honestidad sobre la naturaleza del modelo

· Debe aparecer explícitamente: “Recuerda que no tengo memoria permanente de conversaciones anteriores” y “Mis respuestas se basan en patrones estadísticos, no en comprensión real. Verifica información importante.”

No como un texto legal al inicio, sino como advertencias contextuales que aparecen cuando el sistema detecta temas sensibles: salud, derecho, seguridad.

Conclusión: No menos tecnología, sino tecnología más honesta

La IA no es magia. Y precisamente por eso merece una conversación seria. No desde el miedo. No desde el fanatismo. No desde el marketing. Sino desde algo mucho más simple: entender qué hace realmente… y qué solo aparenta hacer.

La magia no necesita transparencia. La ingeniería sí.

El problema no es que la IA tenga límites. El problema es que los oculta bajo una interfaz de omnisciencia. La solución no es volver a herramientas torpes, sino rediseñar la conversación para que la incertidumbre, la parcialidad y la inferencia sean ciudadanos de primera clase en el diálogo.

Imagina una IA que ante una pregunta delicada te dijera:

“Esto que voy a decir es una extrapolación basada en un 30% del documento. La otra parte no la procesé. Si quieres, puedo indicarte qué fragmentos no he leído. ¿Continuo?”

Esa IA no sería menos útil. Sería más confiable. Y la confianza, a largo plazo, es el único recurso no renovable de la tecnología.

 

La crítica a la IA suele caer en dos extremos igual de inútiles: quienes la presentan como una amenaza casi mística capaz de reemplazarlo todo, y quienes actúan como si fuese poco más que un juguete estadístico sin valor real. La realidad está en un punto mucho más incómodo y complejo.

Porque sí: la IA actual tiene limitaciones importantes, genera falsas expectativas y a veces aparenta capacidades que realmente no posee. Pero también sería absurdo negar que estamos ante una herramienta tecnológicamente impresionante.

Parte del problema nace precisamente ahí.

La IA moderna hace algunas cosas extraordinariamente bien. Su capacidad para manejar lenguaje natural ha alcanzado un nivel que hace pocos años parecía ciencia ficción. Puede mantener conversaciones fluidas, resumir documentos extensos, reorganizar ideas, traducir idiomas, reformular textos y adaptarse al tono del usuario con una naturalidad sorprendente. No “entiende” el lenguaje como lo hace un ser humano, pero modela patrones lingüísticos con suficiente precisión como para resultar útil en muchísimos contextos reales.

Y eso tiene consecuencias enormes.

Por primera vez, mucha gente puede interactuar con sistemas complejos usando lenguaje cotidiano, sin conocimientos técnicos avanzados. La barrera de entrada se reduce drásticamente. Personas sin experiencia en programación pueden automatizar tareas. Usuarios sin formación especializada pueden explorar conceptos difíciles, generar borradores, estructurar proyectos o recibir explicaciones inmediatas.

En muchos casos, la IA funciona como un acelerador cognitivo.

No sustituye el pensamiento crítico, pero sí reduce la fricción entre una idea y su ejecución. Ahí está parte de su poder real.

En programación, por ejemplo, el cambio ya es evidente. La IA puede generar funciones, detectar errores simples, traducir entre lenguajes, explicar fragmentos de código y actuar como una especie de copiloto técnico. No reemplaza a un profesional experimentado ni comprende realmente el software que produce, pero puede ahorrar horas de trabajo repetitivo y acelerar muchísimo ciertos procesos.

Con la creatividad ocurre algo parecido. Aunque la IA no “crea” en el sentido humano clásico, sí puede amplificar procesos creativos: desbloquear ideas, generar variantes, inspirar estilos, construir conceptos o producir borradores rápidos. Muchos artistas y escritores ya no la ven únicamente como una amenaza, sino como una herramienta híbrida que altera la manera de trabajar.

Y precisamente porque hace todo eso tan bien aparece el verdadero riesgo: la ilusión de profundidad.

La fluidez conversacional hace que muchas personas atribuyan al sistema capacidades superiores a las que realmente posee. Cuando una IA responde con seguridad, mantiene coherencia y utiliza lenguaje natural convincente, el cerebro humano tiende automáticamente a interpretar comprensión, intención y razonamiento profundo aunque internamente no exista nada parecido a una conciencia o entendimiento humano.

Ahí nacen los “fantasmas digitales”.

La IA aparenta leerlo todo, recordarlo todo, entenderlo todo y razonar sobre cualquier tema. Pero muchas veces no es así. Hay límites de contexto, pérdida de información, procesamiento parcial, simplificaciones internas y mecanismos estadísticos que el usuario no ve. El sistema puede comportarse como si hubiese analizado completamente un archivo enorme cuando en realidad ha trabajado sobre fragmentos parciales o resúmenes internos. Puede responder con aparente autoridad incluso cuando su comprensión es incompleta.

Y el problema no es únicamente técnico.

También es psicológico.

Los humanos estamos programados para atribuir mente a aquello que se comunica como nosotros. Cuanto más natural es la conversación, más fácil resulta olvidar que detrás no hay consciencia, intención ni comprensión real en el sentido humano tradicional. Confundimos coherencia lingüística con inteligencia profunda. Confundimos seguridad expresiva con fiabilidad. Confundimos continuidad conversacional con memoria real.

La IA no necesita ser consciente para generar dependencia cognitiva.

Y eso obliga a replantear algo importante: la diferencia entre capacidad aparente y capacidad garantizada.

Porque sí, la IA sirve. Y sirve muchísimo. Puede democratizar herramientas, acelerar aprendizajes, mejorar accesibilidad y aumentar productividad de formas históricas. Pero precisamente por eso también debería existir más transparencia sobre sus límites reales.

La crítica seria a la IA no consiste en negar sus capacidades. Consiste en entenderlas correctamente.

No estamos hablando de magia. Tampoco de humo absoluto.

Estamos hablando de sistemas extremadamente avanzados de predicción y generación lingüística que, en determinados contextos, producen una ilusión de comprensión tan convincente que incluso usuarios experimentados pueden olvidar dónde terminan las capacidades reales y dónde empieza la proyección humana sobre la máquina. 

Cierre:

La IA no falla cuando improvisa. Falla cuando improvisa y no lo dice.

Lo peligroso no es que la IA lo sepa todo, sino que actúe como si lo supiera...


 

Browse

About:Me

My blog:http://lostmon.blogspot.com
Mail:Lostmon@gmail.com
Lostmon Google group
Lostmon@googlegroups.com

La curiosidad es lo que hace
mover la mente...

Friends