mobile application securityapp security testingfirebase securitysupabase rlsowasp mobile

Mobile Application Security Testing: A Complete Guide 2026

A complete guide to mobile application security testing. Learn modern methodologies, CI/CD integration, and how to fix Supabase and Firebase vulnerabilities.

Published July 1, 2026 · Updated July 1, 2026

Mobile Application Security Testing: A Complete Guide 2026

Over 70% of mobile applications contain at least one major security vulnerability, according to DigitalXRAID's mobile app pen testing overview. That figure should change how teams think about release readiness. A green build, a clean UI, and a smooth onboarding flow don't say much about whether your app leaks tokens, trusts the wrong backend response, or exposes data through a weak access rule.

Modern mobile application security testing has also changed shape. A lot of risk no longer sits only inside the APK or IPA. It sits in the services glued to the app: Supabase policies, Firebase rules, cloud functions, public RPCs, bundled keys, and auth flows that look sound in the client but fail under direct API access. Small teams feel this most because they move quickly, use managed backends, and often don't have a dedicated security engineer to challenge assumptions before launch.

The good news is that good testing isn't reserved for large enterprises. If you treat security testing as part code review, part runtime validation, and part backend policy verification, you can catch the issues that turn into incidents. Teams that want a practical baseline for securing mobile applications effectively should start by focusing on the paths attackers use in real apps, not just on compliance wording.

Why Mobile App Security Testing Matters Now More Than Ever

A large share of mobile risk now lives outside the binary. It lives in BaaS configuration, auth claims, row access policies, callable functions, and API paths the client happens to use today but an attacker can call directly tomorrow.

That changes what mobile application security testing needs to cover.

Mobile apps now handle identity, payments, health data, location, messaging, and access to internal systems. For teams shipping on Supabase or Firebase, the security boundary is rarely the screen or even the app package. It is the combination of client code, tokens, backend rules, RPCs, cloud functions, and the assumptions those pieces make about each other. Teams that care about securing mobile applications effectively need to test that full path, not just the app container.

A common mistake is treating mobile security as a client-only problem. Teams often spend time on local storage, TLS pinning, jailbreak checks, and obfuscation, then give far less attention to the backend authorization layer that decides who can read or modify data. In real incidents, I see the same pattern repeatedly. The mobile app behaves correctly in the UI, but a direct request to a Supabase REST endpoint, an unprotected Postgres RPC, or a permissive Firebase rule bypasses that intent completely.

Release speed makes this worse because trust boundaries drift unnoticed. A new feature can add a broader query, a new claim, a debug route in a cloud function, or a service role path that was safe in staging and dangerous in production. None of that looks dramatic in a sprint review.

The useful question is simple. What can an attacker do without the app?

That is why modern testing has to validate backend behavior with the same discipline applied to the client. For a Supabase-backed app, that means checking row level security against real user roles, testing whether RPCs enforce auth internally instead of assuming the client did it, and verifying that storage buckets, edge functions, and generated APIs reject unauthorized access. For Firebase, it means testing Firestore and Storage rules with crafted identities, confirming callable functions do their own authorization checks, and reviewing custom claims flows for privilege mistakes. Teams building for Apple platforms should also pair that with platform-specific validation such as iOS app security testing practices, because transport, keychain, entitlements, and runtime protections still matter.

Traditional mobile pentesting guides often stop too early for this stack. They are good at binary analysis, interception, local storage checks, and rooted or jailbroken device scenarios. Those checks still belong in the plan. They just do not answer whether tenant isolation holds under direct API access, whether an exposed function can be replayed outside the app, or whether a policy change inadvertently turned private data into public data.

Good testing gives product teams something concrete. Proof that the controls they rely on still hold after each release, and fast feedback when they do not.

The Core Methodologies of Mobile Security Testing

An infographic titled Core Mobile Security Testing Methodologies, detailing SAST, DAST, IAST, and MAST security testing techniques.

Teams that rely on a single testing method usually get a false sense of coverage. Mobile apps fail in layers. The client can be clean while a backend policy is wide open, or the API can look locked down while secrets leak from the app bundle.

Security testing terms also get blurred together. In practice, they answer different questions, and modern mobile stacks need all of them.

