Android Tutorial Understanding Network security configuration

Every developer must understand this article if developing any kind of network communication app.

Android os recent versions put end apps users privacy at the heart of its platform, the network communication between apps MUST BE secure by default, meaning connection must be to HTTPS not HTTP , because HTTP connection is exposed to any interceptor ,then user data breached and user privacy violated.
So, if your app connects to the server using plain HTTP , app connection will be failed by default.
Android creates xml file managing this matter, the file is network_security_config.xml
This file makes the rules for connection pattern without modifying the app code.

To understand these rules (by very simple explaining) we want to basically understand normal connection between client and server using HTTPS:
- Client requests HTTPS url
- Server sends its SSL/TLS certificate (hashed plain file) to client before sending actual data response.
- Client OS (not app itself) checks if this server certificate is TRUSTED CA type (Either check if it stored before in device ca reposity Or connect to external CA Authorities servers to check).
- If client OS found the certificate is Trusted, then it allow server to complete the operation by sending data response to client app.
- If client OS found the certificate is NOT Trusted, then it cut and cancel the connection and throw SSl/TLS error.

Now, What is NOT TRUSTED CA mean? It means the server actually has certificate, but it is not issued/created by global certificates issuers who are called as TRUSTED CA (Certificate Authority).

So, Why is "Not Trusted Certificate" important? Yes, it is important, because not all Cert must be issued using Trusted CA, for example:
- Custom certificates generated by your organizaion for internal use only, no need for third parity Trusted CA.
- Always Trusted CA certificate is costly & must be renewed every year for the issuer.
- Our app need specific self-signed certificate issued by our server, so we can generate server and client cert to communicate between our app and its server.

So, this file network_security_config.xml comes to fill the gap.

Legitimate(whitelist) HTTP connection (non ssl/tls) for Google Play Store :

In B4A, when creating app and using okhttp library for example, app will works fine with HTTPS urls because it uses the default network security policy.
But if we called HTTP url (not HTTPS), app crashes with SSL/TLS exception error, because you violate network security rules and user privacy.
So if you want to solve it you should add this line to manifest editor as first step:
B4X:
CreateResourceFromFile(Macro, Core.NetworkClearText)
The above code will generate our file network_security_config.xml inside objects/res/xml directory, it contains the following rules:
B4X:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true">
    <trust-anchors>
        <certificates src="system" />
    </trust-anchors>
</base-config>
</network-security-config>
The above tags allow our app to accept non-secure HTTP urls connections (cleartextTrafficPermitted="true").
It is a wildcard setting used for app testing purpose or internal distribution only, Google Play Store will REJECT the app if you publish it (It is against user privacy protection).
So, let's customize the rules above to be acceptable with Google Play Store privacy.
cleartextTrafficPermitted="true" means accept ALL HTTP connections, so you placed end users data communication under danger of breach.
So to avoid this violation you must:
- (MANDATORY) Define HTTP urls connections explicitly.
- (OPTIONAL) Document these urls in privacy policy file that used in google play, and explain why/how they are used.
Let's define our HTTP urls as the following:
- open network_security_config.xml
- replace all of its content with the following code:
B4X:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
    <domain includeSubdomains="true">example.com</domain>
    <domain includeSubdomains="false">example2.com</domain>
    <domain includeSubdomains="true">10.0.0.13</domain>
    <domain includeSubdomains="true">192.168.1.111</domain>
</domain-config>
</network-security-config>
- Save the file
- Make file ready-only (because it will be overwritten by B4A compiler).
- Compile your app.
As we see, in domain tag we can define any domain or ip address to be allowed for HTTP connection without rejection by Google Play Store.
You can add domain or ip as much as you want.
All tags are simple and understandable.


Thanks.
 

hatzisn

Expert
Licensed User
Longtime User
Hi, is this a latest android demand? I am asking because I already have an application that uses plain http for non important data only.
 

Hamied Abou Hulaikah

