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

 

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