FlowDroid/IccTA only outputs suspicious data-leakage flows without specifying the specific data type, thus yields a large number of non-sensitive data-related issues such as debugging output (i.e., Log Data Leakage and SD Card Data Lekage), and redundant sources (i.e., the following example of SMS Data Leakage), which requires substantial manual effort to verify it.
Specifically, for the 4 types of data leakage of GCash, 13 types of sensitive data are detected by Ausera (i.e., 3 Logging Data Leakage, 7 SD Card Data Leakage, 1 SMS Data Leakage, and 0 SharedPreference Data Leakage), however, FlowDroid/IccTA outputs 73 leakages, thus yields 62 false positives through manual cross-validation by co-authors.
SMS Data Leakage/SharedPreference Data Leakage:
Found a flow to sink virtualinvoke $r10.<android.telephony.SmsManager: void sendTextMessage(java.lang.String,java.lang.String,java.lang.String,android.app.PendingIntent,android.app.PendingIntent)>($r1, null, $r2, $r6, $r7), from the following sources:
- $r5 = virtualinvoke $r4.<android.widget.EditText: android.text.Editable getText()>() (in <com.globe.gcash.android.activity.transaction.RegistrationTransactionActivity: void doNext()>)
- $r5 = virtualinvoke $r4.<android.widget.EditText: android.text.Editable getText()>() (in <com.globe.gcash.android.activity.transaction.RegistrationTransactionActivity: void doNext()>)
- $r5 = virtualinvoke $r4.<android.widget.EditText: android.text.Editable getText()>() (in <com.globe.gcash.android.activity.transaction.RegistrationTransactionActivity: void doNext()>)
- $r5 = virtualinvoke $r4.<android.widget.EditText: android.text.Editable getText()>() (in <com.globe.gcash.android.activity.transaction.RegistrationTransactionActivity: void doNext()>)
***Note that we cannot know the data type of variable $r4 only relying on the data-leakage flow.
***Actually, the five sources are the redundant sources if there is no concrete data type.
***The comparison results of Ausera can be referred at https://sites.google.com/view/ausera/homepage/demo
- $r1 := @parameter2: android.content.Intent (in <com.globe.gcash.android.facebook.BrowseFacebookFriendsListActivity: void onActivityResult(int,int,android.content.Intent)>)
Logging Data Leakage/SD Card Data Leakage:
Note that all of the data are exposed by Log function, however, most of them are non-sensitive data according to our manual analysis.
- $r5 = virtualinvoke $r4.<android.widget.EditText: android.text.Editable getText()>() (in <com.globe.gcash.android.activity.transaction.RegistrationTransactionActivity: void doNext()>)
- $r5 = virtualinvoke $r4.<android.widget.EditText: android.text.Editable getText()>() (in <com.globe.gcash.android.activity.transaction.RegistrationTransactionActivity: void doNext()>)
- $r5 = virtualinvoke $r4.<android.widget.EditText: android.text.Editable getText()>() (in <com.globe.gcash.android.activity.transaction.RegistrationTransactionActivity: void doNext()>)
- $r5 = virtualinvoke $r4.<android.widget.EditText: android.text.Editable getText()>() (in <com.globe.gcash.android.activity.transaction.RegistrationTransactionActivity: void doNext()>)
- $r1 := @parameter2: android.content.Intent (in <com.globe.gcash.android.activity.paybills.PayBillsTransactionActivity: void onActivityResult(int,int,android.content.Intent)>)
- $r5 = virtualinvoke $r4.<android.widget.EditText: android.text.Editable getText()>() (in <com.globe.gcash.android.activity.sendmoney.SendGcashMobileFieldsActivity: void onClickAction1(android.view.View)>)
- $r1 := @parameter2: android.content.Intent (in <com.globe.gcash.android.activity.transaction.SendMoneyTransactionActivity: void onActivityResult(int,int,android.content.Intent)>)
- $r1 := @parameter2: android.content.Intent (in <com.globe.gcash.android.activity.buyload.BuyLoadTransactionActivity: void onActivityResult(int,int,android.content.Intent)>)
- $r1 = virtualinvoke $r0.<com.globe.gcash.android.activity.dashboard.DashboardFragmentActivity: android.view.View findViewById(int)>(2131165456) (in <com.globe.gcash.android.activity.dashboard.DashboardFragmentActivity: void setActionBarIcon()>)
- $r1 := @parameter2: android.content.Intent (in <com.globe.gcash.android.activity.paybills.BillersActivity: void onActivityResult(int,int,android.content.Intent)>)
- $r1 := @parameter2: android.content.Intent (in <com.globe.gcash.android.activity.transaction.SendMoneyTransactionActivity: void onActivityResult(int,int,android.content.Intent)>)
- $r1 := @parameter2: android.content.Intent (in <com.globe.gcash.android.activity.buyload.BuyLoadTransactionActivity: void onActivityResult(int,int,android.content.Intent)>)
- $r2 = specialinvoke $r0.<roboguice.activity.RoboFragmentActivity: android.view.View findViewById(int)>($i0) (in <com.jeremyfeinstein.slidingmenu.lib.app.SlidingFragmentActivity: android.view.View findViewById(int)>)
- $r1 = virtualinvoke $r0.<com.globe.gcash.android.activity.GcashActivity: android.view.View findViewById(int)>(2131165456) (in <com.globe.gcash.android.activity.GcashActivity: void setActionBarIcon()>)
- $r2 = virtualinvoke $r1.<android.widget.EditText: android.text.Editable getText()>() (in <com.globe.gcash.android.activity.form.validator.FormValidator: boolean validateEditTextsDigitsIfExceedsRange(int,int,android.widget.EditText[])>)
- $r2 = virtualinvoke $r1.<android.widget.EditText: android.text.Editable getText()>() (in <com.globe.gcash.android.activity.form.validator.FormValidator: boolean validateEditTextsDigitsIfExceedsRange(int,int,android.widget.EditText[])>)
- $r5 = virtualinvoke $r4.<android.widget.EditText: android.text.Editable getText()>() (in <com.globe.gcash.android.activity.sendmoney.SendGcashMobileFieldsActivity: void onClickAction1(android.view.View)>)
- $r1 := @parameter2: android.content.Intent (in <com.globe.gcash.android.activity.transaction.SendMoneyTransactionActivity: void onActivityResult(int,int,android.content.Intent)>)
- $r1 := @parameter2: android.content.Intent (in <com.globe.gcash.android.activity.buyload.BuyLoadTransactionActivity: void onActivityResult(int,int,android.content.Intent)>)
- $r5 = virtualinvoke $r4.<android.widget.EditText: android.text.Editable getText()>() (in <com.globe.gcash.android.activity.transaction.RegistrationTransactionActivity: void doNext()>)
- $r5 = virtualinvoke $r4.<android.widget.EditText: android.text.Editable getText()>() (in <com.globe.gcash.android.activity.transaction.RegistrationTransactionActivity: void doNext()>)
- $r5 = virtualinvoke $r4.<android.widget.EditText: android.text.Editable getText()>() (in <com.globe.gcash.android.activity.transaction.RegistrationTransactionActivity: void doNext()>)
- $r5 = virtualinvoke $r4.<android.widget.EditText: android.text.Editable getText()>() (in <com.globe.gcash.android.activity.transaction.RegistrationTransactionActivity: void doNext()>)
- $r1 := @parameter2: android.content.Intent (in <com.globe.gcash.android.facebook.BrowseFacebookFriendsListActivity: void onActivityResult(int,int,android.content.Intent)>)
- $r1 := @parameter2: android.content.Intent (in <com.globe.gcash.android.activity.donate.DonateTransactionActivity: void onActivityResult(int,int,android.content.Intent)>)
- $i1 := @parameter1: int (in <com.globe.gcash.android.activity.buyload.BuyLoadTransactionActivity: void onActivityResult(int,int,android.content.Intent)>)
- $i1 := @parameter1: int (in <com.globe.gcash.android.activity.transaction.SendMoneyTransactionActivity: void onActivityResult(int,int,android.content.Intent)>)
- $i0 := @parameter0: int (in <com.globe.gcash.android.activity.transaction.SendMoneyTransactionActivity: void onActivityResult(int,int,android.content.Intent)>)
- $r1 := @parameter2: android.content.Intent (in <com.globe.gcash.android.activity.transaction.SendMoneyTransactionActivity: void onActivityResult(int,int,android.content.Intent)>)
- $r15 = virtualinvoke $r14.<android.widget.EditText: android.text.Editable getText()>() (in <com.globe.gcash.android.activity.paybills.PayBirTransactionActivity: void doNext()>)
- $r7 = virtualinvoke $r6.<android.widget.EditText: android.text.Editable getText()>() (in <com.globe.gcash.android.activity.transaction.SendMoneyTransactionActivity: void doNext()>)
- $r1 := @parameter2: android.content.Intent (in <com.globe.gcash.android.activity.paybills.PayBillsTransactionActivity: void onActivityResult(int,int,android.content.Intent)>)
- $r2 = virtualinvoke $r1.<android.widget.EditText: android.text.Editable getText()>() (in <com.globe.gcash.android.activity.paybills.PayBillsTransactionActivity: java.lang.String getAccountReference()>)
- $r7 = virtualinvoke $r6.<android.widget.EditText: android.text.Editable getText()>() (in <com.globe.gcash.android.activity.transaction.SendMoneyTransactionActivity: void doNext()>)
- $r15 = virtualinvoke $r14.<android.widget.EditText: android.text.Editable getText()>() (in <com.globe.gcash.android.activity.paybills.PayBirTransactionActivity: void doNext()>)
- $r7 = virtualinvoke $r6.<android.widget.EditText: android.text.Editable getText()>() (in <com.globe.gcash.android.activity.transaction.SendMoneyTransactionActivity: void doNext()>)
- $r15 = virtualinvoke $r14.<android.widget.EditText: android.text.Editable getText()>() (in <com.globe.gcash.android.activity.paybills.PayBirTransactionActivity: void doNext()>)
- $r10 = virtualinvoke $r9.<android.widget.EditText: android.text.Editable getText()>() (in <com.globe.gcash.android.activity.donate.DonateTransactionActivity: void doNext()>)
- $r9 = virtualinvoke $r8.<android.widget.EditText: android.text.Editable getText()>() (in <com.globe.gcash.android.activity.buyload.BuyLoadTransactionActivity: void doNext()>)
- $r15 = virtualinvoke $r14.<android.widget.EditText: android.text.Editable getText()>() (in <com.globe.gcash.android.activity.paybills.PayBirTransactionActivity: void doNext()>)
- $r15 = virtualinvoke $r14.<android.widget.EditText: android.text.Editable getText()>() (in <com.globe.gcash.android.activity.paybills.PayBirTransactionActivity: void doNext()>)
- $r7 = virtualinvoke $r6.<android.widget.EditText: android.text.Editable getText()>() (in <com.globe.gcash.android.activity.transaction.SendMoneyTransactionActivity: void doNext()>)
- $r1 := @parameter2: android.content.Intent (in <com.globe.gcash.android.activity.transaction.SendMoneyTransactionActivity: void onActivityResult(int,int,android.content.Intent)>)
- $r15 = virtualinvoke $r14.<android.widget.EditText: android.text.Editable getText()>() (in <com.globe.gcash.android.activity.paybills.PayBirTransactionActivity: void doNext()>)
- $r11 = virtualinvoke $r10.<android.widget.EditText: android.text.Editable getText()>() (in <com.globe.gcash.android.activity.paybills.PayBillsTransactionActivity: void doNext()>)
- $r1 := @parameter2: android.content.Intent (in <com.globe.gcash.android.activity.donate.DonateTransactionActivity: void onActivityResult(int,int,android.content.Intent)>)
- $r9 = virtualinvoke $r8.<android.widget.EditText: android.text.Editable getText()>() (in <com.globe.gcash.android.activity.buyload.BuyLoadTransactionActivity: void doNext()>)
- $r7 = virtualinvoke $r6.<android.widget.EditText: android.text.Editable getText()>() (in <com.globe.gcash.android.activity.transaction.SendMoneyTransactionActivity: void doNext()>)
- $r7 = virtualinvoke $r6.<android.widget.EditText: android.text.Editable getText()>() (in <com.globe.gcash.android.activity.transaction.SendMoneyTransactionActivity: void doNext()>)
- $r15 = virtualinvoke $r14.<android.widget.EditText: android.text.Editable getText()>() (in <com.globe.gcash.android.activity.paybills.PayBirTransactionActivity: void doNext()>)
- $r7 = virtualinvoke $r6.<android.widget.EditText: android.text.Editable getText()>() (in <com.globe.gcash.android.activity.transaction.SendMoneyTransactionActivity: void doNext()>)
- $r1 := @parameter2: android.content.Intent (in <com.globe.gcash.android.activity.paybills.PayBillsTransactionActivity: void onActivityResult(int,int,android.content.Intent)>)
- $r2 = virtualinvoke $r1.<android.widget.EditText: android.text.Editable getText()>() (in <com.globe.gcash.android.activity.paybills.PayBillsTransactionActivity: java.lang.String getAccountReference()>)
- $r7 = virtualinvoke $r6.<android.widget.EditText: android.text.Editable getText()>() (in <com.globe.gcash.android.activity.transaction.SendMoneyTransactionActivity: void doNext()>)
- $r15 = virtualinvoke $r14.<android.widget.EditText: android.text.Editable getText()>() (in <com.globe.gcash.android.activity.paybills.PayBirTransactionActivity: void doNext()>)
- $r7 = virtualinvoke $r6.<android.widget.EditText: android.text.Editable getText()>() (in <com.globe.gcash.android.activity.transaction.SendMoneyTransactionActivity: void doNext()>)
- $r15 = virtualinvoke $r14.<android.widget.EditText: android.text.Editable getText()>() (in <com.globe.gcash.android.activity.paybills.PayBirTransactionActivity: void doNext()>)
- $r10 = virtualinvoke $r9.<android.widget.EditText: android.text.Editable getText()>() (in <com.globe.gcash.android.activity.donate.DonateTransactionActivity: void doNext()>)
- $r9 = virtualinvoke $r8.<android.widget.EditText: android.text.Editable getText()>() (in <com.globe.gcash.android.activity.buyload.BuyLoadTransactionActivity: void doNext()>)
- $r15 = virtualinvoke $r14.<android.widget.EditText: android.text.Editable getText()>() (in <com.globe.gcash.android.activity.paybills.PayBirTransactionActivity: void doNext()>)
- $r15 = virtualinvoke $r14.<android.widget.EditText: android.text.Editable getText()>() (in <com.globe.gcash.android.activity.paybills.PayBirTransactionActivity: void doNext()>)
- $r7 = virtualinvoke $r6.<android.widget.EditText: android.text.Editable getText()>() (in <com.globe.gcash.android.activity.transaction.SendMoneyTransactionActivity: void doNext()>)
- $r1 := @parameter2: android.content.Intent (in <com.globe.gcash.android.activity.transaction.SendMoneyTransactionActivity: void onActivityResult(int,int,android.content.Intent)>)
- $r15 = virtualinvoke $r14.<android.widget.EditText: android.text.Editable getText()>() (in <com.globe.gcash.android.activity.paybills.PayBirTransactionActivity: void doNext()>)
- $r11 = virtualinvoke $r10.<android.widget.EditText: android.text.Editable getText()>() (in <com.globe.gcash.android.activity.paybills.PayBillsTransactionActivity: void doNext()>)
- $r1 := @parameter2: android.content.Intent (in <com.globe.gcash.android.activity.donate.DonateTransactionActivity: void onActivityResult(int,int,android.content.Intent)>)
- $r9 = virtualinvoke $r8.<android.widget.EditText: android.text.Editable getText()>() (in <com.globe.gcash.android.activity.buyload.BuyLoadTransactionActivity: void doNext()>)
- $r7 = virtualinvoke $r6.<android.widget.EditText: android.text.Editable getText()>() (in <com.globe.gcash.android.activity.transaction.SendMoneyTransactionActivity: void doNext()>)
- $r7 = virtualinvoke $r6.<android.widget.EditText: android.text.Editable getText()>() (in <com.globe.gcash.android.activity.transaction.SendMoneyTransactionActivity: void doNext()>)
Found a flow to sink virtualinvoke $r0.<com.globe.gcash.android.activity.sendmoney.SendGcashMobileFieldsActivity: void setResult(int,android.content.Intent)>(-1, $r3), from the following sources:
- $r5 = virtualinvoke $r4.<android.widget.EditText: android.text.Editable getText()>() (in <com.globe.gcash.android.activity.sendmoney.SendGcashMobileFieldsActivity: void onClickAction1(android.view.View)>)
- $r5 = virtualinvoke $r4.<android.widget.EditText: android.text.Editable getText()>() (in <com.globe.gcash.android.activity.sendmoney.SendGcashMobileFieldsActivity: void onClickAction1(android.view.View)>)
- $r1 := @parameter2: android.content.Intent (in <com.globe.gcash.android.facebook.BrowseFacebookFriendsListActivity: void onActivityResult(int,int,android.content.Intent)>)
We find that most of the encryption-related weaknesses we defined in Ausera overlap with those in CongiCrypt, however, they both have some unique rules. For example, Ausera considers hard-coded key embedded in the apk while CongiCrypt does not; CongiCrypt suggests using TLSv1, TLSv1.1, or TLSv1.2 instead of TLS or SSL while Ausera does not.
Specifically, for the encryption issue types of GCash, 5 types of encryption issues are detected by Ausera (i.e., Encryption key hard-coded, Using DES/Blowfish, Improper RSA, Insecure SecureRandom, Insecure hash function (md5/sha1)). CongiCrypt also identified 5 types (i.e., ImpreciseValueExtractionError violating CrySL rule for MessageDigest, ConstraintError violating CrySL rule for MessageDigest, ConstraintError violating CrySL rule for javax.net.ssl.SSLContext [insure hash function, TLSv1/TLSv1.1/TLSv1.2], IncompleteOperationError violating CrySL rule for javax.net.ssl.SSLContext, RequiredPredicateError violating CrySL rule for javax.net.ssl.SSLContext [Insecure SecureRandom]). In summary, 3 types of security encryption issues are overlap. 2 types are unique for each of them.
(1) Unique results of Ausera
com.globe.gcash.soap.server.container.SessionEncryptor2$1.<init> ==> enc.key
public void <init>() {
org.bouncycastle.jce.provider.symmetric.Blowfish$Mappings $r0;
$r0 := @this: org.bouncycastle.jce.provider.symmetric.Blowfish$Mappings;
specialinvoke $r0.<java.util.HashMap: void <init>()>();
virtualinvoke $r0.<org.bouncycastle.jce.provider.symmetric.Blowfish$Mappings: java.lang.Object put(java.lang.Object,java.lang.Object)>("Cipher.BLOWFISH", "org.bouncycastle.jce.provider.symmetric.Blowfish$ECB");
virtualinvoke $r0.<org.bouncycastle.jce.provider.symmetric.Blowfish$Mappings: java.lang.Object put(java.lang.Object,java.lang.Object)>("Cipher.1.3.6.1.4.1.3029.1.2", "org.bouncycastle.jce.provider.symmetric.Blowfish$CBC");
virtualinvoke $r0.<org.bouncycastle.jce.provider.symmetric.Blowfish$Mappings: java.lang.Object put(java.lang.Object,java.lang.Object)>("KeyGenerator.BLOWFISH", "org.bouncycastle.jce.provider.symmetric.Blowfish$KeyGen");
virtualinvoke $r0.<org.bouncycastle.jce.provider.symmetric.Blowfish$Mappings: java.lang.Object put(java.lang.Object,java.lang.Object)>("Alg.Alias.KeyGenerator.1.3.6.1.4.1.3029.1.2", "BLOWFISH");
virtualinvoke $r0.<org.bouncycastle.jce.provider.symmetric.Blowfish$Mappings: java.lang.Object put(java.lang.Object,java.lang.Object)>("AlgorithmParameters.BLOWFISH", "org.bouncycastle.jce.provider.symmetric.Blowfish$AlgParams");
virtualinvoke $r0.<org.bouncycastle.jce.provider.symmetric.Blowfish$Mappings: java.lang.Object put(java.lang.Object,java.lang.Object)>("Alg.Alias.AlgorithmParameters.1.3.6.1.4.1.3029.1.2", "BLOWFISH");
return;
}
](2) Unique results of CongiCrypt
ConstraintError violating CrySL rule for javax.net.ssl.SSLContext
First parameter (with value "SSL") should be any of {TLSv1, TLSv1.1, TLSv1.2}
at statement: $r4 = staticinvoke <javax.net.ssl.SSLContext: javax.net.ssl.SSLContext getInstance(java.lang.String)>("SSL")
ConstraintError violating CrySL rule for javax.net.ssl.SSLContext
First parameter (with value "TLS") should be any of {TLSv1, TLSv1.1, TLSv1.2}
at statement: $r4 = staticinvoke <javax.net.ssl.SSLContext: javax.net.ssl.SSLContext getInstance(java.lang.String)>("TLS")
Operation on object of type javax.net.ssl.SSLContext object not completed. Expected call to init
at statement: $r9 = virtualinvoke $r5.<javax.net.ssl.SSLContext: javax.net.ssl.SSLSocketFactory getSocketFactory()>()