5

I have an SDK that contains MYSDKActivity. In this activity layout, I have 1 edit text where the user can enter his card number. Any android Client who is integrating this SDK, can use ActivityLifecycleCallbacks in their application class and register text watcher on this edit text and can listen to user card number input.

I want to prevent SDK's edit text usage via the Application class. Only my SDK can access this edit text and perform some action. I want to block usage outside my SDK.

public class MyDemoApp extends Application implements Application.ActivityLifecycleCallbacks {

@Override
public void onCreate() {
    super.onCreate();
    registerActivityLifecycleCallbacks(this);
}

@Override
public void onActivityCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState) {}

@Override
public void onActivityStarted(@NonNull Activity activity) {}

@Override
public void onActivityResumed(@NonNull Activity activity) {
    if (activity instanceof MYSDKActivity) {
        final TextInputLayout textInputLayout = activity.findViewById(R.id.my_sdk_edit_text);
        if (textInputLayout != null) {
            ViewGroup textInputLayoutViewGroup = ((ViewGroup) textInputLayout.getChildAt(0));
            for (int i = 0; i < textInputLayoutViewGroup.getChildCount(); i++) {
                View child = textInputLayoutViewGroup.getChildAt(i);
                if (child instanceof TextInputEditText) {
                    Log.v("USER Input",  ((TextInputEditText) child).getText().toString());
                    ((TextInputEditText) child).addTextChangedListener(new TextWatcher() {
                        @Override
                        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

                        }

                        @Override
                        public void onTextChanged(CharSequence s, int start, int before, int count) {
                            Log.v("USER Input", s.toString());
                        }

                        @Override
                        public void afterTextChanged(Editable s) {}
                    });
                }
            }
        }
    }
}

}

Kishan Maurya
  • 3,356
  • 8
  • 21
  • 2
    Consider not using Android framework widget, use a SurfaceView and render your own keypad / edit field for secure data entry. Assuming you are following [Tapjacking recommendations](https://developer.android.com/topic/security/risks/tapjacking) there still isn't anything preventing reverse engineering your SDK code and having a malicious actor send fraudulent data to your server side, but anyone using your SDK should be registered so why would an SDK integrator be doing bad-actor things? – Morrison Chang Feb 17 '23 at 09:12

1 Answers1

-1

The best way to achieve this

  1. Create a custom layout which doesn't exposes methods like gettext and addTextWatcher.

  2. Never store this data as plain string if you are storing this on the store.(Use encryption).

  • First won't actually work as the malicious client could always access private fields via reflection. Second one is interesting though, but you will have a small amount of time between user entering his data and encryption so it can be accessed at that moment. Still, it narrows the window of opportunity for a malicious actor. – bmaciejm Feb 17 '23 at 13:04
  • IMHO You can disable reflection for the custom view using the SecurityManager in your custom view constructor class for more detail.https://stackoverflow.com/questions/40218973/java-security-manager-completely-disable-reflection – Bhupendra Singh Feb 18 '23 at 15:53
  • On Android it is not true https://developer.android.com/reference/java/lang/SecurityManager - "Security managers do not provide a secure environment for executing untrusted code and are unsupported on Android. Untrusted code cannot be safely isolated within a single VM on Android. Application developers can assume that there's no SecurityManager installed, i.e. System.getSecurityManager() will return null." – bmaciejm Feb 18 '23 at 16:05