What each method is good at

For mobile teams shipping on Supabase, Firebase, or a similar BaaS stack, the main job is coverage across trust boundaries. SAST helps catch issues in code before they ship. DAST checks how a running build and its connected services behave under real requests. IAST adds runtime context while flows execute. Manual penetration testing fills the gaps where business logic, auth design, and backend policy interactions matter more than signatures.

| Method | Best at finding | Weak spots | Best time to use | |---|---|---|---| | SAST | Hardcoded secrets, unsafe API usage, insecure crypto choices, obvious insecure code paths | Runtime flaws, weak server-side authorization, RLS and security rule mistakes that only appear with real identities | During coding and on pull requests | | DAST | Insecure responses, auth flow weaknesses, exposed endpoints, misconfigured API behavior | Hidden code paths, dead code, chained business logic abuse, some mobile-only runtime conditions | In CI, staging, and release validation | | IAST | Vulnerabilities with execution context, including which code path produced the issue | Added tooling overhead, coverage limited to exercised flows, weaker fit for smaller teams without strong test automation | Useful in mature pipelines | | Manual penetration testing | Tenant isolation failures, insecure direct object reference paths, replayable function calls, broken assumptions between app and backend | Slower, depends on tester depth, not continuous by itself | Before release, after major auth or data model changes, and for sensitive apps |

What works in practice

MAST is not one tool category. It is the working combination of static analysis, runtime testing, platform checks, and manual validation against the backend your app depends on.

That distinction matters with BaaS-backed apps. A scanner may flag a token in local storage or a missing certificate pinning control. Useful findings, but incomplete. It will not reliably tell you whether a Supabase RPC trusts the client too much, whether row level security holds for another tenant's record ID, or whether a Firebase callable function enforces admin claims on the server instead of trusting UI state.

A practical testing stack usually looks like this:

  • Use SAST early for low-cost wins. Catch embedded keys, unsafe deserialization, weak crypto calls, debug flags, and insecure logging before review.
  • Run DAST against real builds and real test identities. Exercise login, token refresh, offline sync, deep links, and error handling. Send requests outside the mobile client too.
  • Add backend policy tests. For Supabase, validate RLS, Storage policies, Edge Functions, and RPC authorization with multiple roles. For Firebase, test Firestore rules, Storage rules, callable functions, and custom claims transitions.
  • Reserve manual testing for high-value paths. Payments, account recovery, role changes, invite flows, shared objects, and tenant boundaries still need human judgment.

I usually tell teams to treat the mobile app as one attack surface and the mobile-backed service as another. The biggest misses happen in the gap between them.

A good example is a clean React Native or Swift client talking to Supabase. SAST can confirm the app is not shipping obvious secrets. DAST can verify that login and token handling behave correctly. Manual testing is what proves whether an authenticated user can call an RPC directly and read or modify data outside their role because the SQL function never checked auth.uid() or role claims internally.

The same pattern shows up in Firebase. Firestore rules may look correct in review, while a callable Cloud Function inadvertently accepts a document ID from any authenticated user and performs a privileged write. Traditional mobile pentesting guides often spend far more time on the APK or IPA than on these backend trust failures. That is a mistake for modern app teams.

For iOS-heavy teams, binary inspection, entitlements, storage validation, and runtime tampering checks still belong in the plan. This guide to iOS app security testing is a useful companion for the platform-specific side of the work.

External testing still has a place, especially when the team needs an independent view before release or after a major architecture change. If you want a reference point for how service-led assessments are commonly framed, this Saskatchewan penetration testing guide is a useful example.

The trade-off most teams underestimate

Automation finds repeatable defects fast. Humans prove impact and catch broken assumptions.

Small teams do not need a heavyweight program to get value from this. They need a repeatable mix: static checks on every pull request, dynamic tests on staging builds, backend authorization tests tied to schema or rule changes, and focused manual validation where trust boundaries can fail. That gives much better coverage than treating mobile security as a once-a-year binary review.

A Practical Mobile App Security Testing Checklist

The most useful checklist isn't a giant compliance spreadsheet. It's a list of things attackers can abuse. For mobile apps, that means you need to test both the client and the connected services behind it.

