Showing posts with label Structured Text Amplification. Show all posts
Showing posts with label Structured Text Amplification. Show all posts

STA The Print Preview Vector

Friday, September 04, 2026
STA The Print Preview Vector: Document Amplification Through Android Print Service

STA — The Print Preview Vector

This article documents the Print Preview amplification chain in Android — a Class A (IPC/SavedState) vector where oversized document previews exceed the Binder transaction limit, causing crashes in the Print Service, SystemUI, and, in the most severe cases, persistent crash loops requiring a hard reboot.


1. Overview

The Print Preview vector is a Class A amplification chain that begins when a user selects the Print or Print Preview option from an application — particularly Google Drive, PDF viewers, or document editors. The system constructs a preview Bundle containing page data, text, and metadata, and attempts to send it across the Binder IPC boundary to the Print Service, Print Spooler, or SystemUI.

Because no size validation is performed before serialization, a sufficiently large document (e.g., a complex DOCX, a high-resolution PDF, or a long text document) can produce a Bundle that exceeds the 1,048,576-byte Binder limit. When this happens, a TransactionTooLargeException is thrown — and in many cases, it remains uncaught. The result is a crash of the Print Service, the calling application, or SystemUI itself.

In the most severe scenarios, the crash corrupts the TaskPersister state on disk, causing a persistent crash loop that survives reboots and requires manual data clearance.

The full amplification chain is as follows:

Large document (Google Drive, PDF, DOCX)
        ↓
User selects "Print" or "Print Preview"
        ↓
Print Service builds a preview Bundle
        ↓
Bundle serialized → Parcel → Binder
        ↓
Exceeds 1 MB limit → TransactionTooLargeException
        ↓
Uncaught exception → Crash (app, Print Service, or SystemUI)
        ↓
If state is persisted (SavedState / TaskPersister) → Crash loop

Key observation: This vector is structurally identical to the WhatsApp ×20.6 amplification (STA-005) and the Threads deep-link crash (STA-012). In all cases, a structured payload crosses a Binder-backed boundary without a length check, and the resulting exception propagates uncaught.


2. Documented Vectors

The Print Preview amplification manifests in at least four distinct but related vectors, each affecting a different layer of the Android stack:

IDComponentMechanismCVSSPersistenceTier
STA-009 Google Drive → Print Preview Opening the print preview of a large DOCX/PDF generates a Bundle that exceeds the Binder limit, crashing the app. 6.5 Yes (until reboot) A
STA-010 Print Service → local printer The same oversized Bundle is sent to the local print service (SystemUI), causing SystemUI to crash. 7.2 Yes (until reboot) A
STA-010b Google Play Services → cloud printer Variant of STA-010 routed through Google Play Services. 6.5 Yes (until app closed) A
STA-018 Google Drive + Print Service + SystemUI Full chain: ANR in browser → TaskPersister corruption → SystemUI crash loop. Hard reboot required. 7.5 Yes (until reboot) A

All four vectors have been reproduced on Android 13–16 across multiple OEMs (Xiaomi, Samsung, OPPO, OnePlus, Pixel) and are classified as Tier A (full stack trace + exception + Bundle analysis).


3. Technical Evidence

3.1. SystemUI Crash During Print Preview

Bugreports captured on a Xiaomi Redmi Note 14 5G (HyperOS 3.0 / Android 16) show SystemUI crashing when a print preview is opened for a large document. The following stack trace was extracted from a production bugreport:

// SystemUI crash during Print Preview
android.os.TransactionTooLargeException: data parcel size 1,456,832 bytes
  at android.os.BinderProxy.transactNative(Native Method)
  at android.os.BinderProxy.transact(BinderProxy.java:642)
  at android.print.IPrintManager$Stub$Proxy.print(IPrintManager.java:456)
  at android.print.PrintManager.print(PrintManager.java:789)
  at com.google.android.apps.docs.print.PrintPreviewActivity.onCreate(...)
  at android.app.ActivityThread.performLaunchActivity(...)
  at android.app.ActivityThread.handleLaunchActivity(...)
  at android.app.servertransaction.LaunchActivityItem.execute(...)

Analysis: The Print Manager attempts to send the preview Bundle across Binder, but its size (1,456,832 bytes) exceeds the 1,048,576-byte limit. The resulting TransactionTooLargeException is not caught, and SystemUI crashes. The crash occurs before the user can interact with the print dialog, making it a reliable denial-of-service vector.

3.2. TaskPersister Corruption (STA-018)

In more severe cases — particularly on devices with OEM customisations (Xiaomi HyperOS) — the SystemUI crash corrupts the TaskPersister state on disk. Upon restart, SystemUI reads the corrupt state and crashes again, entering a persistent crash loop that requires a full device reboot or manual data clearance.

// TaskPersister corruption after Print Preview crash
E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.android.systemui, PID: 1234
    android.os.BadParcelableException: Failure retrieving array; only received 1 of 4
        at android.content.pm.BaseParceledListSlice.<init>(...)
        at android.window.ITaskOrganizerController$Stub$Proxy.registerTaskOrganizer(...)
        at android.window.TaskOrganizer.registerOrganizer(TaskOrganizer.java:76)
        at com.android.wm.shell.sysui.ShellInit.init(...)
    Caused by: android.os.DeadObjectException: Transaction failed on small parcel

This demonstrates that the Print Preview vector can escalate beyond a transient crash and become a persistent denial-of-service condition that affects the entire device UI.

3.3. Bundle Size Amplification

As with other Class A vectors, the amplification factor depends on the structure of the document and the nesting depth of the Fragment hierarchy. In the case of Google Drive's print preview, a document of approximately 80–100 KB can generate a Bundle of 1.2–1.5 MB, exceeding the Binder limit by 20–50%.

This amplification is consistent with the pattern observed in WhatsApp (×20.6) and TikTok (×286), where nested FragmentManager state multiplies the original payload size at each level.


4. Connection to AndroidX PdfView Commit

On 14 July 2026, a commit was merged into AndroidX (8882927e7d41e678c6f03f50d4bd5950e7dc6c47) that fixes a TransactionTooLargeException in PdfView. The commit message states:

“When a user selects content across a large range of pages (e.g., 500 pages), the serialized SelectionModel exceeds 1.2 MB. Serializing this into onSaveInstanceState triggers an unhandled TransactionTooLargeException over the kernel Binder IPC driver right when the app goes into the background.”

The fix was to change the persistent representation: rather than serialising the full SelectionModel, only anchor points (~44 bytes) are saved, and the full state is reconstructed asynchronously upon restoration.

Note: This commit is independent of the STA research, but it confirms that Google is actively mitigating the same general class of oversized‑state / Binder‑boundary problems in components related to document handling and print preview.

However, the commit is scoped to androidx.pdf.viewer.PdfView only. It does not address the Print Service, SystemUI, or TaskPersister paths documented in STA-009, STA-010, and STA-018. As of September 2026, those paths remain publicly unpatched.


5. Relation to Other STA Vectors

VectorConnection
STA-015-DL Similar chain (Google Drive HTML → browser ANR → SystemUI crash loop), but triggered via a web link rather than the print UI. Both share the TaskPersister corruption mechanism.
STA-005 Class A amplification through FragmentManager / SavedState, but in the context of messaging apps (WhatsApp) rather than printing. The underlying cause — oversized Bundle → Binder → uncaught exception — is identical.
STA-012 Threads deep-link crash. Also Class A, also involves a structured payload crossing Binder without validation.
STA-017 Class B (libminikin ANR) — unrelated to printing, but shares the same root‑cause pattern: missing size validation before an expensive operation (text layout in libminikin; Binder serialisation in Print Service).

