pen testing apisapi securitysupabase securityfirebase securitymobile app security

Advanced Pen Testing APIs: Supabase & Firebase

Learn modern pen testing apis in Supabase and Firebase. This guide covers reconnaissance, auth testing, RLS fuzzing, remediation, and CI/CD integration.

Published April 16, 2026 · Updated April 16, 2026

Advanced Pen Testing APIs: Supabase & Firebase

You ship a mobile feature on Friday. The app talks to Supabase or Firebase. Auth works, the UI looks clean, and your QA pass says nothing obvious is broken.

Two weeks later, someone changes an ID in a request, calls an RPC directly, or pulls a key from the app bundle and reaches data they should never see.

That pattern is common in modern stacks because BaaS convenience changes where security breaks. You aren’t only defending a neat REST API behind a custom backend any more. You’re defending generated endpoints, row policies, edge functions, callable functions, mobile clients, cached tokens, and release pipelines that move faster than most manual reviews.

Generic guidance on pen testing apis usually stops at the OWASP list. That’s useful, but it doesn’t help much when the actual bug lives in a permissive RLS policy, a public RPC, or a Firebase rule that looked right in review and still leaks under a slightly different request path.

Why Your Modern App Needs API Pen Testing Now

A lot of teams still assume Supabase and Firebase are “secure enough” if they use the built-in auth and avoid putting obviously sensitive logic in the client. That assumption breaks fast.

The usual failure mode isn’t dramatic engineering negligence. It’s normal product work. A team adds a new table, exposes a helper function, relaxes a policy for testing, or leaves an old endpoint reachable because removing it might break the app. The release goes out. Nobody notices the gap because the app behaves correctly for normal users.

Secure by default is not the same as secure in practice

BaaS platforms remove a lot of boilerplate. They do not remove the need to test authorisation decisions in the running system.

Supabase makes it easy to expose data through PostgREST and database functions. Firebase makes it easy to wire mobile clients directly into backend services. That speed is useful, but it also means security mistakes become production behaviour very quickly.

What breaks most often is not cryptography. It’s access control logic.

A user should only read their own rows.
A support agent should only update certain fields.
A mobile app should call one function through an intended path, not invoke another one directly.

Those rules are easy to describe in a ticket. They’re harder to prove under hostile input.

The cost of “we’ll test later”

The UK context makes this hard to ignore. A 2024 British Airways API exposure incident risked 400,000 customer records due to broken object level authorisation, and API incidents average £3.8M per breach, with effective API pen testing reducing breach costs by 40% through early detection of issues such as RLS misconfigurations and unprotected RPCs, according to Omdia’s 2025 penetration testing market analysis.

That matters even if you’re a small team.

A smaller product may not make national news, but the mechanics are the same. You still face customer churn, incident handling, emergency engineering work, app store fallout, and awkward questions from clients or auditors.

Practical rule: if your mobile app can talk to your backend, an attacker can too. Pen testing starts from that assumption.

Where modern app teams get caught

The teams most exposed are often the fastest ones:

  • Mobile-first startups: The app bundle reveals endpoints, environment details, and sometimes more than it should.
  • Indie hackers: Shipping alone means security review is usually “I’ll revisit this after launch”.
  • Product-led SaaS teams: Feature flags, rapid schema changes, and helper functions create drift between intended and actual access.

Pen testing apis in these environments isn’t a luxury exercise. It’s the discipline of proving what a hostile client can do, not what the code review said should happen.

Laying the Groundwork Your Reconnaissance Phase

A bad API pen test starts with the swagger file and ends there.

A useful one starts by assuming your documentation is incomplete.

A flowchart titled API Pen Testing Reconnaissance Blueprint illustrating six sequential steps for professional security testing.

Start with the inventory you have

Build a target map from what the team already knows:

  1. OpenAPI or Swagger specs
  2. Postman collections
  3. Client-side API wrappers
  4. Mobile network traces
  5. Edge or cloud function lists
  6. Auth flows and token types

This gives you the documented attack surface. It does not give you the actual one.

