Mobile app fraud: emulators, clones and tampering, and what you can detect.
Mobile app fraud prevention with native SDKs: detect emulators, rooted and jailbroken devices, cloned apps and tampering, with server-verified attestation.

Mobile app fraud prevention starts from an uncomfortable fact: your app runs on a device the attacker controls, so anything it reports can be forged. The answer is to have the app report raw observations, let your server make every decision, and use hardware-backed attestation to raise the cost of lying.
This playbook sets out what Fingerly’s native iOS and Android SDKs and server genuinely detect, how attestation fits in, and where the honest limits are.
What can fraudsters do to a mobile app?
They change the environment so one operator looks like many customers, or so a modified client passes your checks. The common moves are running the app in emulators, provisioning racks of phones, cloning the app so several copies run side by side, rooting or jailbreaking a device, attaching hooking tools, intercepting the app’s encrypted traffic, and repackaging the app itself.
These are rarely the goal. They are how an operator gets past the checks you already have, to farm sign-up bonuses, redeem rewards, create fake accounts or move money from a compromised phone.
What do the native SDKs detect?
The native SDKs report raw observations, and the server derives the findings and scores them with your weights. Here is what is reported today, by platform.
- Android: an emulator or virtualised Android, a cloned app running in a cloning framework, a rooted device, instrumentation attached to the app, intercepted traffic, a failed integrity check on the app, a debugger or test runner attached, and a device that looks provisioned for bulk use.
- iOS: the iOS Simulator, a jailbroken device including rootless jailbreaks, instrumentation attached to the app, intercepted traffic, a failed integrity check, developer tooling attached, and a device that looks provisioned for bulk use.
- Network, on both: VPNs including tunnels over mobile data, proxies, Tor exits and a location that disagrees with the address.
- Across devices, on the server: many alike devices behind one network, compared with your own traffic after a learning period of seven days.
How does attestation prove the app is genuine?
Attestation lets the device’s security hardware vouch for your app, and the server checks the proof itself. A modified app can forge everything else in a report, which is why attestation is the evidence that matters most.
- Android 7.0 (API 24) and newer: the SDK gets a one-time challenge from Fingerly and has the hardware-backed keystore attest to it. The server verifies the result, and a failed check raises the tampering signal. It works without configuration and without extra services on the device; listing your package names and signing certificates on the key also makes the server check that the attestation names your app.
- iOS 14 and newer, on a real device: App Attest. It is optional, needs the App Attest capability on your app target and your iOS app ID on your public key. The first report from an install attests a new key, and every later one signs an assertion with it. A failed check raises the tampering signal.
Every native event records one attestation state: attested, not attested, or failed, so “not proven” is never confused with “not checked”. A key that names an app can also require attestation, refusing reports that do not prove themselves. Turn that on only once every device you need to serve can attest.
Why must your server make the decision?
Because the app can be patched to report anything. The SDK holds no weight, threshold or rule, and the app is never told which signals fired. It receives a score and level as a convenience, which can adapt the interface but should not be used for security decisions.
The decision belongs to your backend. Send the request ID with the action, read the stored event with a secret key, check that it is for this action and recent, and decide there. If the score is absent, never read it as clean: it is absent when a request was not scored and when your key hides it.
Where in the app should you identify?
- Onboarding and signup, to catch emulators, device farms and fake accounts before benefits are granted.
- Login, where compromised and emulated devices attempt takeovers.
- Reward redemption, where cloned apps and instrumented devices farm incentives.
- Transfers, new payees and payments, where instrumentation or interception during the action is worth stopping for, whatever the rest of the session says.
Use the native SDKs for iOS and Android, or the React Native, Flutter and Lynx bridges, which call the same native code. Consent defaults to pending, which collects nothing until your consent tool grants it, and the SDKs never show a permission prompt.
How do you avoid penalising legitimate users and developers?
Weight these signals as evidence, and be honest about their limits. Attestation raises the cost of forging a report, but it does not make forgery impossible, and a device that offers no proof is not proven guilty. Hiding tools exist, so evidence that is hard to fake carries the most weight.
- Developers and testers use emulators every day. Use development and staging keys for your own testing; requests made with them are free.
- A debug build installed from a laptop, or an unlocked bootloader, is not enough on its own to report tampering or root.
- Managed work profiles are a normal Android setup and are not reported as cloned apps. Phones rented in a datacentre are real hardware and are caught by the device-farm side instead.
- Families share phones, so treat a device-farm finding as a reason to review and let the size of the cluster guide the action.
- Recognition after a reinstall differs by platform: on iOS a reinstall on the same device keeps its visitor ID, and on Android it starts a new one.
Detection coverage is described as it stands for the current native SDKs. It is not a guarantee against every tool an attacker may use.