A checklist infographic outlining seven essential security testing practices for mobile application development and protection.

UK expert standards described by Duke University require an approved mobile application vulnerability assessment for every in-scope application, using a hybrid process that combines static and dynamic analysis with manual penetration testing, with testing cadence tied to major version releases. That hybrid model is the right mental model for this checklist too.

Client-side checks that still matter

Start with the mobile artefact itself. You're looking for what an attacker can learn from the app package and what they can change at runtime.

  • Secure storage: Check whether tokens, refresh tokens, user identifiers, and cached records are stored in Keychain, Keystore, or equivalent protected storage. Verify that sensitive material isn't left in logs, preferences, SQLite files, or temp storage.
  • Secrets in the bundle: Search APK and IPA contents for API keys, service role keys, signing material, private endpoints, and debug flags. Public configuration is common. Privileged secrets should never be in a distributable app.
  • Transport controls: Confirm TLS is enforced correctly and validate how the app behaves under interception. If certificate pinning exists, test the failure path too. Broken fallback logic is common.
  • Platform misuse: Review exported activities, deep links, pasteboard use, backup settings, web views, and permission handling. Many defects here look harmless until another app or a malicious user chains them.

Backend-connected checks teams often skip

Supabase and Firebase apps frequently encounter issues because the app may look polished while the backend trusts requests it shouldn't.

A solid review should include:

  1. Authorisation at the data layer
    Verify that policies or rules enforce per-user or per-tenant access. Don't trust the app to send the right filter.

  2. Function exposure
    Test RPCs, edge functions, and cloud functions directly. If the mobile app can call them, an attacker can usually call them without the app.

  3. Input trust
    Check whether backend logic trusts client-supplied user IDs, tenant IDs, role names, or pricing fields.

  4. Error handling
    Review responses for stack traces, policy hints, table names, or overly descriptive errors that help an attacker map the system.

What to verify for BaaS platforms

Use a targeted pass for managed backends:

  • Supabase: Review Row Level Security policies, direct table access, storage bucket policies, and SECURITY DEFINER functions.
  • Firebase: Inspect Firestore rules, Storage rules, callable function auth checks, and assumptions tied to custom claims.
  • Shared concern: Make sure analytics, crash reporting, and third-party SDKs aren't improperly collecting sensitive values that should never leave the device.

Field note: The fastest way to miss a serious issue is to test only through the app UI. Policies often fail when requests are replayed directly.

Cadence matters more than teams admit

A checklist isn't useful if it only appears before launch. The highest-value moments are when the app changes shape: a new auth flow, a major version release, a refactor of data access, or a switch to a new backend function. That's when old assumptions break.

Finding What Scanners Miss Evidence-Driven Validation

A finding without evidence often becomes a low-priority ticket. A finding with proof becomes work that gets scheduled today. That's the core value of evidence-driven validation.

The difference is simple. “Possible insecure access” is abstract. “User B can read User A's invoice records by changing one identifier in a direct API call” is concrete. Developers can reproduce it, product can understand the impact, and leadership can prioritise the fix.

Fuzzing backend logic, not just inputs

Traditional fuzzing is often described as throwing unexpected input at a target. That still matters, but modern mobile stacks need a more specific form of it. For Supabase and Firebase, the interesting question usually isn't whether a field accepts malformed JSON. It's whether rule logic leaks records when claims, paths, filters, or nested conditions vary in edge cases.

For example, you might test a query under these conditions:

  • Missing auth context
  • Valid auth token with the wrong tenant
  • A token with stale role information
  • An RPC call that omits one field the UI normally sends
  • A storage request that swaps object paths but keeps the same session

That kind of testing often finds what a general scanner won't. If you're building a workflow around automated discovery first, then validation second, this guide to mobile app vulnerability scanning is a useful companion to manual verification.

Why proof-of-exploit changes remediation speed

A proof-of-exploit doesn't need to be dramatic. It just needs to show real impact safely. In practice, that usually means demonstrating one of these outcomes:

| Validation type | What it proves | |---|---| | Unauthorised read | Data exposure is real, not theoretical | | Unauthorised write | Integrity can be broken | | Privilege bypass | Auth logic depends on the client | | Secret reuse | A leaked key or token changes actual system access |