A structured methodology for pen testing apis begins with API inventory creation because initial inventories miss up to 40% of undocumented APIs, and leftover debug endpoints appear in 35% of professional engagements, as described in Nyx Sentinel’s API pentesting methodology.

Then find what nobody wrote down

Shadow and zombie APIs cause more trouble than teams expect.

In Supabase environments, these often show up as old RPCs, experimental edge functions, and table exposures that remained reachable after a frontend refactor. In Firebase environments, the equivalent is often callable functions, old routes behind API gateways, or stale rules that still permit reads after the app moved on.

Use multiple angles:

  • Frontend bundle review: Search built JavaScript for endpoint paths, project identifiers, function names, and auth assumptions.
  • APK and IPA analysis: Pull strings, config files, and network metadata from the mobile binary.
  • Traffic capture: Run the app through Burp Suite or Proxyman and observe every request path, header, and error response.
  • Version guessing: If you see /v1/, test for adjacent versions and alternate paths.
  • Function enumeration: Review public function names and infer likely helper endpoints from naming conventions.

One of the fastest ways to miss real risk is to test only what engineering intended to publish.

Documentation tells you how the product is meant to work. Recon tells you what is actually reachable.

Recon in Supabase and Firebase looks different

Traditional API recon often assumes a bespoke backend with a small set of routes. BaaS changes that.

With Supabase, map:

  • Generated REST access to tables and views
  • RPC functions
  • Storage-related endpoints
  • Auth flows and JWT handling
  • Edge functions
  • Any frontend logic that assumes RLS is the only gate

With Firebase, map:

  • Callable and HTTP Cloud Functions
  • Firestore or Realtime Database access patterns
  • Client-enforced role checks
  • Storage rules
  • Third-party services called from the mobile app

The mistake I see often is treating these as “platform features” instead of attack surface. They’re both.

Build a recon sheet before active testing

A simple spreadsheet still works well. Track:

| Asset | How discovered | Auth required | Suspected risk | |---|---|---:|---| | Public endpoint or function | Docs, bundle, traffic, binary | None or token | Data exposure, abuse | | RPC or callable function | Schema, app trace | User token | BOLA, mass assignment | | Storage path | App trace, code search | User token or public | Unauthorised file access | | Deprecated route | Error leaks, versioning | Varies | Forgotten auth logic |

This sounds basic. It prevents shallow testing.

If you want a practical companion for the API-specific checks teams usually overlook during recon, this guide on API security testing is a useful reference point.

What good recon produces

By the end of recon, you should know:

  • Which endpoints are documented
  • Which ones are only discoverable from the app
  • Which functions are callable directly
  • Where tokens originate and how they travel
  • Which routes depend on RLS, rules, or backend checks
  • Which old assets are still alive

If you can’t answer those, you aren’t ready to test thoroughly. You’re still testing the brochure.

Testing Authentication and Authorisation Flaws

A common mobile incident looks like this. Login works, tokens refresh, and the app passes QA. Then a tester changes one document ID, one storage path, or one RPC argument and starts pulling another customer’s data.

That is the real auth test in a Supabase or Firebase app. The question is not whether a user can sign in. The question is whether every request after sign-in is tied to the right identity, role, tenant, row, and object.

A hand-drawn illustration depicting API authentication bypass with a broken lock, key, and denied access wall.

Test auth as a chain of trust

Start with the token, then follow where trust moves.

In modern stacks, identity often passes through several layers. A mobile app gets a JWT, calls an edge function or API route, which then calls Supabase PostgREST, a custom RPC, Firebase rules, or a Cloud Function. Any layer that trusts client-controlled claims, stale sessions, or weak role mapping can break the whole chain.

Check these points first:

  • JWT handling: expired tokens, altered claims, weak audience checks, and services that trust role or tenant fields from the client without server-side verification
  • Session state: logout, password reset, account suspension, MFA changes, and whether old refresh tokens still work
  • Privilege transitions: what happens after role changes, org switches, or account deletion
  • Mobile token storage: tokens in SharedPreferences, Keychain, AsyncStorage, local SQLite, logs, or crash reports
  • Guest and anonymous flows: pre-auth endpoints, upgrade paths, and callable functions that stay reachable after account creation

