An Empirical Assessment of Security Risks of

Global Android Banking Apps

Overview

To explore the entire mobile banking ecosystem and help to ensure the user’s finance security, in this paper, we take a large number of banking apps as subjects to conduct a comprehensive empirical study on the data-related weaknesses in global Android banking apps. As shown in Figure 1, our study contains three main steps:

(1) we first collect 693 banking apps across 83 countries from various markets, to our knowledge, this is the largest banking app dataset taken into study to date; (2) To collect the weaknesses exhibited in banking apps and complement the capability of existing tools in data-related weakness detection, we first summarize a weakness baseline and propose an automated security risk assessment system (Ausera), which combines static program analysis techniques and sensitive keyword identification, to identify such weaknesses. (3) By applying Ausera, we collected 2,157 security weaknesses in the 693 banking apps, and further conduct a comprehensive empirical study to investigate the ecosystem of banking apps in terms of security weaknesses, aiming to answer the following research questions:

  • RQ1: What is the current status of existing tools towards collecting reliable data-related weaknesses in banking apps compared with Ausera?
  • RQ2: What is the overall security status of banking apps in terms of data-related weaknesses?
  • RQ3: What is the weakness status of banking apps globally w.r.t. economies and regulations?
  • RQ4: How are weaknesses introduced during app evolution and fragmentation?
  • RQ5: What is the gap between academic researchers and banks towards weakness understanding and fixing?

Figure 1: Overview of our study

Figure 2: Overview of Ausera

1. We extract 70 keywords in total from 470 unique banking apps to test, and these keywords can be categoried into 4 categories.

Identity:

  • user, name, username, userid, byname, user-id, user-agent, user-key, 用户名, 登录名, 登陆名, 证件号, 身份证, 昵称,login, sign, signin

Credential:

  • pin, pincode, pinnumber, password, passcode, pwd, passwort, 密码, 密碼

Personal Info:

  • name, firstname, lastname, gender, birthday, birthdate, address, phonenumber, phoneno, mobilenumber, mobileno, email, e-mail, gmail, contact, 姓名, 性别, 生日, 出生,地址,手机,邮箱, 郵箱

Financial Info:

  • creditcard, cardno, cardnumber, debitcard, loancard, cvvcode, depositamount, loanamount, startdate, loanpurpose, balance, income, payment, payee, expiry, message, 卡号, 卡號, 余额, 金额,时间

2. We identify 106 vulnerable sinks in total that are likely to be exploited.

SharedPreference ;

Logging;

SD Card;

SMS

% GUI Data (i.e., input data and server data)

<android.widget.EditText: android.text.Editable getText()> -> _SOURCE_ 

% SharedPreference Sinks

<android.content.SharedPreferences$Editor: android.content.SharedPreferences$Editor putBoolean(java.lang.String,boolean)> -> _SINK_
<android.content.SharedPreferences$Editor: android.content.SharedPreferences$Editor putFloat(java.lang.String,float)> -> _SINK_
<android.content.SharedPreferences$Editor: android.content.SharedPreferences$Editor putInt(java.lang.String,int)> -> _SINK_
<android.content.SharedPreferences$Editor: android.content.SharedPreferences$Editor putLong(java.lang.String,long)> -> _SINK_
<android.content.SharedPreferences$Editor: android.content.SharedPreferences$Editor putString(java.lang.String,java.lang.String)> -> _SINK_
<android.content.SharedPreferences$Editor: android.content.SharedPreferences$Editor putBoolean(java.lang.String,boolean)> -> _SINK_
<android.content.SharedPreferences$Editor: android.content.SharedPreferences$Editor putFloat(java.lang.String,float)> -> _SINK_
<android.content.SharedPreferences$Editor: android.content.SharedPreferences$Editor putInt(java.lang.String,int)> -> _SINK_
<android.content.SharedPreferences$Editor: android.content.SharedPreferences$Editor putLong(java.lang.String,long)> -> _SINK_
<android.content.SharedPreferences$Editor: android.content.SharedPreferences$Editor putString(java.lang.String,java.lang.String)> -> _SINK_

% Logging Sinks

<android.util.Log: int d(java.lang.String,java.lang.String)> -> _SINK_
<android.util.Log: int d(java.lang.String,java.lang.String,java.lang.Throwable)> -> _SINK_
<android.util.Log: int e(java.lang.String,java.lang.String)> -> _SINK_
<android.util.Log: int e(java.lang.String,java.lang.String,java.lang.Throwable)> -> _SINK_
<android.util.Log: int i(java.lang.String,java.lang.String)> -> _SINK_
<android.util.Log: int i(java.lang.String,java.lang.String,java.lang.Throwable)> -> _SINK_
<android.util.Log: int v(java.lang.String,java.lang.String)> -> _SINK_
<android.util.Log: int v(java.lang.String,java.lang.String,java.lang.Throwable)> -> _SINK_
<android.util.Log: int w(java.lang.String,java.lang.Throwable)> -> _SINK_
<android.util.Log: int w(java.lang.String,java.lang.String)> -> _SINK_
<android.util.Log: int w(java.lang.String,java.lang.String,java.lang.Throwable)> -> _SINK_
<android.util.Log: int wtf(java.lang.String,java.lang.Throwable)> -> _SINK_
<android.util.Log: int wtf(java.lang.String,java.lang.String)> -> _SINK_
<android.util.Log: int wtf(java.lang.String,java.lang.String,java.lang.Throwable)> -> _SINK_

% SD Card Sinks

<java.io.OutputStream: void write(byte[])> -> _SINK_
<java.io.OutputStream: void write(byte[],int,int)> -> _SINK_
<java.io.OutputStream: void write(int)> -> _SINK_
<java.io.FileOutputStream: void write(byte[])> -> _SINK_
<java.io.FileOutputStream: void write(byte[],int,int)> -> _SINK_
<java.io.FileOutputStream: void write(int)> -> _SINK_
<java.io.Writer: void write(char[])> -> _SINK_
<java.io.Writer: void write(char[],int,int)> -> _SINK_
<java.io.Writer: void write(int)> -> _SINK_
<java.io.Writer: void write(java.lang.String)> -> _SINK_
<java.io.Writer: void write(java.lang.String,int,int)> -> _SINK_
<java.io.Writer: java.io.Writer append(java.lang.CharSequence)> -> _SINK_
<java.io.OutputStreamWriter: java.io.Writer append(java.lang.CharSequence)> -> _SINK_

% SMS Sinks

<android.telephony.SmsManager: void sendTextMessage(java.lang.String,java.lang.String,java.lang.String,android.app.PendingIntent,android.app.PendingIntent)> android.permission.SEND_SMS -> _SINK_ 
<android.telephony.SmsManager: void sendDataMessage(java.lang.String,java.lang.String,short,byte[],android.app.PendingIntent,android.app.PendingIntent)> android.permission.SEND_SMS -> _SINK_ 
<android.telephony.SmsManager: void sendMultipartTextMessage(java.lang.String,java.lang.String,java.util.ArrayList,java.util.ArrayList,java.util.ArrayList)> android.permission.SEND_SMS -> _SINK_