Well-Known Member
Licensed User
Longtime User
Hi, is this a latest android demand? I am asking because I already have an application that uses plain http for non important data only.
For new app want to publish to Google play, it is mandatory demand, because it requires at least mintargetsdk 31.
For existing app published before, I don't know how google play react!
 

beelze69

Active Member
Licensed User
Longtime User
Every developer must understand this article if developing any kind of network communication app.

Android os recent versions put end apps users privacy at the heart of its platform, the network communication between apps MUST BE secure by default, meaning connection must be to HTTPS not HTTP , because HTTP connection is exposed to any interceptor ,then user data breached and user privacy violated.
So, if your app connects to the server using plain HTTP , app connection will be failed by default.
Android creates xml file managing this matter, the file is network_security_config.xml
This file makes the rules for connection pattern without modifying the app code.

To understand these rules (by very simple explaining) we want to basically understand normal connection between client and server using HTTPS:
- Client requests HTTPS url
- Server sends its SSL/TLS certificate (hashed plain file) to client before sending actual data response.
- Client OS (not app itself) checks if this server certificate is TRUSTED CA type (Either check if it stored before in device ca reposity Or connect to external CA Authorities servers to check).
- If client OS found the certificate is Trusted, then it allow server to complete the operation by sending data response to client app.
- If client OS found the certificate is NOT Trusted, then it cut and cancel the connection and throw SSl/TLS error.

Now, What is NOT TRUSTED CA mean? It means the server actually has certificate, but it is not issued/created by global certificates issuers who are called as TRUSTED CA (Certificate Authority).

So, Why is "Not Trusted Certificate" important? Yes, it is important, because not all Cert must be issued using Trusted CA, for example:
- Custom certificates generated by your organizaion for internal use only, no need for third parity Trusted CA.
- Always Trusted CA certificate is costly & must be renewed every year for the issuer.
- Our app need specific self-signed certificate issued by our server, so we can generate server and client cert to communicate between our app and its server.

So, this file network_security_config.xml comes to fill the gap.

Legitimate(whitelist) HTTP connection (non ssl/tls) for Google Play Store :

In B4A, when creating app and using okhttp library for example, app will works fine with HTTPS urls because it uses the default network security policy.
But if we called HTTP url (not HTTPS), app crashes with SSL/TLS exception error, because you violate network security rules and user privacy.
So if you want to solve it you should add this line to manifest editor as first step:
B4X:
CreateResourceFromFile(Macro, Core.NetworkClearText)
The above code will generate our file network_security_config.xml inside objects/res/xml directory, it contains the following rules:
B4X:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true">
    <trust-anchors>
        <certificates src="system" />
    </trust-anchors>
</base-config>
</network-security-config>
The above tags allow our app to accept non-secure HTTP urls connections (cleartextTrafficPermitted="true").
It is a wildcard setting used for app testing purpose or internal distribution only, Google Play Store will REJECT the app if you publish it (It is against user privacy protection).
So, let's customize the rules above to be acceptable with Google Play Store privacy.
cleartextTrafficPermitted="true" means accept ALL HTTP connections, so you placed end users data communication under danger of breach.
So to avoid this violation you must:
- (MANDATORY) Define HTTP urls connections explicitly.
- (OPTIONAL) Document these urls in privacy policy file that used in google play, and explain why/how they are used.
Let's define our HTTP urls as the following:
- open network_security_config.xml
- replace all of its content with the following code:
B4X:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
    <domain includeSubdomains="true">example.com</domain>
    <domain includeSubdomains="false">example2.com</domain>
    <domain includeSubdomains="true">10.0.0.13</domain>
    <domain includeSubdomains="true">192.168.1.111</domain>
</domain-config>
</network-security-config>
- Save the file
- Make file ready-only (because it will be overwritten by B4A compiler).
- Compile your app.
As we see, in domain tag we can define any domain or ip address to be allowed for HTTP connection without rejection by Google Play Store.
You can add domain or ip as much as you want.
All tags are simple and understandable.


Thanks.
Hi Hamied,

Very nicely explained..
 
Top