Mobile binaries also expose a lot during testing. API keys, project IDs, storage buckets, and service endpoints are often enough to map the backend and start direct request replay. That does not always mean full compromise, but it regularly shortens the path to one. Solid secrets management best practices help reduce what ends up in the app package and what your CI system injects into builds.

Start authorisation testing with ownership

Broken Object Level Authorisation remains the highest-yield test because BaaS platforms make object access easy to ship and easy to get wrong.

Use at least two normal user accounts and, if possible, one privileged account. Capture a request from User A, then replay it with changed identifiers:

  • user IDs
  • organisation IDs
  • record UUIDs
  • chat thread IDs
  • file paths
  • invoice or subscription IDs

Do not stop at obvious REST paths. In Supabase and Firebase apps, the more interesting targets are often hidden inside JSON bodies, RPC arguments, Firestore document paths, or storage object names.

A fast example:

  1. User A loads a profile or order history screen.
  2. The app requests /rest/v1/orders?id=eq.<uuid> or calls an RPC with account_id.
  3. You replace the identifier with User B’s value.
  4. The API returns data because it checked whether the token was valid, not whether the record belonged to that user.

That failure shows up in mature products too. The backend often assumes the client already selected the right object.

Supabase testing needs row-level and function-level checks

Supabase changes the shape of auth testing because access control is often split between Row Level Security policies, storage policies, and Postgres functions.

That creates two separate questions:

  1. Can this user reach the endpoint, RPC, or table at all?
  2. Once they can, what rows or files can they read, insert, update, or delete?

Teams usually test the first question and miss the second.

A policy can look correct in SQL and still fail in practice. Common patterns include auth.uid() = user_id on select but no matching with check on insert, policies that protect direct table access but forget a helper RPC, and security definer functions that return more than the caller should ever see. AppOmni's research on security risks in low-code and no-code platforms is a useful reference here because it shows how platform abstractions and exposed backend operations widen access in ways teams do not always model during review.

What a real Supabase auth test looks like

Read the policies. Then attack the behavior.

Use separate test users with different tenants, ownership, and roles. Exercise each table, view, bucket, and RPC with changed inputs. Focus on cases where the client sends ownership fields or where a function accepts identifiers that should have been derived server-side.

High-yield checks include:

Read leakage

Query broad filters, guessed UUIDs, joins, and relation paths. Watch for partial leaks such as row counts, foreign key metadata, filenames, or status fields. Full-row exposure is not the only failure mode.

Write leakage

Try inserting records with another user’s user_id, updating rows you do not own, or changing a tenant field during an otherwise valid update. Missing with check clauses cause a lot of damage here.

RPC abuse

Call every exposed function directly. If an RPC takes user_id, team_id, email, role, or a storage path as an argument, treat it as hostile input. Functions should derive identity from auth.uid() and enforce scope inside the database.

Storage policy bypass

Request predictable file paths, change folder names, and test signed URL generation. Buckets often inherit weaker rules than the tables that reference them.

A useful rule during review is simple. If the client supplies the subject of the action, the server or database must verify it independently.

Firebase has different primitives, but the same failure modes

Firebase moves these checks into Authentication, Security Rules, Firestore document paths, Storage Rules, and callable Cloud Functions. The exploit pattern stays the same.

Test whether a user can:

  • read another user’s document by changing the path
  • write ownership fields the rules later trust
  • call a privileged Cloud Function with a normal token
  • perform admin-style actions after manipulating custom claims or stale session state
  • access Storage objects through guessed paths or predictable naming

Rules deserve direct testing, not just code review. Replay requests outside the app, because mobile UI checks create a false sense of safety. If the only restriction exists in the client, there is no restriction.

Teams tightening mobile identity flows should keep this guide to Firebase authentication security nearby during review, especially for custom claims, token refresh behavior, and callable function validation.

What tools miss

Burp Suite, Postman, mitmproxy, and scripted replay save time. They help with tampering, diffing, and coverage.