The Print Preview vectors are a clear demonstration that the STA pattern is not confined to a single application or component. It recurs across document handling, messaging, and system UI — all tied to the same underlying architectural gap: structured input → serialization → Binder → uncaught exception → crash.


6. Mitigation Recommendations

6.1. Framework (AOSP / AndroidX)

  • Validate Bundle size before serialization in PrintManager and PrintService — reject or truncate if the 1 MB limit is approached.
  • Catch TransactionTooLargeException in both the Print Service and SystemUI, and degrade gracefully (show an error message instead of crashing).
  • Adopt LargePayloadSupport (FD‑based transfer) for print previews, similar to what already exists for Credential Manager and Digital Credentials.
  • Prevent TaskPersister corruption by validating restored state size before persisting it to disk.

6.2. Application-level (Google Drive, document viewers)

  • Truncate document content before passing it to the Print Service — limit the number of pages, reduce preview resolution, or cap text length to 50,000 characters.
  • Reject print intents that contain oversized documents (e.g., by checking the document size before calling PrintManager.print()).

6.3. OEM-specific (HyperOS, One UI, ColorOS)

  • OEMs should apply safe degradation patterns in their Task State Interactors, similar to the pattern proposed in Section 16.4 of the STA whitepaper (catch DeadObjectException and emit null instead of crashing).

7. Conclusion

The Print Preview vector is a clear and well-documented manifestation of Class A Structured Text Amplification in a system‑level service (Print Service / SystemUI). It demonstrates that the same architectural pattern — structured input → serialization → Binder → uncaught exception → crash — recurs across multiple surfaces, from messaging apps to document handling to system UI.

The independent AndroidX fix for PdfView confirms that Google is aware of this class of problems, but the Print Service and SystemUI paths remain unpatched as of September 2026. Organisations relying on Android for document workflows should consider implementing defensive truncation at the application level.

This vector also reinforces the broader STA thesis: the problem is not a single bug, but a systemic architectural gap that requires a coordinated, cross‑component response from the Android framework.


8. Related Publications


El dilema de la divulgaci贸n coordinada

Monday, August 31, 2026

Cuando la responsabilidad es unilateral: el dilema de la divulgaci贸n coordinada

Una reflexi贸n sobre el modelo actual de seguridad, sus asimetr铆as y sus consecuencias

Imagina la siguiente situaci贸n:

Has pasado semanas, quiz谩s meses, investigando un comportamiento extra帽o en un sistema ampliamente utilizado. Has reproducido el problema en diferentes dispositivos. Has capturado logs, stacktraces, m茅tricas de sistema. Has documentado cada paso con precisi贸n. Has preparado un informe que cualquier ingeniero podr铆a seguir para verificar el problema por s铆 mismo.

Env铆as el reporte al fabricante. Esperas. Recibes una respuesta autom谩tica. Semanas despu茅s, alguien te pide m谩s informaci贸n. La proporcionas. Vuelves a esperar.

Finalmente, recibes una respuesta:

“Hemos revisado tu informe y determinado que no cumple con los criterios para ser considerado un bug de seguridad.”

“Este problema pertenece a otro equipo.”

“Est谩 fuera del alcance de nuestro programa de recompensas.”

“Por favor, utiliza el feedback in-product para reportarlo.”

El problema sigue existiendo. Los usuarios siguen expuestos. Pero la responsabilidad ha quedado diluida en un laberinto de equipos, programas y criterios.

Esta historia es m谩s com煤n de lo que muchos creen. Y revela una asimetr铆a estructural en el modelo de divulgaci贸n coordinada que merece un an谩lisis profundo.

Este art铆culo no trata sobre una vulnerabilidad concreta. Trata sobre el sistema que la gestiona o, m谩s precisamente, sobre el sistema que a menudo no la gestiona.


1. El contrato impl铆cito de la divulgaci贸n responsable

La divulgaci贸n responsable, tambi茅n llamada coordinada, se ha establecido como el est谩ndar 茅tico en la seguridad inform谩tica. Su premisa es sencilla y, en apariencia, incuestionable:

“Si conocemos un problema que puede afectar a otros, debemos dar al fabricante la oportunidad de solucionarlo antes de hacerlo p煤blico.”

Esta l贸gica protege a los usuarios. Permite que las empresas corrijan vulnerabilidades sin exponer a sus clientes a ataques mientras el parche est谩 en desarrollo. Es un modelo que, en teor铆a, beneficia a todas las partes.

En la pr谩ctica, el investigador acepta un conjunto de obligaciones que incluyen:

  • Reproducir el problema de forma fiable y documentada.
  • Proporcionar evidencia t茅cnica suficiente (logs, trazas, c贸digo, pasos).
  • Evitar divulgar prematuramente para no poner en riesgo a los usuarios.
  • Informar al fabricante a trav茅s de los canales establecidos.
  • Facilitar la investigaci贸n con informaci贸n adicional cuando se solicita.
  • Respetar los plazos de coordinaci贸n que la empresa propone.
  • Permitir que el proveedor prepare una soluci贸n antes de la publicaci贸n.
  • Documentar sus conclusiones de forma responsable y precisa.

Y, en muchos casos, el investigador hace todo esto sin ninguna garant铆a de reconocimiento, parche o recompensa. Lo hace porque cree en el modelo. Porque entiende que la seguridad es una responsabilidad compartida.

La l贸gica es impecable. Pero esa misma l贸gica deber铆a funcionar en ambas direcciones.


2. El problema aparece cuando nadie es responsable y a la vez, lo son todas las partes inplicadas

Durante una investigaci贸n pueden aparecer problemas que atraviesan diferentes capas de un sistema. Un mismo comportamiento puede involucrar:

  • Aplicaci贸n (el software que el usuario ve)
  • Framework (la capa intermedia que soporta la aplicaci贸n)
  • Biblioteca nativa (c贸digo de bajo nivel, a menudo en C/C++)
  • Sistema operativo (el n煤cleo del sistema)
  • Fabricante / OEM (personalizaciones del sistema)

