Home›Insights›Scans vs. Compose state
Gap-First Mobile AppSec

Why your 2024 automated scan is 5 years behind your Jetpack Compose app

Automated crawlers struggle with reactive state machines. Modern Compose apps need state-aware testing, or a clean scan report becomes false confidence.

Fireland Labs · 25 October 2026

What automated scans are good at

Let’s be fair first. Automated scanning earns its place. It is fast, repeatable, and cheap to run on every build.

It is good at known-pattern issues: outdated dependencies, weak transport configuration, missing hardening flags, obvious misconfigurations. If you are not running it, start. Nothing in this article argues against it.

The problem is not the tool class. It is what we assume a clean report tells us.

The shift: from pages to state

Many scanning approaches were designed around a simple model: an application is a set of pages or endpoints, and a crawler can discover them by following links and submitting inputs.

Jetpack Compose apps do not work that way. The UI is a function of state. What the user sees, and what the app allows, depends on who is signed in, what has loaded, what was selected a moment ago, and what the last response said.

In a typical Compose app, a screen is less a destination and more a rendering of the current state. Navigation is often state too. Some states only exist after a specific sequence, with specific timing and specific data.

A crawler that explores screens will see the screens it can reach. It has no reason to know the ones it cannot.

A synthetic example

Synthetic scenario. It describes a concept, not a real product, and it deliberately leaves out how anything would be triggered.

Imagine a subscription app with a premium feature gated by a state holder. The gate is checked when the screen is first shown. A later state transition, say a plan change followed by a retry after a failed request, leaves the feature visible while the backing check is no longer enforced.

Nothing here is exotic. Each step is normal product behavior. The weakness lives in the combination, and the combination only occurs in one ordered path through the state model.

A page-by-page scan can visit every screen in that app and report nothing. The state that matters was never presented to it.

Why this matters

These are the typical failure modes: logic mistakes, authorization checks that live in the UI layer instead of being enforced consistently, and error paths that nobody exercised. They tend to surface in exactly the flows that carry trust: payments, account changes, personal data.

The business consequences are rarely dramatic on day one. They are quieter:

  • Deal friction. A buyer’s security review asks how the app was tested, and “we run an automated scan” invites follow-up questions.

  • Trust and churn. Users do not read scan reports. They notice when access or data behaves in ways they did not expect.

  • Roadmap risk. Findings that arrive late, near a launch or a diligence process, get fixed under pressure and push other work out.

None of this means the scan was wrong. It means the scan answered a narrower question than the one a founder or CTO is asking. “Is the app free of known patterns?” and “Can the product be misused through its own logic?” are different questions, and only the first one is easy to automate.

A clean scan is useful information. It is not evidence of coverage for state-dependent flows.

Impact box

Pending review. The impact model for this article has not been reviewed or approved. The structure below is a placeholder, and it contains no figures on purpose.

Illustrative model, not a prediction. Content to follow.

  • Customer impact (mechanisms): qualitative only, for example trust loss, churn, support load. Pending review.

  • Investor impact (mechanisms): qualitative only, for example deal friction, timeline risk, gating fixes. Pending review.

  • Regulatory impact (high level): applicable frameworks and risk category to be confirmed. Not legal advice, and not a compliance certification.

  • Assumptions: to be listed.

What good testing looks like

State-aware testing starts from how the app actually behaves, not from a list of screens. At a high level, that means three things.

  • Map flows and states. Identify the journeys that matter and the states they pass through, including the unusual ones.

  • Trace data through state holders. Follow sensitive data and decisions from the source, through ViewModels and state, to what is rendered and what is enforced.

  • Test gating and error paths. Check that route and feature gating hold across transitions, retries, failures and restores, and that enforcement does not depend on the UI alone.

For fixes, the same lens applies. Enforce decisions where the data lives, not only where the screen renders, and keep state models small enough that you can reason about every transition.

Automated tooling still helps with the known-pattern layer. The state-dependent layer needs someone who understands the architecture and can reason about it.

What to ask a vendor

Three questions help separate shallow testing from the real thing. A fourth helps with what you receive at the end.

  • How do you cover state-dependent flows in Compose?

  • Do you model user journeys and state transitions, or only crawl screens?

  • What evidence do you provide for logic and authorization findings?

  • How do you label what was tested, what was assumed, and what was out of scope?

Good answers are specific and mention flows, roles and evidence. Vague answers about “full coverage” are worth a follow-up.

Where to start

If you want a fast, high-signal view, start with the Security Health Check. It focuses on the few flows that matter most before your next milestone and gives your team a prioritized plan to ship and verify.

Have a question about your product? Leave your email and we’ll get in touch within 1–2 business days.

Privacy

Prefer email? hello@firelandlabs.com

❌🕸️