App Integrity & Injection Quiz
SECURITY › Security
Where must a Play Integrity token be decrypted and verified to provide real security?
- In the app, immediately after requestIntegrityToken() returns
- In a local SharedPreferences-backed cache stored on the device
- On your trusted backend server, via Google Play's verification
- Inside the WebView component that originally triggered the action
Answer: On your trusted backend server, via Google Play's verification
The token is encrypted and must be verified server-side; a tampered or rooted client could forge or bypass any in-app check, so only your backend can enforce the verdict.
Which device integrity verdict indicates the strongest assurance, including hardware-backed proof and recent security updates?
- MEETS_STRONG_INTEGRITY
- MEETS_BASIC_INTEGRITY
- MEETS_VIRTUAL_INTEGRITY
- MEETS_DEVICE_INTEGRITY
Answer: MEETS_STRONG_INTEGRITY
MEETS_STRONG_INTEGRITY adds hardware-backed security and up-to-date patches on top of device integrity, while BASIC is the weakest and VIRTUAL denotes a Play-backed emulator.
Which query is safe from SQL injection?
- db.rawQuery("SELECT * FROM users WHERE email = '" + email + "'", null)
- db.execSQL("DELETE FROM users WHERE name = '" + name + "'")
- "SELECT * FROM users WHERE id = " + userId run via rawQuery
- db.rawQuery("SELECT * FROM users WHERE email = ?", arrayOf(email))
Answer: db.rawQuery("SELECT * FROM users WHERE email = ?", arrayOf(email))
Only the parameterised form binds the value separately as data through a ? placeholder; the others concatenate untrusted input directly into SQL and are injectable.
How does Room help prevent SQL injection?
- It encrypts the SQLite file by default to block injection
- It binds @Query parameters and checks SQL at compile time
- It strips quotes and semicolons from user input automatically
- It runs each query in a separate sandboxed process
Answer: It binds @Query parameters and checks SQL at compile time
Room binds parameters like :email as bound arguments instead of string concatenation and validates queries at compile time; it does not sanitize by stripping characters or encrypt by default.
Which statement best describes root/tamper detection on Android?
- It cryptographically guarantees the app can't run on a rooted device
- It becomes entirely unnecessary once you enable R8 obfuscation in the app
- It raises attacker cost, though a controlled device can still bypass it
- It reliably replaces server-side checks for sensitive actions and trust
Answer: It raises attacker cost, though a controlled device can still bypass it
Because the attacker controls the device, any on-device check can be patched or spoofed; detection raises cost but cannot guarantee safety and never replaces server-side trust.
What is the correct characterisation of code obfuscation (e.g. R8) as a security measure?
- Defence-in-depth that slows reverse engineering but isn't security alone
- A complete substitute for HTTPS transport and all server-side validation checks
- A way to encrypt the app's business logic so it can never be read
- A guaranteed way to protect API keys embedded inside the shipped APK
Answer: Defence-in-depth that slows reverse engineering but isn't security alone
Obfuscation renames and shrinks code to raise reverse-engineering cost, but it does not encrypt logic or safely hide secrets; embedded keys remain extractable, so it is one layer among many.
Which WebView practice is the most dangerous if the loaded content is not fully trusted?
- Loading the remote page over HTTPS for transport-layer security
- Using addJavascriptInterface to expose native methods to JS
- Disabling scripting entirely with setJavaScriptEnabled(false)
- Checking every URL against a strict allowlist before loading it
Answer: Using addJavascriptInterface to expose native methods to JS
addJavascriptInterface bridges JavaScript to native code, so untrusted page content can invoke exposed methods; the other options are safe or actively protective hardening steps.
In a standard Play Integrity request, what is the purpose of supplying a request hash?
- It encrypts the integrity token so the client can read the verdict locally
- It compresses the integrity token to reduce request and response network overhead
- It ties the verdict to the request so a captured token can't be replayed elsewhere
- It removes the need for a backend, since the hash is verified on the device
Answer: It ties the verdict to the request so a captured token can't be replayed elsewhere
The request hash ties the returned verdict to the exact request being protected, so an attacker cannot reuse a valid token for an unrelated or replayed action; the token is still decrypted and verified server-side.
In the decrypted Play Integrity payload, what does an appRecognitionVerdict of PLAY_RECOGNIZED indicate?
- The user has never once installed this app from the Google Play Store
- The running binary and signing certificate match what Play distributed
- The device is rooted, though the app is still permitted to keep running
- The account currently holds a valid paid entitlement for this app
Answer: The running binary and signing certificate match what Play distributed
PLAY_RECOGNIZED means the app is the unmodified binary and certificate combination recognised by Google Play; licensing or entitlement is reported separately in the account details, not in the app recognition verdict.
Which older API did the Play Integrity API replace for attesting app and device genuineness?
- AccountManager for storing and accessing signed-in user accounts
- DevicePolicyManager for enforcing enterprise device policies
- Firebase Remote Config for updating app settings from the cloud
- SafetyNet Attestation API for app and device attestation checks
Answer: SafetyNet Attestation API for app and device attestation checks
Play Integrity is the successor to the now-deprecated SafetyNet Attestation API; the other options serve account, management, and configuration roles unrelated to attestation.
What does the MEETS_VIRTUAL_INTEGRITY device verdict label signify?
- The app is running on a physical, Play-certified Android phone
- The device failed all integrity checks and was fully rejected
- The app is running on a genuine Google-backed Android emulator
- The device provides StrongBox-backed hardware key storage support
Answer: The app is running on a genuine Google-backed Android emulator
MEETS_VIRTUAL_INTEGRITY identifies a legitimate Google-backed emulator environment, distinct from MEETS_DEVICE_INTEGRITY for physical certified devices; it is neither a failure verdict nor a statement about hardware key storage.
Why is server-side input validation still required even when the Android client already validates input before sending it?
- A modified client can skip on-device checks and send requests straight to your API
- Client-side validation always runs slower than server-side validation
- Server-side validation is only needed for GraphQL endpoints and not REST
- Android forbids validating user input in the UI layer, so checks belong on the server
Answer: A modified client can skip on-device checks and send requests straight to your API
The client is fully under the user's control, so on-device validation is only a UX convenience; an attacker can hit your endpoints directly, making the server the only place validation can be trusted.
What does R8, the default Android build-time optimizer, actually do?
- It encrypts the compiled DEX bytecode so it cannot be read at rest
- It signs and zip-aligns the release APK or App Bundle using your upload key
- It performs automatic runtime root detection and tamper checks
- It shrinks, optimizes, and obfuscates code, replacing ProGuard by default
Answer: It shrinks, optimizes, and obfuscates code, replacing ProGuard by default
R8 tree-shakes unused code, applies optimizations, and renames symbols, replacing ProGuard as the default toolchain; it does not encrypt bytecode, sign the artifact, or provide runtime tamper detection.
For a method on an object passed to addJavascriptInterface to be callable from JavaScript on modern Android, what is required?
- The method must be public and annotated with @JavascriptInterface
- Nothing; every public and private method on the object is automatically exposed
- The method must be declared directly inside the hosting Activity class
- JavaScript must first be disabled with setJavaScriptEnabled(false)
Answer: The method must be public and annotated with @JavascriptInterface
Since API 17, only public methods explicitly annotated with @JavascriptInterface are reachable from the page, which closed the earlier reflection-based remote-code-execution hole; the bridge obviously requires JavaScript to be enabled.