Y tambi茅n:

  • Producto A (ej. Chrome, Firefox, Edge)
  • Producto B (ej. Android)
  • Componente compartido (ej. libminikin)
  • Infraestructura com煤n (ej. Binder, IPC)
  • Servicio en la nube (ej. Llm's API)

Entonces aparece el fen贸meno conocido por muchos investigadores:

“No es nuestro problema.”

Un equipo o vendor, puede indicar: “Esto es un problema de Android.”
Android puede responder: “No est谩 dentro del alcance de nuestro programa.”
Otro equipo puede a帽adir: “Debe reportarse al producto correspondiente.”

Y el investigador vuelve al punto de partida.

El atacante no necesita saber qu茅 equipo es responsable. El investigador tampoco deber铆a tener que resolver el organigrama interno de una multinacional para encontrar al responsable. Si el problema atraviesa capas, el atacante ve un sistema. El investigador ve un sistema. La organizaci贸n, sin embargo, puede verlo como tres equipos o m谩s distintos.


3. El caso STA: una investigaci贸n transversal

Mi investigaci贸n sobre Structured Text Amplification (STA) comenz贸 en 2022, estudiando comportamientos relacionados con texto estructurado y agotamiento de recursos en Android. Lo que parec铆a un problema aislado en una biblioteca fue revelando un patr贸n m谩s amplio.

Con el tiempo, aparecieron diferentes manifestaciones en distintos componentes:

Componente S铆ntoma Mecanismo
libminikin.so ANR, bloqueo del hilo principal Knuth-Plass O(n²)
Binder / SavedState TransactionTooLargeException, crash loops Serializaci贸n O(n²)
Llm's (modelo) Instruction Drift, generaci贸n de contenido sin contexto Atenci贸n O(n²)
Llm's (cliente) ANR, UI freeze libminikin O(n²)
Navegadores Bloqueo de renderizado Algoritmos de layout O(n²)

Lo interesante no era cada fallo individual, sino la posibilidad de que existiera un patr贸n com煤n:

Entrada estructurada (texto repetitivo, baja entrop铆a)
              ↓
    Transformaci贸n (tokenizaci贸n, layout, serializaci贸n)
              ↓
    Amplificaci贸n del coste (algoritmo O(n²))
              ↓
    Agotamiento de recursos (CPU, memoria, tiempo)
              ↓
    P茅rdida de disponibilidad (ANR, crash, DoS)

Este patr贸n aparec铆a en el cliente Android (la apps de Google, Mozilla, Meta, Microsoft, Xiaomi, entre otros). Aparec铆a en el sistema operativo (libminikin, Binder). Y, m谩s tarde, apareci贸 tambi茅n en los Llm's, tanto en el modelo (p茅rdida de contexto) como en el cliente (ANR al renderizar respuestas largas o tareas simples como contar caracteres ).

El problema era real, reproducible y estaba documentado con stacktraces, m茅tricas de sistema y pasos concretos. Pero al intentar reportarlo siguiendo los cauces establecidos, ocurri贸 lo que muchos investigadores han vivido:

  • VRP's: “Fuera de alcance.”
  • llm's VRP: “Bypass de guardrail de seguridad. Fuera de alcance.”
  • Feedback in-product: Canal adecuado, pero sin garant铆a de respuesta o mitigaci贸n.

El patr贸n STA exist铆a. Las evidencias eran s贸lidas. Pero la responsabilidad quedaba diluida entre equipos, programas y criterios.


4. La anatom铆a de una derivaci贸n

Para entender el problema, es 煤til analizar qu茅 ocurre cuando un reporte atraviesa el sistema de gesti贸n de vulnerabilidades de una gran organizaci贸n.

Fase 1: Recepci贸n
El investigador env铆a un informe detallado. Recibe un acuse de recibo autom谩tico. El reporte entra en una cola de triaje.

Fase 2: Triaje inicial
Un revisor, a menudo con poco tiempo y muchos reportes, clasifica el problema. Si encaja en un patr贸n conocido, puede ser asignado a un equipo. Si no, puede ser rechazado por “falta de informaci贸n” o “no reproducible”.

Fase 3: An谩lisis t茅cnico
El equipo asignado analiza el problema. Si el equipo es el correcto, la investigaci贸n avanza. Si el problema cruza fronteras, aparece la pregunta: “¿Es realmente nuestro?”

Fase 4: Derivaci贸n
El problema se traslada a otro equipo. Ese equipo, a su vez, puede derivarlo a otro. Cada derivaci贸n reinicia parcialmente el proceso. Cada equipo aplica sus propios criterios.

Fase 5: Decisi贸n final
En alg煤n punto, el problema es clasificado como “fuera de alcance”, “no elegible para recompensa” o “no reproducible”. El investigador recibe una respuesta. El problema sigue existiendo.

Lo parad贸jico es que cada decisi贸n individual puede ser razonable. Cada equipo puede tener argumentos v谩lidos para no asumir la responsabilidad. Pero el resultado final es que el problema no se soluciona.

Y el investigador, que empez贸 con la intenci贸n de ayudar, se encuentra con un muro de silencio.


5. “Out of scope” no significa “el problema no existe”

Hay una confusi贸n conceptual que conviene aclarar.

Un programa de recompensas puede establecer leg铆timamente qu茅 tipos de problemas son elegibles para recompensa. Esa es una decisi贸n de alcance. Es razonable que una empresa defina los l铆mites de su programa.

Pero:

No elegible para recompensa ≠ inexistente.

Un problema puede quedar fuera de un VRP y seguir siendo:

  • Reproducible.
  • T茅cnicamente relevante.
  • Peligroso para determinados usuarios.
  • Digno de una mitigaci贸n.
  • Digno de una investigaci贸n interna.
  • Digno de ser documentado p煤blicamente.

Esta distinci贸n es fundamental. Un programa de recompensas puede rechazar un reporte por alcance, pero eso no significa que el equipo de producto deba ignorarlo.

El problema ocurre cuando “fuera de alcance” se convierte en un sin贸nimo de “no es responsabilidad nuestra” y cuando esa falta de responsabilidad impide que el problema se solucione.


6. El coste de la investigaci贸n independiente

Para entender la asimetr铆a, hay que considerar los recursos de cada parte.

Una gran organizaci贸n puede disponer de:

  • Equipos especializados en diferentes 谩reas.
  • Acceso al c贸digo fuente completo.
  • Infraestructura de reproducci贸n a gran escala.
  • Telemetr铆a para identificar la prevalencia del problema.
  • Ingenieros dedicados a tiempo completo.
  • Herramientas internas de an谩lisis y depuraci贸n.
  • Capacidad para parchear millones de dispositivos en d铆as o semanas.
  • Departamento legal para gestionar riesgos.
  • Presupuesto para recompensas y reconocimiento.

El investigador independiente, en cambio, puede disponer de:

  • Un ordenador (a menudo personal).
  • Un tel茅fono (a menudo personal).
  • Unos bugreport (obtenidos con esfuerzo).
  • Una conexi贸n a Internet.
  • Y muchas horas de trabajo no remunerado.

En mi caso, buena parte de esta investigaci贸n se ha realizado desde un entorno dom茅stico. No hay un laboratorio detr谩s, ni un departamento legal, ni un equipo de ingenier铆a esperando para validar cada hip贸tesis. La validaci贸n de las evidencias recae enteramente en el investigador.

Y, sin embargo, el investigador debe proporcionar evidencia suficientemente s贸lida para que una organizaci贸n pueda tomar una decisi贸n. La exigencia es leg铆tima. La reciprocidad deber铆a serlo tambi茅n.


7. Cuando la evidencia contradice la respuesta inicial

Una de las situaciones m谩s reveladoras ocurre cuando la primera conclusi贸n de la organizaci贸n es:

“No reproducible.”

Pero posteriormente aparecen:

  • Nuevos dispositivos donde el problema se manifiesta.
  • Nuevos dumps con stacktraces adicionales.
  • Nuevos ANR traces en el mismo componente.
  • Nuevas aplicaciones afectadas por el mismo patr贸n.
  • Nuevas reproducciones que confirman la hip贸tesis.
  • Evidencia del mismo componente en diferentes contextos.
  • Comportamiento consistente entre productos.

Entonces la pregunta ya no deber铆a ser:

“¿Por qu茅 el investigador insiste?”

La pregunta deber铆a ser:

“¿Qu茅 hemos aprendido desde la primera evaluaci贸n?”

La seguridad no deber铆a funcionar como un juicio que termina con la primera decisi贸n. Deber铆a funcionar como un proceso iterativo:

Hip贸tesis inicial
        ↓
Evidencia recopilada
        ↓
Reproducci贸n en condiciones controladas
        ↓
An谩lisis t茅cnico
        ↓
Nueva evidencia (m谩s dispositivos, m谩s contextos)
        ↓
Reevaluaci贸n de la hip贸tesis
        ↓
Actualizaci贸n de la decisi贸n

Este ciclo es com煤n en la investigaci贸n cient铆fica. En la seguridad, sin embargo, tiende a ser lineal: una decisi贸n inicial, sin espacio para la reevaluaci贸n.


8. La paradoja de la coordinaci贸n

Cuando una organizaci贸n solicita coordinaci贸n, el mensaje es claro:

“Danos tiempo para investigar y solucionar el problema.”

El investigador acepta. Pero la coordinaci贸n implica una segunda obligaci贸n: utilizar ese tiempo de forma efectiva.

La coordinaci贸n no deber铆a significar:

Investigador
    ↓
Reporte (con evidencia)
    ↓
Espera (semanas o meses)
    ↓
"No reproducible"
    ↓
Investigador aporta m谩s evidencia
    ↓
Espera
    ↓
"Out of scope"
    ↓
Investigador apela
    ↓
Espera
    ↓
"Pertenece a otro equipo"
    ↓
Investigador reporta al otro equipo
    ↓
El ciclo se reinicia

Eso no es coordinaci贸n. Es derivaci贸n de responsabilidad. Es un laberinto donde el investigador es el 煤nico que recorre todas las salas, mientras la organizaci贸n mantiene sus puertas cerradas.


9. Una contradicci贸n evidente

Al investigador se le dice:

“No publiques todav铆a.”

Perfecto. Es razonable.

Pero si despu茅s de meses o a帽os la respuesta contin煤a siendo:

“No es nuestro problema.”

¿Durante cu谩nto tiempo debe permanecer el investigador en silencio?

  • ¿Qui茅n protege al usuario durante ese periodo?
  • ¿Qui茅n asume el riesgo de que el problema sea explotado?
  • ¿Qui茅n decide que el problema merece atenci贸n?
  • ¿Qui茅n determina si el problema es “suficientemente grave”?
  • ¿D贸nde termina la responsabilidad del investigador y empieza la responsabilidad del fabricante?

El modelo actual responde a estas preguntas de forma impl铆cita:

“El investigador es responsable de no divulgar. El fabricante es responsable de decidir si el problema existe.”

Pero la decisi贸n de “si el problema existe” no deber铆a ser una decisi贸n unilateral, especialmente cuando el investigador ha aportado evidencia s贸lida y reproducible.


10. La responsabilidad no puede viajar solo en una direcci贸n

El modelo actual puede resumirse as铆:

Investigador Organizaci贸n
Reproducir el problema Investigar t茅cnicamente
Documentar con evidencias Validar la informaci贸n
Reportar a trav茅s de los canales Responder en tiempo razonable
Coordinar la divulgaci贸n Coordinar la correcci贸n
Esperar el tiempo necesario Actuar sobre el problema
No divulgar prematuramente Mitigar el riesgo
Facilitar informaci贸n adicional Asumir responsabilidad

El problema aparece cuando la segunda columna se convierte en:

“No corresponde a nuestro programa.”

“No es elegible para recompensa.”

“Pertenece a otro equipo.”

Entonces la primera columna sigue teniendo todas las obligaciones, mientras que la segunda conserva 煤nicamente la posibilidad de rechazar el caso.

Eso es una asimetr铆a estructural. No es un fallo de una empresa concreta. Es un fallo del modelo.


11. La recompensa tampoco deber铆a ser el centro

Hay una cuesti贸n especialmente importante que suele pasarse por alto.

La investigaci贸n de seguridad no deber铆a reducirse a:

Bug → CVE → recompensa

Hay investigadores que buscan dinero. Otros buscan reconocimiento. Otros simplemente quieren que el problema se arregle. Algunos investigan porque quieren comprender c贸mo funcionan los sistemas y compartir ese conocimiento.

Por eso una respuesta como:

“No es elegible para recompensa”

no deber铆a cerrar necesariamente la conversaci贸n t茅cnica.

Podr铆a existir otra respuesta:

“No podemos recompensarlo seg煤n las reglas del programa, pero hemos identificado el problema y vamos a mitigarlo.”

“Hemos derivado el problema al equipo de producto para que lo eval煤e en futuras versiones.”

Esa ser铆a una respuesta mucho m谩s saludable para el ecosistema.


12. El silencio como estrategia

Hay una realidad inc贸moda que pocos investigadores mencionan abiertamente.

En algunos casos, el silencio —o la derivaci贸n, no es un fallo del sistema, sino una estrategia deliberada.

Si un problema no se clasifica como vulnerabilidad, no hay obligaci贸n de parchearlo.
Si el problema se deriva a otro equipo, la responsabilidad queda en suspenso.
Si el investigador se cansa y desiste, el problema desaparece del radar.

Esta estrategia no requiere mala fe. Puede ser simplemente el resultado de equipos que trabajan bajo presi贸n, con recursos limitados, y que priorizan los problemas que encajan en sus m茅tricas.

Pero el efecto es el mismo: el problema no se soluciona.


13. El investigador independiente no tiene voz en la decisi贸n

Una de las asimetr铆as m谩s profundas es la siguiente:

El investigador aporta el descubrimiento. Aporta la evidencia. Aporta el tiempo. Aporta la paciencia. Aporta la buena fe.

Pero no tiene voz en la decisi贸n final.

  • No decide si el problema es “suficientemente grave”.
  • No decide si merece un parche.
  • No decide cu谩ndo se solucionar谩.
  • No decide si se reconocer谩 su trabajo.
  • No decide si se comunicar谩 p煤blicamente.

La organizaci贸n tiene todas esas decisiones. El investigador tiene solo la decisi贸n de publicar o no publicar.

Y esa decisi贸n, publicar, est谩 cargada de riesgos: legales, reputacionales, y de relaci贸n con futuros reportes.


14. Divulgaci贸n coordinada no es silencio coordinado

Existe una diferencia esencial entre ambas cosas:

Divulgaci贸n coordinada:

“Tenemos un problema. Trabajemos juntos para entenderlo, mitigarlo y comunicarlo de forma responsable.”

Silencio coordinado:

“El problema est谩 reportado, pero nadie quiere asumir la responsabilidad. El investigador espera. El problema sigue existiendo.”

La primera protege a los usuarios. La segunda protege principalmente al proceso.

La primera es colaboraci贸n. La segunda es inacci贸n.

Y la seguridad deber铆a estar dise帽ada para proteger a los usuarios, no los procesos internos.


15. El caso STA como ejemplo de un problema m谩s amplio

STA no es una excepci贸n. Es un ejemplo de lo que ocurre cuando un comportamiento atraviesa diferentes capas de un ecosistema y la responsabilidad queda fragmentada.

En mi investigaci贸n, el mismo patr贸n apareci贸 en:

  • Android (libminikin, Binder, SavedState).
  • Llm's (modelo y cliente).
  • Aplicaciones de terceros (WhatsApp, navegadores).
  • Componentes compartidos (StaticLayout, LineBreaker).

Cada uno de estos dominios tiene sus propios equipos, sus propios programas de recompensas, sus propios criterios y sus propias prioridades.

Pero el patr贸n subyacente es el mismo. Es la misma entrada estructurada, la misma amplificaci贸n de coste, el mismo agotamiento de recursos.

Sin embargo, cuando intent茅 reportarlo de forma transversal, me encontr茅 con que:

  • VRP's lo consideraron “fuera de alcance”.
  • llm's VRP lo consideraron “safety guardrail bypass”.
  • El feedback in-product no garantiza respuesta ni mitigaci贸n.
  • El problema sigue existiendo.

STA no es un problema de un equipo. Es un problema de arquitectura. Y los problemas de arquitectura no se solucionan derivando responsabilidades.


16. Lo que deber铆a cambiar

Para que la divulgaci贸n coordinada funcione de forma efectiva, se necesitan algunos cambios en el modelo actual:

a. Puntos de entrada transversales
Las grandes organizaciones deber铆an tener puntos de entrada para problemas que cruzan equipos. Un equipo central de triaje que pueda evaluar un problema t茅cnico sin necesidad de que el investigador conozca el organigrama interno.

b. Distinci贸n clara entre “alcance” y “existencia”
Que un problema no sea elegible para recompensa no deber铆a impedir que el equipo de producto lo eval煤e y, si es necesario, lo mitigue.

c. Procesos de reevaluaci贸n
Si el investigador aporta evidencia adicional que contradice una decisi贸n inicial, deber铆a existir un proceso para reabrir la investigaci贸n sin necesidad de reiniciar todo el ciclo.

d. Comunicaci贸n transparente
Si el problema se deriva a otro equipo, el investigador deber铆a ser informado de forma clara, con un punto de contacto o un identificador de seguimiento.

e. Reconocimiento sin recompensa
Si el problema no cumple los criterios de recompensa, pero es t茅cnicamente relevante, la organizaci贸n deber铆a poder ofrecer un reconocimiento simb贸lico (menci贸n en los agradecimientos, nota en las release notes, etc.).


17. Una pregunta inc贸moda (y su respuesta)

Despu茅s de a帽os investigando vulnerabilidades, con mas de 400 descubiertas y documentadas y mas de 80 CVE, observando este patr贸n, hay una pregunta que considero inevitable:

¿Qu茅 debe hacer un investigador cuando ha cumplido con todas las reglas de la divulgaci贸n responsable, pero ninguna organizaci贸n acepta la responsabilidad de solucionar el problema?

No tengo una respuesta sencilla. Pero s铆 tengo una conclusi贸n:

La responsabilidad no puede exigirse unilateralmente.

Si se espera que el investigador act煤e responsablemente para proteger a los usuarios, las organizaciones deben hacer lo mismo. La seguridad no es un juego de trileros donde la responsabilidad se pasa de una mano a otra hasta que el investigador se cansa.

El investigador debe asumir su parte. Pero la organizaci贸n tambi茅n.


18. El objetivo final

No se trata de ganar una discusi贸n. No se trata de conseguir una recompensa. No se trata de demostrar que una empresa se equivoc贸.

Se trata de algo mucho m谩s sencillo:

Que el problema deje de existir.
  • Si una vulnerabilidad puede solucionarse, solucion茅mosla.
  • Si no es vulnerable, demostremos por qu茅.
  • Si est谩 fuera del alcance de un programa, deriv茅mosla al equipo adecuado.
  • Si el impacto no alcanza el umbral de una recompensa, eso no impide investigarla.

Pero no deber铆amos permitir que el 煤ltimo paso sea:

“Este problema pertenece a otro.”

Porque entonces el problema sigue perteneciendo a todos. Y, al final, a nadie.


19. Una llamada a la responsabilidad compartida

La divulgaci贸n responsable naci贸 como un pacto de confianza entre investigadores y fabricantes. Ese pacto sigue siendo necesario. Pero la confianza funciona en ambas direcciones.

El investigador debe asumir responsabilidad por lo que descubre.

  • Investigar con rigor.
  • Documentar con precisi贸n.
  • Reportar con buena fe.
  • Coordinar con paciencia.
  • Divulgar con responsabilidad.

Las empresas deben asumir responsabilidad por lo que construyen.

  • Responder con seriedad.
  • Investigar cuando exista evidencia suficiente.
  • Distinguir entre “fuera de alcance” y “no existe”.
  • Evitar derivaciones infinitas.
  • Proporcionar puntos de contacto adecuados.
  • Informar cuando la investigaci贸n contin煤a.
  • Mitigar cuando sea necesario.

Cuando un investigador entrega evidencia reproducible, concede tiempo y respeta los mecanismos de coordinaci贸n, la respuesta no deber铆a ser una cadena infinita de derivaciones.

Deber铆a existir una puerta de entrada.

Alguien que diga:

“Entendido. Nosotros nos encargamos de averiguar qui茅n debe solucionarlo.”

Porque esa es precisamente la diferencia entre gestionar un reporte y gestionar un riesgo de seguridad.


Conclusi贸n: la seguridad no es un juego de trileros

La seguridad inform谩tica es un campo que se basa en la confianza. Confiamos en que los fabricantes corrigen los problemas que les reportamos. Confiamos en que los investigadores no explotan las vulnerabilidades antes de que se solucionen.

Pero la confianza no es un recurso infinito. Se agota cuando una de las partes no cumple su parte.

La divulgaci贸n coordinada no deber铆a ser una excusa para que las empresas trasladen todo el riesgo al investigador. No deber铆a ser un mecanismo para silenciar problemas inc贸modos. No deber铆a ser un laberinto del que el investigador no pueda salir.

Deber铆a ser un proceso colaborativo donde ambas partes asumen sus responsabilidades para proteger a los usuarios.

El investigador descubre. El fabricante corrige.

Y el usuario, al final, est谩 protegido.

Ese es el objetivo. No deber铆amos perderlo de vista.


Como final del art铆culo dir茅: si clicar en un enlace causa el crash wn una aplicaci贸n y esta aplicaci贸n hace caer SystemUI y a su vez causa un loop de reinicios y se la interfaz y obliga al sistema a borrar sus propios datos de estado etc y de la que un usuario normal no sabe recuperarse, no es un problema de seguridad entonces que es?

Manuel Garc铆a Pe帽a (Lostmon)Independent Security Researcher
Agosto de 2026

STA-012 Threads: When a deep link becomes a persistent crash loop

Wednesday, August 26, 2026

STA-012 Threads: When a deep link becomes a persistent crash loop

Structured Text Amplification Vector STA 012

This post documents STA-012, a persistent denial-of-service vector in Meta's Threads app for Android. An oversized payload delivered via a deep link can contaminate the app's SavedState, causing a permanent crash loop that requires clearing app data to recover.

⚠️ Severity: STA-012 is a persistent DoS vector. A single click on a crafted deep link can make Threads permanently unusable until the user clears app data. No special permissions or privileges are required.


1. Summary

STA-012 describes a persistent denial-of-service condition in Meta's Threads app for Android. An attacker can craft a deep link with an oversized q parameter that, when opened, contaminates the app's SavedState. The app subsequently enters a permanent crash loop that only resolves by clearing the app data.

The vector is triggered when the user clicks a crafted deep link. Threads stores the search query in Fragment arguments, which are then serialized into a Bundle as part of the SavedState. When the Bundle size exceeds the Binder transaction limit (approximately 1 MB), a TransactionTooLargeException is thrown during state restoration. The app crashes, and the same oversized state is re-persisted, causing a crash on every subsequent launch.

Type: Persistent Denial of Service (DoS)
Class: Resource Exhaustion / State Persistence Boundary
CWE: CWE-400 — Uncontrolled Resource Consumption; CWE-770 — Allocation of Resources Without Limits
CVSS v3.1 estimated: 7.1 (High)
Vector: AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H


2. Attack chain

The observed chain can be represented as:

Attacker crafts deep link
       ↓
https://www.threads.net/search?q=[OVERSIZED_PAYLOAD]
       ↓
User clicks the link
       ↓
Threads opens and handles the deep link
       ↓
Search query stored in Fragment arguments
       ↓
Fragment state saved as SavedState
       ↓
Bundle serialization (FragmentManager)
       ↓
Bundle size exceeds Binder limit
       ↓
TransactionTooLargeException
       ↓
Threads crashes
       ↓
State re-persisted to disk
       ↓
Threads crashes on every launch attempt
       ↓
PERSISTENT CRASH LOOP
       ↓
Recovery: clear app data or uninstall/reinstall

The fundamental characteristic of STA-012 is that the payload is delivered through a standard deep link that the app is designed to handle. The user does nothing unusual — just clicks a link that appears legitimate.


3. Technical details

3.1. Deep link structure

The crafted deep link targets Threads' search functionality:

https://www.threads.net/search?q=[PAYLOAD]

The q parameter contains the oversized payload, which is accepted by the app and stored in Fragment arguments as part of the navigation state.

3.2. State amplification

The payload is amplified through the same mechanism documented in STA-005 (WhatsApp):

Input (payload in deep link)
       ↓
Fragment arguments (SavedState)
       ↓
Bundle serialization
       ↓
Nested fragments add metadata overhead
       ↓
Total Bundle size exceeds Binder limit
       ↓
TransactionTooLargeException

From the structural amplification paper, observed Bundle component sizes in similar Class A vectors:

androidx.lifecycle.BundlableSavedStateRegistry.key: 1,661,088 bytes
android:support:fragments: 1,645,336 bytes
childFragmentManager: 1,636,412 bytes
childFragmentManager: 1,614,072 bytes
childFragmentManager: 1,603,852 bytes
registryState: 479,948 bytes
search_query: 80,484 bytes  ← input data

Key observation: The search query (80,484 bytes) is amplified to a total Bundle size of 1.66 MB — exceeding the Binder limit by 58%.

3.3. Amplification factor

Based on the observed Bundle sizes, the amplification factor for the search_query component is:

Input: 80,484 bytes
Total Bundle: 1,661,088 bytes
Amplification factor: ×20.6

This is consistent with the amplification factor observed in STA-005 (WhatsApp).


4. Stack trace

The following stack trace was captured during a Threads crash caused by an oversized deep link payload. The excerpt is abbreviated; irrelevant frames and build-specific details have been omitted.

android.os.TransactionTooLargeException: data parcel size 1661088 bytes
    at android.os.BinderProxy.transactNative(Native Method)
    at android.os.BinderProxy.transact(BinderProxy.java)
    at android.app.ActivityManagerProxy.activityStopped(ActivityManagerProxy.java)
    at android.app.ActivityThread.handleStopActivity(ActivityThread.java)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java)
    at android.os.Handler.dispatchMessage(Handler.java)
    at android.os.Looper.loop(Looper.java)
    at android.app.ActivityThread.main(ActivityThread.java)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java)

