Android clipboard sensitive information disclosure vulnerability solution: disable the copy and paste function of EditText

Keywords: Android

Any third-party software in Android can access the content of the clipboard. Although the high version imposes access restrictions on the clipboard, we still need to take care of the lower version. Let's talk about the solution below.

1. Custom nomunedittext inherits from AppCompatEditText

2. Override the isSuggestionsEnabled method and return false

Create the canPaste() method and return false. This method is a hidden method

3. Implementation ActionMode.Callback Callback

 private class ActionModeCallbackInterceptor implements ActionMode.Callback {

        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
            return false;
        }

        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
            return false;
        }

        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
            return false;
        }

        public void onDestroyActionMode(ActionMode mode) {
        }
    }

4. Set callback

      this.setLongClickable(false);
        //this.setTextIsSelectable(false);
        this.setCustomSelectionActionModeCallback(new ActionModeCallbackInterceptor());
        //Using this method, you can basically disable the paste copy function, and above 6.0 is available
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            this.setCustomInsertionActionModeCallback(new ActionModeCallbackInterceptor());
        }

You can disable the copy and paste function of EditText by using the above methods. However, if you press and hold the text in EditTeit control, the cursor will change, and this method can only be used in version 6.0 or above. If you can't meet your needs in the following ways:

1. Steps 2 and 3 are the same as above, and step 4 is no longer used this.setCustomInsertionActionModeCallback(new ActionModeCallbackInterceptor()) method.

Use the following method (reflection) instead:

 this.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                NoMenuEditText.this.clearFocus();
                return false;
            }
        });
@SuppressLint("ClickableViewAccessibility")
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            // setInsertionDisabled when user touches the view
            this.setInsertionDisabled();
        }
        return super.onTouchEvent(event);
    }

    private void setInsertionDisabled() {
        try {
            Field editorField = TextView.class.getDeclaredField("mEditor");
            editorField.setAccessible(true);
            Object editorObject = editorField.get(this);

            @SuppressLint("PrivateApi") Class editorClass = Class.forName("android.widget.Editor");
            Field mInsertionControllerEnabledField = editorClass.getDeclaredField("mInsertionControllerEnabled");
            mInsertionControllerEnabledField.setAccessible(true);
            mInsertionControllerEnabledField.set(editorObject, false);
        } catch (Exception ignored) {
        }
    }

Using this method can solve the version compatibility problem of the first method, and long press the text cursor in the EditText control will not have any change, which perfectly solves the problem of sensitive information disclosure of the clipboard. I hope the above plan will help you.

Please read the following complete code (don't forget to like it)

@SuppressLint("NewApi")
public class NoMenuEditText extends AppCompatEditText {
    private final Context context;

    /**
     * This method is hidden
     */
    boolean canPaste() {
        return false;
    }

    @Override
    public boolean isSuggestionsEnabled() {
        return false;
    }

    public NoMenuEditText(Context context) {
        super(context);
        this.context = context;
        init();
    }

    public NoMenuEditText(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
        init();
    }

    public NoMenuEditText(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        this.context = context;
        init();
    }

    @SuppressLint("ClickableViewAccessibility")
    private void init() {
        this.setLongClickable(false);
        //this.setTextIsSelectable(false);
        this.setCustomSelectionActionModeCallback(new ActionModeCallbackInterceptor());
        //Using this method, you can basically disable the paste copy function, and above 6.0 is available
//        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
//            this.setCustomInsertionActionModeCallback(new ActionModeCallbackInterceptor());
//        }
        this.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                NoMenuEditText.this.clearFocus();
                return false;
            }
        });
    }

    @SuppressLint("ClickableViewAccessibility")
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            // setInsertionDisabled when user touches the view
            this.setInsertionDisabled();
        }
        return super.onTouchEvent(event);
    }

    private void setInsertionDisabled() {
        try {
            Field editorField = TextView.class.getDeclaredField("mEditor");
            editorField.setAccessible(true);
            Object editorObject = editorField.get(this);

            @SuppressLint("PrivateApi") Class editorClass = Class.forName("android.widget.Editor");
            Field mInsertionControllerEnabledField = editorClass.getDeclaredField("mInsertionControllerEnabled");
            mInsertionControllerEnabledField.setAccessible(true);
            mInsertionControllerEnabledField.set(editorObject, false);
        } catch (Exception ignored) {
        }
    }

    /**
     * Prevents the action bar (top horizontal bar with cut,copy,paste,etc.)
     * from appearing by intercepting the callback that would cause it to be
     * created,and returning false.
     */
    private class ActionModeCallbackInterceptor implements ActionMode.Callback {

        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
            return false;
        }

        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
            return false;
        }

        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
            return false;
        }

        public void onDestroyActionMode(ActionMode mode) {
        }
    }
}

reference resources: https://stackoverflow.com/questions/41673185/disable-edittext-context-menu

Posted by lnt on Mon, 29 Jun 2020 22:10:56 -0700