They do not understand your tenancy model, your support roles, your RLS assumptions, or the fact that one RPC was meant to be called only after a completed payment step. That part still needs a human tester who understands how Supabase policies, Firebase rules, mobile clients, and product workflows fit together.

The practical goal is simple. Prove that every sensitive action is authorised at the backend layer that executes it, not in the screen that triggered it.

Uncovering Business Logic and Injection Vulnerabilities

Once you’ve proved who can access what, the next question is uglier.

What can a valid user do that product never intended?

That’s the territory of business logic flaws, and they’re common in modern APIs because BaaS platforms make it easy to expose useful backend operations quickly. The danger is that useful operations often become abusable operations.

A conceptual drawing of a four-step data pipeline interrupted by a human hand labeled as a logic flaw.

Business logic flaws start where validation ends

Input validation can be perfect and the workflow can still be insecure.

A few examples that show up often:

  • applying a discount after an order is locked
  • reusing a one-time referral benefit
  • cancelling after fulfilment but keeping the credit
  • calling a support-only function from a normal user token
  • invoking an RPC out of sequence because the UI, not the backend, enforced the expected steps

These flaws don’t look like classic “malicious payload” attacks. They look like ordinary product actions performed in the wrong order, by the wrong user, or more often than intended.

Test the workflow, not just the fields

A practical way to approach this is to write down the intended sequence for a sensitive action. Then break it.

Take a subscription upgrade flow. Ask:

  1. Can the final confirmation endpoint be called first?
  2. Can a user replay a completion request?
  3. Can they modify a price-related parameter after server calculation?
  4. Does the backend trust state that only the client should know?
  5. Can they race two requests and keep both outcomes?

That testing style matters in Supabase and Firebase because many teams place important business rules in client code, edge functions, callable functions, or thin wrappers over database operations.

A secure API doesn’t just reject invalid syntax. It rejects valid-looking requests with invalid intent.

RPCs and Cloud Functions deserve hostile input

Supabase RPCs and Firebase Cloud Functions often carry more risk than standard CRUD endpoints because they encapsulate business actions. Teams treat them as internal helpers. Attackers treat them as public capabilities.

Start by identifying every function that:

  • changes money, credits, or quotas
  • modifies user roles or account states
  • returns aggregated or joined data
  • performs admin-like actions
  • reaches external services
  • accepts free-form input or arrays of IDs

Then fuzz both structure and meaning.

Useful fuzzing angles

  • Send fields with the right type but wrong semantics
  • Duplicate parameters with conflicting values
  • Pass arrays where the UI sends one value
  • Omit fields the frontend always includes
  • Supply ownership or role fields manually
  • Use edge-case strings in search, filter, or sort inputs

Common API Injection Vectors and Testing Tools

| Vulnerability Type | Example Payload | Primary Testing Tool | |---|---|---| | SQL injection | ' OR '1'='1 | Burp Suite, SQLmap | | NoSQL injection | {"$ne": null} | Burp Suite | | Command injection | test; id | Burp Suite | | Mass assignment style parameter abuse | {"role":"admin"} | Burp Suite Param Miner, manual replay |

The payloads above are starting points, not guarantees. The point is to provoke backend behaviour and observe how the API validates, transforms, and trusts input.

Supabase-specific failure patterns

Supabase RPCs deserve extra scrutiny when they’re used to “safely” wrap privileged logic.

A few recurring issues:

Functions trust caller-supplied identifiers

The function accepts user_id, team_id, or account_id as a parameter and uses it directly. If ownership isn’t derived from the authenticated context, you likely have an authorisation flaw hiding inside a business function.

Functions expose joined data

The function returns more columns than the UI needs. That often produces excessive data exposure, especially when joins pull in internal notes, flags, or metadata.

Security assumptions move from policy to function

Teams sometimes relax table access because “all writes go through the RPC”. Then the RPC itself lacks strict checks or can be called in ways the frontend never does.

Firebase-specific failure patterns

In Firebase stacks, look closely at callable functions that:

  • trust custom claims without revalidating context
  • process purchase or entitlement changes
  • write to multiple documents based on client-supplied paths
  • rely on front-end hidden fields to determine role or state

