deardaniel/secdata-raw huggingface dataset:
OWASP Mobile Application Security Testing Guide: MASTG BEST 0009

---
title: Use Secure Encryption Algorithms
alias: use-secure-encryption-algorithms
id: MASTG-BEST-0009
platform: android
---

Replace insecure encryption algorithms with secure ones such as AES-256 (preferably in GCM mode) or Chacha20.

For comprehensive guidance on implementing secure encryption in Android, refer to the documentation on ["Cryptography"](https://developer.android.com/privacy-and-security/cryptography) and ["Broken or risky cryptographic algorithm"](https://developer.android.com/privacy-and-security/risks/broken-cryptographic-algorithm#weak-or-broken-cryptographic-encryption-functions-use-strong-cryptographic-algorithms-in-encryption-1B2M2Y8Asg) on the official Android Developers website.
OWASP Mobile Application Security Testing Guide: MASTG BEST 0011

---
title: Securely Load File Content in a WebView
alias: securely-load-file-content-in-webview
id: MASTG-BEST-0011
platform: android
knowledge: [MASTG-KNOW-0018]
---

The recommended approach to **load file content to a WebView securely** is to use [`WebViewClient`](https://developer.android.com/reference/android/webkit/WebViewClient) with [`WebViewAssetLoader`](https://developer.android.com/reference/androidx/webkit/WebViewAssetLoader) to load assets from the app's assets or resources directory using `https://` URLs instead of insecure `file://` URLs. This ensures the content is loaded in a secure, same-origin environment and avoids exposing local files to potential cross-origin attacks.

If you must allow the WebView to load local files using the `file://` scheme, consider the following:

- For apps with a `minSdkVersion` that has secure defaults for WebView file access methods, ensure that these methods are **not used** and the default values are preserved. Alternatively, explicitly set them to `false` to guarantee the WebView does not allow local file access:
    - `setAllowFileAccess(false)`
    - `setAllowFileAccessFromFileURLs(false)`
    - `setAllowUniversalAccessFromFileURLs(false)`

- For apps with a `minSdkVersion` that **does not have secure defaults** for these methods (e.g., older API levels), ensure that the above methods are **explicitly** set to `false` in your WebView configuration.

For more details, refer to the [official Android documentation on loading local content securely](https://developer.android.com/develop/ui/views/layout/webapps/load-local-content), especially the section on ["Things to avoid"](https://developer.android.com/develop/ui/views/layout/webapps/load-local-content#antipatterns).
OWASP Mobile Application Security Testing Guide: MASTG BEST 0032

---
title: Migrate from UIWebView to WKWebView
alias: migrate-from-uiwebview-to-wkwebview
id: MASTG-BEST-0032
platform: ios
knowledge: [MASTG-KNOW-0076]
---

Apple deprecated [`UIWebView`](https://developer.apple.com/documentation/uikit/uiwebview) in iOS 12 in favor of [`WKWebView`](https://developer.apple.com/documentation/webkit/wkwebview) for better security and performance. Migrate your app to `WKWebView` to benefit from its improved security features, such as out-of-process rendering and enhanced JavaScript control. `WKWebView` allows you to disable JavaScript entirely, preventing script injection vulnerabilities, and provides better isolation between web content and the app, reducing the risk of memory corruption affecting the main app process. Additionally, `WKWebView` supports modern web security features like Content Security Policy (CSP), which can further enhance the security of your web content.
OWASP Mobile Application Security Testing Guide: MASTG BEST 0014

---
title: Preventing Screenshots and Screen Recording
alias: preventing-screenshots-and-screen-recording
id: MASTG-BEST-0014
platform: android
---

Ensure the app hides sensitive content, such as card numbers and passcodes, from screenshots, screen recording, nonsecure displays, task switcher thumbnails, and remote screen sharing. Malware may capture screen output and extract confidential information. Protect on screen keyboards or custom keypad views as they may leak keystrokes from passcode fields. Screenshots can be saved in locations accessible to other apps or a local attacker.

Setting [`FLAG_SECURE`](https://developer.android.com/security/fraud-prevention/activities#flag_secure) on the window prevents screenshots (or appear black), blocks screen recording, and hides content on nonsecure displays and in the system task switcher.

<div style="display:flex; flex-wrap:wrap; gap:16px; align-items:flex-start; margin:16px 0;">
  <figure style="flex:1 1 220px; margin:0; text-align:center;">
    <img src="Images/Chapters/0x05d/task-switcher-without-flag-secure.png" width="200" alt="Task switcher without FLAG_SECURE">
    <figcaption>Without <code>FLAG_SECURE</code></figcaption>
  </figure>
  <figure style="flex:1 1 220px; margin:0; text-align:center;">
    <img src="Images/Chapters/0x05d/task-switcher-with-flag-secure.png" width="200" alt="Task switcher with FLAG_SECURE">
    <figcaption>With <code>FLAG_SECURE</code></figcaption>
  </figure>
</div>

You can follow the official documentation to implement `FLAG_SECURE` in your app, see ["Secure sensitive activities"](https://developer.android.com/security/fraud-prevention/activities).
OWASP Mobile Application Security Testing Guide: MASTG BEST 0039

---
title: Prevent SQL Injection in ContentProviders
alias: prevent-sqli-contentprovider
id: MASTG-BEST-0039
platform: android
knowledge: [MASTG-KNOW-0117]
---

The `ContentProvider` enables Android applications to share data with other applications and system components. If a `ContentProvider` constructs SQL queries using untrusted input from URIs, IPC calls, or Intents without validation or parameterization, it becomes vulnerable to SQL injection. Attackers can take advantage of this vulnerability to bypass access controls and extract sensitive data. Improper handling of URI path segments, query parameters, or `selection` arguments in `ContentProvider` queries can lead to arbitrary SQL execution.

- **Use Parameterized Queries**: Instead of building SQL using string concatenation, use `selection` and `selectionArgs` parameters.

For example:

```kotlin
  val idSegment = uri.getPathSegments()[1]
  val selection = "id = ?"
  val selectionArgs = arrayOf(idSegment)
  val cursor = qb.query(db, projection, selection, selectionArgs, null, null, sortOrder)
```

- **Use Prepared Statements**: When performing insert, update, or delete operations, use SQLite prepared statements (for example, `SQLiteStatement` or `SQLiteDatabase` methods that support argument binding) instead of dynamically constructed SQL. Prepared statements ensure that untrusted input is bound as parameters and cannot alter the structure of the SQL query, effectively preventing SQL injection even when input originates from URIs or IPC calls.

Refer to ["Protect against malicious input"](https://developer.android.com/guide/topics/providers/content-provider-basics#Injection) for more information.
OWASP Mobile Application Security Testing Guide: MASTG BEST 0023

---
title: Exclude Sensitive Information from Backups
alias: exclude-sensitive-information-from-backups
id: MASTG-BEST-0023
platform: ios
knowledge: [MASTG-KNOW-0102]
---

iOS does not provide a guaranteed mechanism to exclude files from backups. Setting [`NSURLIsExcludedFromBackupKey`](https://developer.apple.com/documentation/foundation/urlresourcekey/isexcludedfrombackupkey) instructs the system not to include a file in backups, but it does not ensure exclusion. To reduce data exposure, apply the following techniques:

## Bind Data to the Current Device

Store sensitive data in the Keychain and mark it with [`kSecAttrAccessibleWhenUnlockedThisDeviceOnly`](https://developer.apple.com/documentation/security/ksecattraccessiblewhenunlockedthisdeviceonly) or [`kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly`](https://developer.apple.com/documentation/security/ksecattraccessiblewhenpasscodesetthisdeviceonly) to keep secrets restricted to the current device. When implementing this, create a new Keychain entry and set the `kSecAttrAccessible` attribute to one of the `ThisDeviceOnly` values when inserting the item.

### Handling Larger Files

For larger files, store them encrypted within the app container and keep the decryption key in the Keychain using a `ThisDeviceOnly` accessibility class. When you need to use the files, decrypt them only into RAM or into non‑backed‑up locations such as `/Library/Caches` or `/tmp`. Note that these locations are [_purgeable_](https://developer.apple.com/documentation/foundation/optimizing-your-app-s-data-for-icloud-backup), and the system may delete their contents at any time; avoid treating them as durable storage. Be prepared to re‑decrypt the files on demand if they are cleared.

## Bind Data to the User via a Server-Managed Key

If binding to the device is insufficient, you can instead bind data to a user by storing the decryption key on your server and releasing it only after successful authentication. Do not persist this key on the device; keep it only in RAM and decrypt files as described above.
OWASP Mobile Application Security Testing Guide: MASTG BEST 0016

---
title: Use `SECURE_FLAG` to Prevent Screenshots and Screen Recording
alias: use-secure-flag-to-prevent-screenshots-and-screen-recording
id: MASTG-BEST-0016
platform: android
status: placeholder
note: Preventing screenshots and screen recording helps protect sensitive data from being exposed in system-generated snapshots and recordings.
---
OWASP Mobile Application Security Testing Guide: MASTG BEST 0034

---
title: Validate WebView Input
alias: validate-webview-input
id: MASTG-BEST-0034
platform: ios
knowledge: [MASTG-KNOW-0076]
---

Always treat any data passed to a [`WKWebView`](https://developer.apple.com/documentation/webkit/wkwebview) as untrusted unless it is fully controlled by the app. This includes URLs loaded through [`load(_:)`](https://developer.apple.com/documentation/webkit/wkwebview/load(_:)), local files loaded through [`loadFileURL`](https://developer.apple.com/documentation/webkit/wkwebview/loadfileurl(_:allowingreadaccessto:)), HTML passed to [`loadHTMLString`](https://developer.apple.com/documentation/webkit/wkwebview/loadhtmlstring(_:baseurl:)), JavaScript passed to [`evaluateJavaScript`](https://developer.apple.com/documentation/webkit/wkwebview/evaluatejavascript(_:completionhandler:)), and any data inserted into the rendered page.

If the app loads a URL into a `WKWebView`, the URL should be parsed and validated against a strict allowlist of expected schemes, hosts, paths, and other relevant components. Do not allow attacker-controlled input, such as deep links, custom URL schemes, pasted text, or server-supplied values, to determine arbitrary WebView destinations.

For deep links and custom URL schemes, only accept known commands and fixed destinations. Do not forward arbitrary URL parameters directly into `WKWebView.load(_:)`.

If untrusted data must be displayed inside web content, avoid HTML and JavaScript injection patterns such as [`innerHTML`](https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML) or string built `evaluateJavaScript` calls. Prefer safe text only rendering and context appropriate escaping.

If local content is loaded with `loadFileURL`, keep `allowingReadAccessTo` as narrow as possible and never combine broad local file access with untrusted HTML or script injection.
OWASP Mobile Application Security Testing Guide: MASTG BEST 0013

---
title: Disable Content Provider Access in WebViews
alias: disable-cont
id: MASTG-BEST-0013
platform: android
knowledge: [MASTG-KNOW-0018]
---

Unlike other file content access methods from `WebSettings`, the `setAllowContentAccess` method always defaults to `true`. Therefore, **whenever access to content providers isn't explicitly needed**, ensure that the `setAllowContentAccess` method is set to `false` to prevent WebViews from accessing content providers.

## Why is this important?

Enabling content access in a WebView is not a vulnerability per se; it increases the number of ways an attacker could chain vulnerabilities. For example, if combined with an XSS or other injection vulnerability (or if the WebView is used to display untrusted remote content), it can allow an attacker to read sensitive data that they can send back to a remote server.

Although there are many "safeguards" (such as CORS restrictions and the fact that a non-exported provider won't serve data to any external caller), the app's own content providers would be accessible even if they were not exported; they may have access to the app's private storage, both in internal and external storage. Also in some cases even other apps' files in shared/external storage, depending on the app permissions (e.g. `READ_MEDIA_IMAGES`, etc.).
OWASP Mobile Application Security Testing Guide: MASTG BEST 0001

---
title: Use Secure Random Number Generator APIs
alias: android-use-secure-random
id: MASTG-BEST-0001
platform: android
knowledge: [MASTG-KNOW-0013]
---

Use a cryptographically secure pseudorandom number generator as provided by the platform or programming language you are using.

## Java/Kotlin

Use [`java.security.SecureRandom`](https://developer.android.com/reference/java/security/SecureRandom), which complies with the statistical random number generator tests specified in [FIPS 140-2, Security Requirements for Cryptographic Modules, section 4.9.1](http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.140-2.pdf) and meets the cryptographic strength requirements described in [RFC 4086: Randomness Requirements for Security](http://tools.ietf.org/html/rfc4086). It produces non-deterministic output and automatically seeds itself during object initialization using system entropy, so manual seeding is generally unnecessary and can weaken randomness if not done properly.

The default (no-argument) constructor of `SecureRandom` is recommended, as it uses the system-provided seed of appropriate length to ensure high entropy. Providing a seed (hardcoded or otherwise) to the constructor is [discouraged in the Android Documentation](https://developer.android.com/privacy-and-security/risks/weak-prng?source=studio#weak-prng-java-security-securerandom), because it risks creating deterministic output and undermining security.

Although [the documentation](https://developer.android.com/reference/java/security/SecureRandom?hl=en#setSeed(byte[])) says the provided seed normally supplements the existing seed, this behavior may differ if an [old security provider](https://android-developers.googleblog.com/2016/06/security-crypto-provider-deprecated-in.html) is used. To avoid these pitfalls, ensure your app targets a modern Android version with an updated provider or explicitly configures a secure provider such as AndroidOpenSSL (or Conscrypt in newer releases).

## Other Languages

Consult the standard library or framework documentation to find the API that exposes the operating system's cryptographically secure pseudorandom number generator. This is usually the safest approach, provided there are no known vulnerabilities in that library's random number generation. For example, see the [Flutter/Dart issue](https://www.zellic.io/blog/proton-dart-flutter-csprng-prng/) as a reminder that some frameworks may have known weaknesses in their PRNG implementations.
OWASP Mobile Application Security Testing Guide: MASTG BEST 0019

---
title: Use Non-Caching Input Types for Sensitive Fields
alias: use-non-caching-input-types
id: MASTG-BEST-0019
platform: android
knowledge: [MASTG-KNOW-0055]
status: placeholder
note: Using non-caching input types helps protect sensitive data from being exposed in system-generated snapshots and recordings.
---
OWASP Mobile Application Security Testing Guide: MASTG BEST 0005

---
title: Use Secure Encryption Modes
alias: use-secure-encryption-modes
id: MASTG-BEST-0005
platform: android
---

Replace insecure encryption modes with secure block cipher modes such as [AES-GCM or AES-CCM](https://csrc.nist.gov/pubs/sp/800/38/d/final) which are authenticated encryption modes that provide confidentiality, integrity, and authenticity.

We recommend avoiding CBC, which while being more secure than ECB, improper implementation, especially incorrect padding, can lead to vulnerabilities such as padding oracle attacks.

For comprehensive guidance on implementing secure encryption modes in Android, refer to the official Android Developers documentation on [Cryptography](https://developer.android.com/privacy-and-security/cryptography).
OWASP Mobile Application Security Testing Guide: MASTG BEST 0025

---
title: Use Secure Random Number Generator APIs
alias: ios-use-secure-random
id: MASTG-BEST-0025
platform: ios
knowledge: [MASTG-KNOW-0070]
---

Use secure random number generator APIs that are backed by the operating system _cryptographically secure pseudorandom number generator (CSPRNG)_. Do not build your own _pseudorandom number generator (PRNG)_.

## Swift / Objective-C

- **Security Framework (preferred)**: Use the [`SecRandomCopyBytes`](https://developer.apple.com/documentation/security/secrandomcopybytes(_:_:_:)) API from the Security framework, which produces cryptographically secure random bytes backed by the system CSPRNG.
- **CommonCrypto**: You _could_ use `CCRandomCopyBytes` or `CCRandomGenerateBytes` (not documented on the Apple Developers website), which are also backed by the system CSPRNG. However, prefer `SecRandomCopyBytes` which is a wrapper around these functions.
- **Swift Standard Library**: You can use the Swift Standard Library `.random` APIs which are backed by `SystemRandomNumberGenerator`. However, note that their random number generator can be customized, so ensure you use the default `SystemRandomNumberGenerator` (e.g., by not specifying a custom generator) or a secure alternative (ensure it is cryptographically secure).
- **CryptoKit**: CryptoKit doesn't expose a direct random byte generator, but it provides secure random nonces and keys through its cryptographic operations, which are backed by the system CSPRNG. For example, you can use `SymmetricKey` for keys and `AES.GCM.Nonce` for nonces without needing to manage raw random bytes directly.

See @MASTG-KNOW-0070 for code examples of these APIs.

## Other Languages

Consult the standard library or framework to locate the API that exposes the operating system CSPRNG. This is usually the safest path, provided the library itself has no known weaknesses.

For cross-platform or hybrid apps on iOS rely on frameworks that forward calls to the underlying system CSPRNG. For example:

- In Flutter or Dart use [`Random.secure()`](https://api.flutter.dev/flutter/dart-math/Random/Random.secure.html), which is documented as cryptographically secure. It reaches `SecRandomCopyBytes` through [the platform integration layers](https://github.com/dart-lang/sdk/blob/47e77939fce74ffda0b7252f33ba1ced2ea09c52/runtime/bin/crypto_macos.cc#L16). See [this article](https://www.zellic.io/blog/proton-dart-flutter-csprng-prng/) for a security review.
- In React Native use a library such as [`react-native-secure-random`](https://github.com/robhogan/react-native-securerandom) or [`react-native-get-random-values`](https://github.com/LinusU/react-native-get-random-values), which internally calls `SecRandomCopyBytes` on iOS.
OWASP Mobile Application Security Testing Guide: MASTG BEST 0024

---
title: Store Data Encrypted in App Sandbox Directory
alias: store-data-encrypted-in-the-app-sandbox-directory
id: MASTG-BEST-0024
platform: ios
knowledge: [MASTG-KNOW-0108]
---

Choose the right location for storing the app's and the user's data to the app sandbox: use **Documents** directory to store user-generated content and **Library** directory for app's internal data.

An app can be configured to make **Documents** directory accessible to the user in the Files app by setting `UIFileSharingEnabled` and `LSSupportsOpeningDocumentsInPlace`. Therefore, storing databases, config files, purchase state in this directory is highly dangerous because:

- a user can tamper with internal app files
- an attacker with a physical access to the device can copy content of `Documents` directory
- other apps can access `Documents` directory of other apps with a [document picker interface](https://developer.apple.com/documentation/uikit/uidocumentpickerviewcontroller)

**Note:** Storing data in the correct directory doesn't mean it's secure. For L2 profile apps, it's recommended to encrypt the files before storing them, and put the encryption key into the Keychain.
OWASP Mobile Application Security Testing Guide: identify sensitive data

## Identifying Sensitive Data

Classifications of sensitive information differ by industry and country. In addition, organizations may take a restrictive view of sensitive data, and they may have a data classification policy that clearly defines sensitive information.

There are three general states from which data may be accessible:

- **At rest** - the data is sitting in a file or data store
- **In use** - an app has loaded the data into its address space
- **In transit** - data has been exchanged between mobile app and endpoint or consuming processes on the device, e.g., during IPC (Inter-Process Communication)

The degree of scrutiny that's appropriate for each state may depend on the data's importance and likelihood of being accessed. For example, data held in app memory may be more vulnerable than data on web servers to access via core dumps because attackers are more likely to gain physical access to mobile devices than to web servers.

When no data classification policy is available, use the following list of information that's generally considered sensitive:

- user authentication information (credentials, PINs, etc.)
- Personally Identifiable Information (PII) that can be abused for identity theft: social security numbers, credit card numbers, bank account numbers, health information
- device identifiers that may identify a person
- highly sensitive data whose compromise would lead to reputational harm and/or financial costs
- any data whose protection is a legal obligation
- any technical data generated by the app (or its related systems) and used to protect other data or the system itself (e.g., encryption keys)

A definition of "sensitive data" must be decided before testing begins because detecting sensitive data leakage without a definition may be impossible.