Android provides capabilities for an app to output or obtain log output. Application can send information to log output using android.util.Log class. To obtain log output, application can execute logcat command.
Log output
android.util.Log
|
| |
|
|
|
Example:
Log.v("method", Login.TAG + ", account=" + str1); Log.v("method", Login.TAG + ", password=" + str2);
To obtain log output
Declare READ_LOGS permission in the manifest file so that app can read log output
AndroidManifest.xml
:
<uses-permission android:name="android.permission.READ_LOGS"/>
Call logcat from an application
Process mProc = Runtime.getRuntime().exec( new String[]{"logcat", "-d", "method:V *:S$Bc`W^(B)"}); BufferedReader mReader = new BufferedReader( new InputStreamReader(proc.getInputStream()));
Prior to Android 4.0, any application with READ_LOGS
permission could obtain all the other application's log output. After Android 4.1, the specification of {[READ_LOGS}} permission has been changed. Even applications with READ_LOGS
permission cannot obtain log output from other application.
By connecting an Android device to a PC, however, log output from other application can be obtained.
Therefore application should not send sensitive information to log output.
Noncompliant Code Example
Facebook SDK for Android contained the following code which sends Facebook access token to log output in plain text format.
Log.d("Facebook-authorize", "Login Success! access_token=" + getAccessToken() + " expires=" + getAccessExpires());
Source: http://blog.parse.com/2012/04/10/discovering-a-major-security-hole-in-facebooks-android-sdk/
Noncompliant Code Example
Here is another example. Weathernews Touch for Android sent user's location data to the log output as follows:
I/MySoraPiece( 6483): Re-use MySoraPiece data
I/ ( 6483): GET JSON:
If a user is using Android OS 4.0 or before, other application with READ_LOGS
permission can obtain the user's location information without declaring ACCESS_FINE_LOCATION
permission in the manifest file.
Compliant Solution
An example code of obtaining log output correctly is as follows:
final StringBuilder slog = new StringBuilder(); try { Process mLogcatProc; mLogcatProc = Runtime.getRuntime().exec(new String[] {"logcat", "-d", "LoginAsyncTask:I APIClient:I method:V *:S" }); BufferedReader reader = new BufferedReader(new InputStreamReader( mLogcatProc.getInputStream())); String line; String separator = System.getProperty("line.separator"); while ((line = reader.readLine()) != null) { slog.append(line); slog.append(separator); } Toast.makeText(this, "Obtained log information", Toast.LENGTH_SHORT).show(); } catch (IOException e) { // handle error } TextView tView = (TextView) findViewById(R.id.logView); tView.setText(slog);
Applicability
Applications should make sure that they do not send sensitive info to log output. If the app includes 3rd party library, the developer should make sure that the library does not send sensitive information to log output. One common solution is for an application to declare and use a custom log class, so that log output is automatically turned on/off based on Debug/Release. Developers can use ProGuard to delete specific method call. This assumes that the method contains no side effects.
Related Vulnerabilities
- Facebook SDK for Android: http://readwrite.com/2012/04/10/what-developers-and-users-can#awesm=~o9iqZAMlUPshPu
- JVN#23328321 Puella Magi Madoka Magica iP for Android vulnerable to information disclosure
- JVN#86040029 Weathernews Touch for Android stores location information in the system log file
- JVN#33159152 Loctouch for Android information management vulnerability
- JVN#56923652 Monaca Debugger for Android information management vulnerability
Related Guidelines
Android Seucre Coding Guidebook by JSSEC | 4.8 Output log to LogCat |