NoSQL-style injection concerns also show up indirectly when backends construct dynamic queries or trust complex filter objects from the client. Even when the underlying platform is managed, your function code can still make dangerous trust decisions.

A simple manual method that works

Use three passes instead of one.

| Pass | Focus | What you’re looking for | |---|---|---| | Happy path | Normal app use | Baseline requests and expected states | | Tamper pass | Request edits and replay | Missing validation, trust in client data | | Sequence abuse | Reorder, repeat, race | Logic flaws, duplicate effects, stale state |

This is slower than scanning everything automatically. It finds problems scanners routinely miss.

What to record in your notes

For each suspicious endpoint or function, capture:

  • Preconditions: logged-in role, object state, account type
  • Exact request change: which field, header, path, or order changed
  • Observed result: data leak, status inconsistency, privilege shift, side effect
  • Why it matters: financial, privacy, role abuse, data integrity

That last line matters. Engineering teams fix issues faster when the finding explains the broken business rule, not just the malformed request.

Automating Security with CI/CD Integration

Point-in-time testing still matters. It just isn’t enough for fast-moving BaaS apps.

If your schema, policies, functions, and mobile builds change every week, a single manual test gives you a dated snapshot. It tells you what was true on test day. It doesn’t tell you what shipped after the next merge.

A diagram illustrating an automated security loop process involving static code scanning, API testing, and post-deployment checks.

Continuous testing fits modern API change rates

A lot of small teams fall behind. They know they need security testing, but they still treat it like a quarterly event.

That approach leaves obvious gaps. In UK small businesses, API-related incidents rose 22% year over year, yet only 12% conduct continuous security testing, which highlights the gap between rapid development and point-in-time assurance, according to Wiz’s API pen testing guidance.

For Supabase and Firebase teams, drift happens quickly:

  • a new RPC is added without a proper check
  • a policy change fixes one query and opens another path
  • a mobile release introduces a leaked key or hardcoded secret
  • an edge function goes public because deployment defaults changed

None of those waits politely for the next annual pen test.

What belongs in the pipeline

You don’t need to automate every manual technique. You do need to automate the checks that catch regressions early.

A practical CI/CD setup should include:

On pull request

  • Schema and policy review: flag dangerous RLS changes, permissive rules, and public object access
  • Function diff checks: identify newly exposed RPCs, callable functions, and auth bypass conditions
  • Secret scanning: inspect frontend code, mobile artefacts, and config for embedded credentials
  • Basic API replay tests: confirm sensitive routes still reject unauthorised access

On merge or staging deploy

  • Authenticated regression tests: run known-good and known-bad requests against a staging environment
  • RLS leakage probes: verify that read and write boundaries still hold across test accounts
  • Mobile binary inspection: extract strings and config to catch endpoint and key exposure introduced by the build

Post-deployment

  • External validation: ensure production behaviour matches expected auth and authorisation boundaries
  • Alerting on changes: trigger reviews when routes, functions, or policies change outside normal patterns

The best API security automation doesn’t replace manual testing. It protects manual findings from being reintroduced a week later.

What works and what doesn’t

What works:

  • small, deterministic checks tied to specific security assumptions
  • failing builds on dangerous policy changes
  • replaying previously exploited requests as regression tests
  • scanning the actual mobile artefact, not just the source tree

What doesn’t:

  • running a generic DAST tool and assuming coverage is complete
  • scanning only public web routes while ignoring mobile and BaaS surfaces
  • producing reports nobody owns
  • passing builds with “informational” findings that are exploitable

If you’re adding this discipline to an existing release process, this guide to automated pen testing is a sensible starting point.

A workable operating model

Use manual pen testing for depth. Use automation for continuity.

That split is practical:

| Testing mode | Best use | |---|---| | Manual assessment | BOLA, business logic, nuanced RLS and function abuse | | Automated pipeline checks | Regressions, newly exposed assets, secrets, policy drift | | Scheduled deep validation | Major releases, architecture changes, sensitive new features |