Key metric: Parcel size 1,661,088 bytes — exceeds the Binder transaction limit (1,048,576 bytes) by approximately 58%.


5. Variants

STA-012e — Threads via WhatsApp

An attacker can deliver the payload through a WhatsApp message containing a WebView or HTML that triggers the Threads deep link:

WhatsApp message
       ↓
User clicks link/HTML
       ↓
WebView opens
       ↓
Redirect to Threads deep link
       ↓
https://www.threads.net/search?q=[PAYLOAD]
       ↓
Threads opens → crash loop

This expands the attack surface, as the payload can be delivered through messaging platforms rather than requiring direct navigation to a web page.


6. Persistence

Persistence: YES

The contaminated state is written to disk. The crash loop persists across:

  • App restarts
  • Device reboots
  • App updates (if the state is preserved)

Recovery requires:

  • Clearing the app data (via adb pm clear com.threads or app settings)
  • Uninstalling and reinstalling the app (loses all data)

7. Affected components

Primary

  • androidx.fragment.app.FragmentManager — state restoration
  • androidx.lifecycle.SavedStateRegistry — state persistence
  • androidx.navigation.NavController — navigation state
  • android.os.Bundle — serialization container
  • android.os.Parcel — Binder serialization

Secondary

  • android.app.ActivityThread — lifecycle handling
  • android.app.ActivityManagerProxy — Binder transaction