If you can't show what an attacker gains, the issue often gets debated instead of fixed.

What not to do

Teams sometimes stop at static flags like “suspicious policy” or “potentially exposed endpoint”. Those are good leads, not finished findings. Evidence-driven work means confirming whether the condition is exploitable in your environment.

That discipline cuts noise. It also prevents over-fixing. Not every permissive-looking rule is exploitable. Not every leaked key is high impact. Validate first, then rank the problem.

Automating Security in Your CI/CD Pipeline

If security testing only happens before release, it turns into a negotiation. Engineers are under deadline pressure, findings arrive late, and nobody wants to reopen code that already passed QA. CI/CD fixes that by moving security checks closer to the change that introduced the problem.

The goal isn't to automate everything. The goal is to automate the repeatable parts so humans can focus on judgement. Pull requests should trigger the cheap, fast checks. Release candidates should trigger deeper scans. Major releases should trigger manual review where risk is concentrated.

Screenshot from https://audityour.app

A practical pipeline shape

For GitHub Actions, GitLab CI, or similar systems, a sensible setup looks like this:

  • On pull request: Run SAST, secret scanning, dependency checks, and configuration linting.
  • On merge to main: Build the app, scan the APK or IPA, and run backend-focused tests against a staging environment.
  • On release candidate: Exercise authentication paths, direct API access, function exposure, and policy validation.
  • On major version release: Add manual penetration testing and deeper business logic review.

This pattern works well because each stage answers a different question. Early checks ask whether the change introduced obvious risk. Release-stage checks ask whether the built app and connected backend still behave securely as a system.

Build gates that teams can live with

The most effective gating rules are clear and limited. If every medium-severity issue blocks a deploy, developers will disable the gate or flood the backlog with exceptions. Start tighter.

Use gates such as:

  1. Fail on hardcoded secrets and privileged keys
  2. Fail on known critical configuration issues
  3. Require review for auth, policy, or function changes
  4. Generate a report for lower-severity findings without blocking

Operational rule: Block releases for problems that create immediate unauthorised access. Report the rest and track them visibly.

If you're designing a broader delivery workflow around this, an auto devops pipeline perspective can help frame where security jobs fit without making the pipeline unwieldy. For a more focused view on integrating these checks into build systems, this piece on CI/CD security testing maps well to mobile release workflows.

What automation should actually test for mobile apps

A useful automated job for mobile application security testing should inspect more than source code. It should be able to work from:

  • Repository URL
  • Built APK
  • Built IPA
  • Connected backend behaviour
  • Public artefacts such as app store bundles or web assets linked to the app

That matters for small teams because they often don't have time to recreate a full manual review every sprint. Automation gives them regression detection. If a safe policy becomes unsafe after a schema update, or if a new build suddenly ships with an exposed key, the pipeline should catch that before users do.

Remediation Examples for Supabase and Firebase

The hardest part of security work usually isn't finding the issue. It's fixing it without breaking the app. Backend-as-a-service platforms make that trade-off more visible because a small policy shortcut can keep development moving, then create a large exposure later.

Iterasec reports that 42% of mobile app breaches in 2025 originated from exposed Row Level Security rules and leaked API keys in frontend bundles, and notes that these issues are rarely caught by traditional pentests. That tracks with what many mobile teams run into in Supabase and Firebase projects.

A hand points at insecure code on a laptop screen, contrasted with fixed, secure database rules.

Supabase example with weak Row Level Security

A common early-stage policy looks like this:

create policy "users can read projects"
on projects
for select
using (true);

It works. It also means every authenticated user may be able to read every row, depending on table exposure and role setup. Teams often add this to unblock frontend development and forget to tighten it.

A safer multi-tenant version usually ties access to the authenticated user or tenant relationship:

create policy "users can read own tenant projects"
on projects
for select
using (
  tenant_id in (
    select tenant_id
    from memberships
    where user_id = auth.uid()
  )
);

The important shift isn't just the SQL syntax. It's the trust model. The first policy trusts any caller who made it past auth. The second policy validates row access against server-side membership data.