That’s how pen testing apis becomes part of engineering instead of a separate ceremony you scramble for before launch.

From Findings to Fixes A Practical Remediation Guide

Findings only matter if the fix is clear.

The fastest way to lose momentum after a good pen test is to hand developers a vague statement like “RLS is misconfigured” or “authorisation is insufficient”. Teams need to know what to change, where to change it, and what to retest after the patch.

Finding one unauthorised row reads in Supabase

Problem

A user can read rows belonging to another user because the policy allows any authenticated session to select from the table.

Weak pattern

create policy "authenticated users can read profiles"
on profiles
for select
to authenticated
using (true);

Safer pattern

create policy "users can read own profile"
on profiles
for select
to authenticated
using (auth.uid() = user_id);

If the product requires broader access, encode the role logic explicitly. Don’t rely on the client to hide records it already received.

Retest

  • read your own row
  • read another user’s row by direct ID
  • read through a broad filter
  • read through any RPC or joined view that touches the same table

Finding two unauthorised writes through an ownership field

Problem

The API accepts a payload with user_id and writes the row as supplied. A normal user can create or update records on behalf of someone else.

Weak pattern

create policy "users can insert orders"
on orders
for insert
to authenticated
with check (true);

Safer pattern

create policy "users can insert own orders"
on orders
for insert
to authenticated
with check (auth.uid() = user_id);

For updates, pair using and with check carefully so a user can’t target one row and rewrite ownership on save.

Finding three public or over-trusting RPCs

Problem

A helper function accepts a target_user_id parameter and returns account data for whichever ID the caller supplies.

Weak pattern

create or replace function get_account_summary(target_user_id uuid)
returns table (user_id uuid, plan text, credit_balance numeric)
language sql
as $$
  select user_id, plan, credit_balance
  from accounts
  where user_id = target_user_id;
$$;

Safer pattern

create or replace function get_account_summary()
returns table (user_id uuid, plan text, credit_balance numeric)
language sql
as $$
  select user_id, plan, credit_balance
  from accounts
  where user_id = auth.uid();
$$;

The fix is usually the same: derive identity from the authenticated context, not from user-controlled input.

Remediation rule: every time a function accepts an identifier tied to ownership or privilege, ask whether that parameter should exist at all.

Finding four Firebase callable function trusts the client

Problem

A callable function updates a role or entitlement based on a field sent by the mobile app.

Weak pattern

exports.updateUserRole = onCall(async (request) => {
  const { uid, role } = request.data;
  await admin.firestore().collection("users").doc(uid).update({ role });
});

Safer pattern

exports.updateUserRole = onCall(async (request) => {
  if (!request.auth || request.auth.token.admin !== true) {
    throw new Error("permission-denied");
  }

  const { uid, role } = request.data;
  const allowedRoles = ["member", "manager"];
  if (!allowedRoles.includes(role)) {
    throw new Error("invalid-argument");
  }

  await admin.firestore().collection("users").doc(uid).update({ role });
});

The backend must enforce both who can do the action and which values are allowed.

Turn fixes into regression tests

Don’t close the issue when the patch merges. Close it when the exploit fails.

A solid remediation loop includes:

  • Proof of failure: the original attack no longer works
  • Neighbour checks: similar endpoints, rules, or functions were reviewed
  • Pipeline coverage: the issue becomes an automated regression test where possible
  • Developer note: the root cause is documented in team-friendly language

That last part matters for culture. Teams improve faster when findings become reusable engineering lessons.

A good pen test doesn’t end with a PDF. It leaves behind stronger policies, safer functions, and a release process that’s harder to break the same way twice.


If you’re building on Supabase, Firebase, or shipping mobile apps that connect directly to backend services, AuditYour.App gives you a fast way to check what’s exposed. You can scan a project URL, website, or APK/IPA for RLS leaks, public RPCs, leaked keys, and hardcoded secrets, then use the remediation output to fix issues before they reach users.

Scan your app for this vulnerability

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

Run Free Scan
Advanced Pen Testing APIs: Supabase & Firebase | AuditYourApp