Skip to content

Security

AlexanderR edited this page Nov 11, 2016 · 1 revision

AIDL2 does not produce "secure" code. This is not possible due to nature of aidl and Android Binder protocol. You are supposed to ensure security of your Service binders and other aidl interfaces by using Android permissions and similar forms of access control security. If your aidl interface can be accessed by untrusted code, your application should already be considered compromised.

Here are some bad things, that can happen to your app, when your aidl code is exposed to unreliable/untrusted users:

  1. Some degree of DoS by filling your Binder buffer (can be trivially done by running multiple processes).

  2. Even greater opportunities for DoS by triggering any Java exception, that can be originate from your application code. This includes NullPointerException, ClassCastException and, most notably, OutOfMemoryError (the later can be easily triggered by sending you a "huge" array with Integer.MAX_VALUE number of entries).

  3. Reliable DoS by sending Parcelables/Bundles with file descriptos until your app runs out of free file descriptors (the workaround is available to native Android classes, but is not exported via Java API).

  4. Sending arbitrary input data to your Parcelable creation code. Usually leads to the results, listed in case 2, but can be further abused if your Parcelables are sufficiently complex or used in certain ways.

The issues above are equally applicable both to Android aidl generator and AIDL2. Some of them can be mitigated by copious input validation and ensuring, that Parcel and related classes are safely written, but the biggest one is outside of AIDL2 control. The hugest attack surface lies in code of your Parcelable classes, which would have to be carephully written and warily used to be truly secure. It may, in theory, be possible to create "secure" parsing code selectivly using some of AIDL2 features, but such approach is offitially unsupported by this project.

If you have to embark on that slippery path anyway, beware the following AIDL2 features, which are especially unsafe:

  1. Collections and Maps are created without runtime type checks. This can be used to trigger heap pollution, which may reveal itself later in unexpected places.
  2. Abstract/non-final Parcelables in method signatures can be abused to instantiate completely different Parcelable class with caller-supplied parameters (any Parcelable class would do, as long as it is accessible to your app's ClassLoader).
  3. Even more dangerous variation of previous issue is applicable to Externalizable/Serializable classes. When used in default configuration, ObjectInputStream will gladly instantiate any Serializable/Externalizable class in systemm as well as any class with accessible default constructor.

None of issues, listed so far, can let attacker directly execute their code, but they don't need to — a sufficiently clever attacker can manipulate system classes and your own code to achive rather suprrising results.

A common workaround, used by Android system services so far, is to reverse the the control flow — let application code implement AIDL interface and have "throwaway" system process make calls on that interface. By using carephully written Parcelabe as return type (or, better yet — no return type and oneway Binder calls), one can avoid need to validate/sanitize input data and reduce client's ability to affect other apps by latching onto shared system resources. Among implementations of this strategy are IMEs, WallaperService, app widgets and many others 1.


1: https://developer.android.com/reference/android/app/Service.html#subclasses-direct

Clone this wiki locally