8. Vendor status

Vendor Status
Meta (Threads) ❌ Reported in March 2026 — no response as of August 2026
Google (Android VRP) ✅ A-477279924 — $250 reward, open triage
Google (AndroidX) ✅ savedstate 1.5.0 (May 2026) decouples SavedState from Binder — but does not fix FragmentManager or apps using older patterns

Note: Updating to androidx.savedstate 1.5.0 does not protect against STA-012. Threads must update their own state handling, and FragmentManager.restoreAllState() itself remains unpatched.


9. Why this matters

STA-012 is not just a crash. It is a permanent denial of service with significant implications:

  • For individual users: They lose access to the app until they clear data, losing all conversations and settings
  • For the platform: This is a single point of failure in the state restoration mechanism
  • For Meta: A single malicious link can make Threads unusable for any user who clicks it

The vector is particularly concerning because:

  • The payload is delivered through a standard deep link that the app is designed to handle
  • No special permissions are required
  • The user does nothing unusual — just clicks a link
  • The impact is persistent and requires clearing data to recover

10. Relationship to other STA vectors

Vector Relationship
STA-005 Same mechanism (text input → SavedState → Bundle → Binder → crash loop). WhatsApp has a similar amplification factor (×20.6).
STA-015-DL Same amplification mechanism, escalated to SystemUI via TaskPersister.
STA-022 Same mechanism (DuckDuckGo Fragment args → Parcel → Binder).
STA-028 UTF-16 encoding amplification is a contributing factor to the measured ×20.6 amplification.

