Skip to main content
ZombieMutex

30 results · ↑ ↓ navigate · Enter open · Esc close

All topics

Engineering topic / Jeffrey Monica

Mobile authentication and security boundaries

A device verdict isn't a user session, and a user session isn't permission to touch every object. This collection is about keeping those boundaries separate.

Key engineering considerations

Attacker control

Assume the caller can modify the client and network request. Name which checks are enforceable server-side.

Evidence binding

Bind signed evidence to a fresh challenge, intended action, and expected application context.

Recovery and revocation

Require independent step-up on dangerous paths and propagate revocation consistently.

iOS App Attest / Android Play Integrity / API authorization

Mobile attestation is not authorization.

A legitimate app instance can still send a request that the signed-in user must not be allowed to make. The server needs to verify the app evidence, bind it to the relevant operation, and independently enforce tenant and object permissions. That is the trust boundary I focus on when reviewing mobile auth.

Apple App Attest

Register an attested public key after verifying Apple's certificate chain and the expected app identity. For sensitive operations, verify an assertion over server-bound client data, including a fresh challenge and a monotonically increasing counter. Keep key associations and production/development environments distinct.

Apple's server validation guidance ↗

Android Play Integrity

Request an integrity verdict for a relevant action, decode it through the backend, and inspect request details, app recognition, signing identity and the selected integrity signals. For standard requests, compare requestHash against a stable digest of the operation. Use a risk policy rather than assuming the verdict automatically authorizes the user.

Android's standard-request guidance ↗

Server-side decision sequence

  1. 01

    Authenticate the user

    Establish the session principal and intended tenant. A device verdict is not a login.

  2. 02

    Validate platform evidence

    Verify the iOS assertion or Android Play Integrity token on the server, including app identity and freshness.

  3. 03

    Bind the requested action

    Compare the attested challenge or request hash against the exact operation and immutable request fields.

  4. 04

    Authorize the object

    Check whether this principal may perform this action on this tenant-owned resource, independent of device trust.

  5. 05

    Commit and record

    Apply idempotency or atomic-update controls. Capture safe decision metadata without logging token contents.

Illustrative server authorization order (pseudocode)

const principal = await requireSession(request);
const evidence = await validatePlatformEvidence(request);

assertBoundToAction(evidence, request.action, request.body);
await authorizeObject(principal, request.tenantId, request.objectId);

return commitOnce(request.idempotencyKey, request.action);

Negative-test checklist

Run these cases against a controlled test backend, not a production account. Each scenario needs a precise expected denial, an observable reason code and a regression test.

Attack or failureExpected backend behavior
Reused challenge or assertionReject stale proof and enforce server-side freshness or counter policy.
Integrity token for another requestReject a requestHash or challenge that does not bind to the current action.
Valid device, wrong tenantDeny object access; device integrity does not grant object permissions.
Expired or revoked user sessionDeny even if platform integrity proof is valid.
Unexpected app identifier or signerReject evidence that does not match the configured application identity.
Concurrent duplicate mutationPreserve authorization and idempotency under simultaneous requests.
Unavailable device-integrity serviceUse an explicit risk policy and safe fallback; never silently grant privileges.

Field guides and review checklists

Articles and reference guides

Mobile voice agents: keep the backend in chargeHow I connected Swift and Kotlin clients to agent workflows, built Core ML and TensorFlow Lite integration boundaries, and kept authorization on the backend.Voice agents are distributed systems with microphonesBuilding an agent that talks is the easy demo. The harder work is authenticated tools, retries, evaluation, telemetry, CRM synchronization and the people who have to operate it.AEAD design review: ciphertext still needs an identity and contextAn encrypted database value can be perfectly unreadable to an attacker and still end up in the wrong record. If a service moves ciphertext between tenants without binding the record's context, the system may deStuxnet: malware crossed from Windows into industrial controlI traced Stuxnet as a boundary-crossing problem: from Windows software into industrial control commands. Calling it sophisticated Windows malware misses the physical-system risk. The attack path targeted software used to supervise and program industAndroid toll fraud: when the app can intercept consentThe trust failure I examined in Android toll-fraud reporting is the confirmation step: an OTP does not protect a purchase if malicious software on the same device can intercept or submit it. Microsoft documented Android toll-fraud workflows in which malware tried to subscribe victimTriada: the Android firmware supply-chain backdoorTriada challenges an app-centric mobile threat model in an important way. Google's Android security team described a malware family that moved from rooting attempts into compromised system images. The malicious codRefresh-token rotation under concurrent replay: 200 scheduled callersI sent 200 scheduled refresh attempts through one local token family. Only one issued a successor; multiple workers would need a different test.Reproducing a one-time challenge replay race with 200 contendersI tried consuming one action-bound challenge 200 times. My single-process guard accepted one call and rejected 199; shared-store races remain untested.Android Play Integrity request binding and backend verdict policyWhat requestHash protects, what the server must verify, and why an integrity verdict is not a substitute for authorization.Authentication telemetry without leaking tokens or recovery secretsDesign privacy-conscious auth decision logs that help explain failures without recording the credentials that caused them.Device integrity is not authorization: an App Attest and Play Integrity decision modelA valid App Attest or Play Integrity result cannot authorize a user. I walk through the server decisions separately and test them with synthetic inputs.Object-level API authorization: why a valid JWT is not enoughPractical tests for broken object-level authorization in authenticated mobile and backend APIs.Mobile session recovery as an explicit state machineModel sign-in, refresh rotation, expiry, step-up recovery, and revocation without creating a hidden authentication bypass.Hardening iOS Device Trust Signals Against Hostile ClientsA practical look at building and evaluating device trust signals under jailbreaks, instrumentation, replay, and tampered clients, with emphasis on server-side verification and failure-aware design.

Related case studies