What to verify after the fix

  • Direct table reads: Try querying as another signed-in user.
  • Nested joins: Make sure related tables don't reintroduce leakage.
  • Write paths: Check insert, update, and delete policies separately.
  • Storage access: If files map to the same tenant model, align those rules too.

Supabase example with exposed RPC behaviour

Another pattern shows up in database functions. A function may be callable by roles that should never reach it directly, or it may trust caller-provided identifiers.

Insecure idea:

create function update_plan(target_user uuid, new_plan text)
returns void
language plpgsql
as $$
begin
  update profiles
  set plan = new_plan
  where id = target_user;
end;
$$;

If the function is exposed and permissioned loosely, a caller may update another user's record.

Safer direction:

create function update_my_plan(new_plan text)
returns void
language plpgsql
security invoker
as $$
begin
  update profiles
  set plan = new_plan
  where id = auth.uid();
end;
$$;

This version removes the client-controlled target user and ties the update to the authenticated caller. In some cases, changing a plan should be admin-only. Then the function should verify role claims or live entirely behind a server-side trusted path instead of being callable from the app.

Don't accept user IDs from the client when the backend can derive identity itself.

Firebase example with permissive rules

Firestore rules often start broad during prototyping:

match /projects/{projectId} {
  allow read, write: if request.auth != null;
}

That checks authentication, not authorisation. Any signed-in user may now access any project document that path reaches.

A better rule ties access to ownership or membership stored in the document or a related path:

match /projects/{projectId} {
  allow read, write: if request.auth != null
    && request.auth.uid in resource.data.memberIds;
}

That still needs careful review. If memberIds is user-controlled, a write path might let someone add themselves. Secure rules depend on secure update conditions too.

Firebase Functions example with missing auth checks

A callable function can look safe because the app only shows it to logged-in users. But if the function itself doesn't verify auth, the UI isn't protecting anything.

Insecure pattern:

exports.deleteAccountData = onCall(async (request) => {
  const userId = request.data.userId;
  // delete records for userId
});

Safer pattern:

exports.deleteMyAccountData = onCall(async (request) => {
  if (!request.auth) {
    throw new Error("unauthenticated");
  }

  const userId = request.auth.uid;
  // delete records for userId
});

The rule is consistent across platforms. If the server can derive identity, derive it there. Don't let the client tell you who it is acting for.

From Testing to Tenacity Building a Security Culture

The strongest mobile teams don't treat security as a final gate staffed by someone else. They treat it as part of how software gets built. That means developers understand where trust boundaries sit, reviewers ask whether the backend verifies what the UI assumes, and release pipelines test the artefacts that users install.

Security culture doesn't start with slogans. It starts with habits.

Habits that make teams safer

  • Developers check data paths, not just screens: Every new feature that touches backend data gets an access review.
  • Reviewers challenge trust assumptions: If code passes a user ID, role, or tenant ID from the client, someone asks whether the backend should derive it instead.
  • Pipelines catch regressions: Scans run on builds and connected services, not only on repositories.
  • Manual testing focuses on impact: Humans spend time on auth, business logic, and policy failures that automation can't fully reason about.

What this changes for small teams

Indie hackers and startup teams often assume they need a large security budget to be serious about mobile application security testing. They don't. They need a repeatable system. Start with static checks and bundle inspection. Add runtime testing for release candidates. Validate backend rules and exposed functions directly. Then revisit the risky paths whenever the app changes in meaningful ways.

Secure mobile delivery isn't about shipping slower. It's about removing the unknowns that turn a routine release into an incident response call.

The biggest shift is mindset. Security testing isn't a one-off task before launch. It's continuous evidence that your app, your backend, and your release process still deserve user trust.


If you're shipping a mobile app on Supabase, Firebase, or a similar stack, AuditYour.App can help you catch exposed RLS rules, unprotected RPCs, leaked API keys, and hardcoded secrets before they become production problems. Paste a project URL, upload an APK or IPA, or run a one-off snapshot to get actionable findings and remediation guidance without a heavy setup process.

Scan your app for this vulnerability

AuditYourApp automatically detects security misconfigurations in Supabase and Firebase projects. Get actionable remediation in minutes.

Run Free Scan