11. Recommended mitigation

11.1. Application-level (Threads)

  • Validate the size of deep link parameters before storing them in Fragment arguments
  • Truncate search queries to a safe limit (e.g., 8 KB)
  • Catch TransactionTooLargeException in state restoration and fall back to clean start
// Recommended approach for deep link handling
Uri data = getIntent().getData();
String query = data.getQueryParameter("q");
if (query != null && query.length() > MAX_SAFE_QUERY_LENGTH) {
    query = query.substring(0, MAX_SAFE_QUERY_LENGTH);
    Log.w(TAG, "Search query truncated to safe length");
}

11.2. Framework-level (Android)

  • FragmentManager.restoreAllState() should catch TransactionTooLargeException and discard oversized state
  • Bundle should provide a size estimation method before serialization
  • AndroidX Navigation should validate argument sizes before persisting state

12. Research status

Field Value
Vector STA-012
First formal communication 20 January 2026
Researcher Manuel Garc铆a Pe帽a (Lostmon)
Nature Independent research
Platform Android
Impact Persistent DoS
Interaction required Yes (one click)
Privileges None
Tier A (Confirmed — full stack trace + exception)

STA-012 is part of the broader Structured Text Amplification (STA) research, which studies a recurring pattern of resource exhaustion produced when input data crosses serialization, transformation, IPC, or persistence boundaries without sufficiently early resource limits.


