Mobile
Android: allowBackup, cleartext traffic and network security config
Three AndroidManifest settings often turn into mobile expertise findings. How to configure backups, unencrypted traffic and certificate trust correctly.
· 7 min read

Many of an Android app's security properties are defined not in code but in AndroidManifest.xml and a few XML
files. They look minor, yet in a mobile expertise they often come up as separate findings. While preparing the
Android app of our own product for expertise, we revisited three settings: backups (allowBackup), unencrypted
HTTP traffic and the network security configuration.
These settings map to the MASVS-STORAGE and MASVS-NETWORK sections of OWASP MASVS.
1. allowBackup: keep data out of backups
By default, Android may back up an app's data (SharedPreferences, databases, internal files) — to the cloud or to
a computer via adb backup. If the app stores tokens, sessions or personal data, they leave the device and can be
restored on another one.
For an app that handles financial or personal data, the safest option is to disable backups:
<application
android:allowBackup="false"
android:fullBackupContent="false"
android:dataExtractionRules="@xml/data_extraction_rules"
... >
On Android 12 (API 31) and above, dataExtractionRules is taken into account alongside allowBackup. So create
res/xml/data_extraction_rules.xml and exclude data from both cloud backup and device-to-device transfer:
<?xml version="1.0" encoding="utf-8"?>
<data-extraction-rules>
<cloud-backup>
<exclude domain="root" path="." />
<exclude domain="file" path="." />
<exclude domain="database" path="." />
<exclude domain="sharedpref" path="." />
<exclude domain="external" path="." />
</cloud-backup>
<device-transfer>
<exclude domain="root" path="." />
<exclude domain="file" path="." />
<exclude domain="database" path="." />
<exclude domain="sharedpref" path="." />
<exclude domain="external" path="." />
</device-transfer>
</data-extraction-rules>
Disabling backups is only the first step. Our expertise report had a separate high-severity finding: sensitive
data was stored unencrypted in internal storage. We closed it by moving to flutter_secure_storage (Keystore-based
encryption on Android). In other words, even with backups off, data on the device still has to be encrypted.
2. Cleartext traffic: HTTPS only
Since Android 9 (API 28), unencrypted HTTP traffic is blocked by default when targetSdkVersion is 28 or higher.
In practice, though, it often gets switched back on: usesCleartextTraffic="true" is added during development to
reach a local server and then forgotten in the release.
State it explicitly in the manifest:
<application
android:usesCleartextTraffic="false"
android:networkSecurityConfig="@xml/network_security_config"
... >
Check the code too. Our report had a low-severity "insecure (http) links" finding: a few addresses starting with
http:// were left in the code. Even if they are unused, static analysis finds them. Search the whole project:
grep -rn "http://" lib/ android/app/src/main/ --include=*.dart --include=*.kt --include=*.java --include=*.xml
XML namespaces (http://schemas.android.com/...) are normal — do not confuse them with network addresses.
3. Network security config: whom we trust
network_security_config.xml defines which certificates the app trusts and which rules apply to which domains.
In our case, "insecure certificate validation" was a high-severity finding. To close it, we used this
configuration:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="false">
<trust-anchors>
<certificates src="system" />
</trust-anchors>
</base-config>
<domain-config cleartextTrafficPermitted="false">
<domain includeSubdomains="true">api.example.uz</domain>
<pin-set expiration="2027-06-30">
<pin digest="SHA-256">BASE64_ROOT_CA_PIN_1=</pin>
<pin digest="SHA-256">BASE64_ROOT_CA_PIN_2=</pin>
</pin-set>
</domain-config>
</network-security-config>
What matters here:
systemcertificates only. Adding<certificates src="user" />makes the app trust any certificate the user installs — which makes intercepting traffic through a proxy easier.- Pin-set. We pinned specific root CAs rather than the server certificate. That way, the app does not need a new release every time the server certificate is renewed. Use at least two pins (primary and backup).
expiration. After this date, pin checking switches off and the app keeps working. This prevents old, un-updated versions from being "locked out". Pick a date that fits your release plan.debug-overrides. If you need a proxy during development, allow it only inside<debug-overrides>— it has no effect in a release build.
A Flutter app has one subtlety: Dart's HTTP client does not fully use Android's network configuration. So we
implemented pinning in two layers: pin-set on Android, and in Dart a SecurityContext loaded with trusted root
certificates only.
Two more small but useful checks
android:debuggable— make sure the manifest does not hard-codetrue. A release build sets it tofalseautomatically, but a hand-written value can break that.android:exported— set it explicitly for everyactivity,serviceandreceiver. Components that external apps do not need to call should beexported="false".
How to test the settings in practice
Writing the configuration is not enough — confirm that it works. Install a user certificate on a test device and
route traffic through a proxy: the release build should refuse the connection. Then check that the app's data
cannot be extracted via adb backup or a device backup. The expertise runs the same kind of practical tests, so
it helps to know the outcome in advance.
Short checklist
allowBackup="false"anddata_extraction_rules.xmlare configured.- Sensitive data is in Keystore-backed encrypted storage.
usesCleartextTraffic="false", and nohttp://addresses remain in the code.network_security_config.xml:systemcertificates only, withpin-setandexpiration.- Debug settings live only inside
debug-overrides. debuggableandexportedvalues have been checked.
Security scan
Want your manifest and network settings checked before the expertise? Send your APK for a security scan. The Claude AI agent reviews the configuration, and our specialist confirms the results and points out exactly which lines to change.


