Information Security 7 min read

Creating a Custom PMD Rule to Detect Sensitive Information in Android Log Output

This article continues a previous guide by demonstrating how to define a complex custom PMD rule that flags Android log statements exposing sensitive data such as device identifiers, process IDs, class names, and file paths, illustrating rule design, AST analysis, example code, and verification steps.

360 Quality & Efficiency
360 Quality & Efficiency
360 Quality & Efficiency
Creating a Custom PMD Rule to Detect Sensitive Information in Android Log Output
In the previous article we used a simple rule example to quickly show how to use PMD custom rules. Now we move on to a more complex example for practice.

I will continue to explain the custom‑rule approach step by step, leaving many details for you to think about and discover.

1. Clarify the rule you want to customize

The rule originates from a development requirement: log files must not contain sensitive information. Based on past code samples, the following fields are considered sensitive:

- pid
- uid
- imei
- classname
- getLocalClassName
- getPackageCodePath
- getPackagePath
- android.os.Process.myPid
- android.os.Process.myUid
- android.os.Process.getUidForName

These include both string literals and methods that retrieve specific fields, mainly related to phone information, class names, and code paths.

2. List all different ways the rule can be violated

Incorrect example code:

public class TestLog{    static Logger Log = Logger.getLogger("log");    static boolean DEBUG = true;    static boolean DEBUG1 = false;    public static void main(String []args){
        Context cont = activity.getApplicationContext();
        String classname = activity.getLocalClassName();
        String pcodeName = cont.getPackageCodePath();        int id= android.os.Process.myPid();
        String pid =String.valueOf(id);
        int uicd= android.os.Process.myUid();
        String uid = String.valueOf(uicd);        int idname= android.os.Process.getUidForName("pay");
        String imei = ((TelephonyManager)getSystemService(TELEPHONY_SERVICE)).getDeviceId();        int bbq=activity.getLocalClassName();

        Log.i("classname", classname); //trigger rule
        Log.i("pcodeName", pcodeName); //trigger rule
        Log.i("pid", pid); //trigger rule 
        Log.i("uid", uid); //trigger rule
        Log.i("imei", imei); //trigger rule
        Log.i("imei", imei.length);
        Log.i("imei", imei.size());
        Log.i("imei:", activity.getLocalClassName()); //trigger rule
        Log.i("imei:", MYUUID);
        Log.i("imei:", imei.toString()); //trigger rule
        Log.i("imei:", ab.imei.toString()); //trigger rule
        Log.i("imei:", bbq); //trigger rule
        Log.i("imei:", idname); //trigger rule
        Log.i("imei:", id); //trigger rule
        Log.i("imei:", uicd); //trigger rule
        Log.i("imei:", pcodeName); //trigger rule
        Log.i("imei:", 101);

        if (DEBUG) {
            Log.i("imei", imei); //trigger rule
        }
        if (DEBUG1) {
            Log.i("imei", imei);
        }
    }
}

In the code I marked the statements that trigger rule so you can see what sensitive data is being logged.

3. Use designer.bat to analyze the AST characteristics of all violations

During the AST analysis phase we need to categorize the offending code patterns:

a. Directly outputting a sensitive string in the log.

b. Outputting a sensitive string after some processing.

c. Logging a variable that was previously assigned a sensitive value.

d. Log statements wrapped by a log‑switch that is true, causing the sensitive data to be emitted.

4. Write the rule code to capture these characteristics

Because the WeChat article limits text length, the rule code is shown as images. To copy the code, click the "Read original" link at the end of the article. You can also refer to the code comments together with step 3 for deeper understanding.

5. Create your own XML rule file with the rule metadata

The previous article already covered how to write the XML file in detail, so it is not repeated here.

6. Run PMD to scan the erroneous code and verify the custom rule

After completing the rule, use the sample code to confirm that the logic works. In practice you should run the rule against a large code base to improve accuracy and reduce false positives.

JavaAndroidStatic AnalysisPMDCustom RuleSensitive Data
360 Quality & Efficiency
Written by

360 Quality & Efficiency

360 Quality & Efficiency focuses on seamlessly integrating quality and efficiency in R&D, sharing 360’s internal best practices with industry peers to foster collaboration among Chinese enterprises and drive greater efficiency value.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.