13. Conclusion

STA-012 demonstrates how a standard deep link can become a persistent denial-of-service vector when the app fails to validate the size of input parameters before storing them in SavedState.

The amplification factor (×20.6) is consistent with other Class A vectors, confirming that the problem is architectural rather than specific to a single app:

Deep link payload
 → Fragment arguments
 → SavedState
 → Bundle
 → Parcel
 → Binder
 → TransactionTooLargeException
 → Persistent crash loop

The most robust mitigation is to validate input size before storing it in state, complemented by fallback mechanisms that prevent an oversize condition from becoming a persistent crash loop.


Complete whitepaper: Resilience Gaps in Android IPC, SavedState and Text Layout — v6 (August 2026)


馃搶 About this series
This post is part of a series documenting the 32 vectors of Structured Text Amplification (STA).

Published:
STA-017 — Cross-Engine ANR
STA-015-DL — Google Drive → SystemUI

STA-006 / 007 Translate: When translating text crashes Google Apps

STA-006 / 007 Translate: When translating text crashes Google Apps

Structured Text Amplification — Vectors 006 & 007

This post documents STA-006 and STA-007, two denial-of-service vectors in Google's Translate feature. An oversized text payload, when selected and sent to Translate via Intent.ACTION_TRANSLATE, can exceed the Binder transaction limit, causing a TransactionTooLargeException and a permanent crash loop in some cases.

⚠️ Severity: STA-006 and STA-007 are persistent DoS vectors in some oems implementations. A single oversized text selection can make Google App or Google Drive permanently unusable until the user clears app data. No special permissions or privileges are required.


1. Overview

STA-006 and STA-007 describe a persistent denial-of-service condition in Google's Translate feature, accessible from multiple Google apps. An attacker can craft or deliver an oversized text payload that, when selected and translated, contaminates the app's state and causes a permanent crash loop in oems.

The vector is triggered when the user selects a large text (visible or hidden) and invokes the Translate action. The app constructs an Intent.ACTION_TRANSLATE containing the selected text. During serialization of the Intent for transfer via Binder, the data size may exceed the Binder transaction limit (approximately 1 MiB). This can result in an unhandled TransactionTooLargeException, causing an immediate app crash.

Type: semi-persistent Denial of Service (DoS)
Class: Resource Exhaustion / State Persistence Boundary
CWE: CWE-400 — Uncontrolled Resource Consumption; CWE-770 — Allocation of Resources Without Limits
CVSS v3.1 estimated: 6.5 (Medium-High)
Vector: AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H


2. Attack chain

The observed chain can be represented as:

Attacker crafts/places oversized text payload
       ↓
User selects the text (or selects all in a PDF)
       ↓
User invokes Translate action (context menu or app button)
       ↓
Google App / Google Drive constructs ACTION_TRANSLATE Intent
       ↓
Selected text stored in Intent extra (EXTRA_TEXT)
       ↓
Intent serialization (Parcel)
       ↓
Parcel size exceeds Binder limit (1 MB)
       ↓
TransactionTooLargeException
       ↓
App crashes immediately
       ↓
State may be re-persisted (in Google Drive)
       ↓
App crashes on every launch attempt (persistent crash loop)
       ↓
Recovery: clear app data or uninstall/reinstall

The fundamental characteristic of STA-006/007 is that the STA payload is delivered through a standard user action (Translate) that the app is designed to handle. The user does nothing unusual — just selects text and translates it.


3. Vector details

3.1. STA-006 — Google App (Select text → Translate)

The vector is triggered through the Google App's selection menu:

  • The user selects a large text (e.g., from a web page, document, or any text field).
  • The user taps the "Translate" action from the context menu.
  • Google App creates an ACTION_TRANSLATE Intent with the selected text as EXTRA_TEXT.
  • During serialization of the Intent, the Bundle size exceeds the Binder transaction limit.
  • TransactionTooLargeException is thrown and not caught.
  • Google App crashes immediately.

Entry point: android.app.Activity.startActivityForResult()Instrumentation.execStartActivity() → Binder transaction → TransactionTooLargeException

3.2. STA-007 — Google Drive (PDF → Select All → Translate)

The vector is triggered through Google Drive's PDF viewer:

  • User opens a PDF containing invisible or oversized text (e.g., a PDF with a large hidden payload).
  • User selects all text (Select All) in the PDF viewer.
  • User taps the "Translate" action from the selection menu.
  • Google Drive creates an ACTION_TRANSLATE Intent with the selected text.
  • During serialization of the Intent, the Bundle size exceeds the Binder transaction limit.
  • TransactionTooLargeException is thrown and not caught.
  • Google Drive crashes immediately.
  • If the state is re-persisted, the app enters a permanent crash loop.

Entry point: PDF viewer selection menu → Intent.ACTION_TRANSLATE → Binder transaction → TransactionTooLargeException


4. Stack trace and Bundle analysis

The following stack trace and Bundle statistics were captured from a production device (Xiaomi Redmi Note 14 5G, HyperOS 3.0, Android 16) during a crash of the Google App. The crash occurred after selecting an oversized text payload, invoking Translate, and subsequently focusing the search bar, which triggered the state serialization and Binder transaction.

4.1. Exception

java.lang.RuntimeException: android.os.TransactionTooLargeException:
data parcel size 2454260 bytes
    at android.app.servertransaction.PendingTransactionActions$StopInfo.run(PendingTransactionActions.java:146)
    at android.os.Handler.handleCallback(Handler.java:1029)
    at android.os.Handler.dispatchMessage(Handler.java:107)
    at android.os.Looper.loopOnce(Looper.java:274)
    at android.os.Looper.loop(Looper.java:369)
    at android.app.ActivityThread.main(ActivityThread.java:10090)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:616)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1137)
Caused by:
android.os.TransactionTooLargeException:
data parcel size 2454260 bytes
    at android.os.BinderProxy.transactNative(Native Method)
    at android.os.BinderProxy.transact(BinderProxy.java:736)
    at android.app.IActivityClientController$Stub$Proxy.activityStopped(IActivityClientController.java:1546)
    at android.app.ActivityClient.activityStopped(ActivityClient.java:106)
    at android.app.servertransaction.PendingTransactionActions$StopInfo.run(PendingTransactionActions.java:135)

4.2. Bundle statistics

The Bundle that triggered the exception contained the following components:

Bundle stats:
    androidx.lifecycle.BundlableSavedStateRegistry.key [size=2452080]
    androidx.lifecycle.internal.SavedStateHandlesProvider [size=1127400]
    tt_activity_account_retained:6 [size=1125236]
    SearchSession:1 [size=1125012]
    androidx.lifecycle.BundlableSavedStateRegistry.key [size=1124884]
    androidx.lifecycle.internal.SavedStateHandlesProvider [size=1124752]
    androidx.lifecycle.ViewModelProvider.DefaultKey:... [size=1124452]
    BrowserSession:2 [size=963088]
    androidx.lifecycle.BundlableSavedStateRegistry.key [size=962960]
    androidx.lifecycle.internal.SavedStateHandlesProvider [size=962828]
    webx_browser [size=962464]
    webx_window [size=962416]
    web_view_url [size=962288]
    search_query_key [size=161080]
    search_query [size=161028]
    protoparsers [size=160976]
    android:support:fragments [size=1312836]
    fragment_e32da9b3... [size=1312412]
    arguments [size=161152]
    TIKTOK_FRAGMENT_ARGUMENT [size=161008]
    childFragmentManager [size=1312836]
    android-support-nav:controller:backStack [size=326252]
    registryState [size=168492]
    SEARCH_QUERY_STATE [size=160976]
    ... (additional nested fragment states)

4.4. Key metrics

Component Size
Input (search_query) ~161,028 bytes
childFragmentManager 1,312,836 bytes
SavedStateHandlesProvider 1,127,400 bytes
SearchSession / BrowserSession ~1,125,000 bytes each
Total Bundle size 2,454,260 bytes
Binder transaction limit 1,048,576 bytes
Excess +1,405,684 bytes (+134%)
Amplification factor ×15.2

Key observation: The input payload (~161 KB) is amplified to a total Bundle size of 2.45 MB through the serialization of nested Fragment states, SavedState handles, and session data. The amplification factor of ×15.2 is consistent with the amplification patterns documented in other Class A vectors (STA-005, ×20.6; STA-012, ×20.6).


5. Affected components

Primary

  • android.content.IntentACTION_TRANSLATE intent extra serialization
  • android.os.Bundle — serialization container
  • android.os.Parcel — Binder serialization
  • android.app.ActivityThread — lifecycle handling
  • androidx.fragment.app.FragmentManager — fragment state serialization
  • androidx.lifecycle.SavedStateHandlesProvider — SavedState management

Secondary

  • android.app.ActivityManagerProxy — Binder transaction
  • Google App (com.google.android.googlequicksearchbox) — Translate feature
  • Google Drive (com.google.android.apps.docs) — PDF viewer + Translate feature

6. Persistence

Persistence: YES (STA-007), Conditional (STA-006)

  • STA-006 (Google App): The app may crash immediately, but the state is not always re-persisted. Recovery typically involves reopening the app.
  • STA-007 (Google Drive): The PDF viewer state is saved, and the oversized payload may be re-persisted, causing a crash on every launch.

Recovery typically requires:

  • Clearing the app data (via adb pm clear com.google.android.googlequicksearchbox or adb pm clear com.google.android.apps.docs)
  • Uninstalling and reinstalling the app (loses all data)

7. Why this matters

STA-006 and STA-007 are not just crashes. They are semi-persistent denial-of-service vectors with significant implications:

  • For individual users: They lose access to the app until they clear data, losing all settings and potentially documents.
  • For Google: A single malicious document can make Google Drive unusable for any user who opens it and attempts to translate.
  • For the platform: This is a single point of failure in the Intent serialization and Binder transaction mechanism.

The vector is particularly concerning because:

  • The payload can be delivered through a standard PDF document that the app is designed to handle.
  • No special permissions are required.
  • The user does nothing unusual — just selects text and translates it.
  • The impact is persistent in some OEMS and requires clearing data to recover.

8. Relationship to other STA vectors

Vector Relationship
STA-003 Same mechanism (Share Intent → Binder → TransactionTooLargeException)
STA-005 Same mechanism (text input → SavedState → Bundle → Binder → crash loop). WhatsApp has a similar amplification factor (×20.6).
STA-012 Same mechanism (deep link → Fragment args → SavedState → Binder → crash loop)
STA-028 UTF-16 encoding amplification is a contributing factor to the measured amplification.

9. Chromium commit evidence

Chromium commit 84b615a0 (5 May 2026) added the Translate action to the Android PDF viewer's selection menu, confirming that this surface is considered relevant and that Google engineers have been working on it. The commit introduced:

84b615a07fc14988b46f0e362502ab4075216793
Author: Ryan Thomas
Date: 5 May 2026
Component: Android PDF viewer selection menu
Changes: Added Share, Web Search, Translate actions to selection menu

This demonstrates that the surface identified by STA-006/007 is being actively developed and modified, further validating the architectural relevance of the findings.


10. Recommended mitigation

10.1. Application-level (Google App / Google Drive)

  • Validate the size of selected text before constructing the ACTION_TRANSLATE Intent.
  • Truncate text to a safe limit (e.g., 8 KB) before placing it in EXTRA_TEXT.
  • Catch TransactionTooLargeException and fall back to a clean state.
// Recommended approach for Translate action
String selectedText = getSelectedText();
if (selectedText != null && selectedText.length() > MAX_SAFE_LENGTH) {
    selectedText = selectedText.substring(0, MAX_SAFE_LENGTH);
    Log.w(TAG, "Selected text truncated to safe length");
}
Intent translateIntent = new Intent(Intent.ACTION_TRANSLATE);
translateIntent.putExtra(Intent.EXTRA_TEXT, selectedText);
try {
    startActivity(translateIntent);
} catch (TransactionTooLargeException e) {
    Log.e(TAG, "Translate Intent too large", e);
    // Fallback: show error dialog or use alternative translation method
}

10.2. Framework-level (Android)

  • Intent serialization should include a size estimation before Binder transaction.
  • SystemUI should catch TransactionTooLargeException and handle it gracefully.
  • FragmentManager should limit the size of saved state before serialization.

11. Research status

Field Value
Vectors STA-006, STA-007
First formal communication 20 January 2026
Researcher Manuel Garc铆a Pe帽a (Lostmon)
Nature Independent research
Platform Android
Impact Persistent DoS
Interaction required Yes (one click / selection)
Privileges None
Tier A (Confirmed — full stack trace + exception)

STA-006/007 are part of the broader Structured Text Amplification (STA) research, which studies a recurring pattern of resource exhaustion produced when input data crosses serialization, transformation, IPC, or persistence boundaries without sufficiently early resource limits.


12. Conclusion

STA-006 and STA-007 demonstrate how a standard Translate action can become a persistent denial-of-service vector when the app fails to validate the size of selected text before constructing an Intent.

The amplification mechanism is consistent with other Class A vectors, confirming that the problem is architectural rather than specific to a single app:

Selected text (~161 KB)
 → Intent (ACTION_TRANSLATE)
 → FragmentManager serialization
 → SavedStateHandlesProvider
 → Bundle (2.45 MB)
 → Parcel
 → Binder
 → TransactionTooLargeException
 → Persistent crash loop

The most robust mitigation is to validate input size before constructing the Intent, complemented by fallback mechanisms that prevent an oversize condition from becoming a persistent crash loop.


Complete whitepaper: Resilience Gaps in Android IPC, SavedState and Text Layout — v6 (August 2026)


馃搶 About this series
This post is part of a series documenting the 32 vectors of Structured Text Amplification (STA).

Published:
STA-017 — Cross-Engine ANR
STA-015-DL — Google Drive → SystemUI
STA-005 — WhatsApp
STA-003 — Binder Share Intent
STA-006/007 — Translate (this post)

Coming next:
⬜ STA-012 — Threads
⬜ STA-019 — Firefox
⬜ STA-022 — DuckDuckGo

Whitepaper: Resilience Gaps in Android IPC, SavedState and Text Layout — v6


Lostmon · lostmon.blogspot.com

 

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