Recipe Name:
Code Injection: Prevent use of DexClassLoader
Description:
Do not use the DexClassLoader to dynamically load code
Level:
error
Language:
  • java
Tags:
  • security
  • framework specific
  • mobile
  • Android
Documentation

Dynamically loading code from unknown sources is not recommended. This can lead to remote code injection. Also note that dynamically loading code from a known location but over an unsafe connection can result in attacks (i.e., the downloaded code can be tampered with). Similarly, dynamic installation of APK files should be prevented.

Prevent writing code which can dynamically execute code from other sources. Dynamically loading APK files is also discouraged. This functionality will usually fail since this is a settings option that is disabled by default for security reasons.

Either remove the offending code or use a third-party library such as Grab-n-Run which offers secure dynamic loading of code. A secure code example which uses Grab-n-Run is given below.

Correct code example
String jarContainerPath = "some.apk";
try {
  Map<String, URL> packageNamesToCertMap = new HashMap<String, URL>();
  packageNamesToCertMap.put("com.example", new URL("certificate.pem"));
  SecureLoaderFactory mSecureLoaderFactory = new SecureLoaderFactory(this);
  SecureDexClassLoader mSecureDexClassLoader = mSecureLoaderFactory.createDexClassLoader(
    jarContainerPath,null,getClass().getClassLoader(), packageNamesToCertMap);
  Class<?> loadedClass = mSecureDexClassLoader.loadClass("com.example.MyClass");
} catch (...) {
  ...
}
Resources
Recipe
id: scw:android:DexClassLoader
version: 10
metadata:
  name: 'Code Injection: Prevent use of DexClassLoader'
  shortDescription: Do not use the DexClassLoader to dynamically load code
  level: error
  language: java
  enabled: true
  descriptionFile: Storage/descriptions/java_android_avoid_dynamically_loading_code.html
  tags: security;framework specific;mobile;Android
search:
  instanceCreation:
    type: dalvik.system.DexClassLoader
availableFixes:
- name: Use Grab'n Run's Secure Loader
  actions:
  - rewrite:
      to: "java.lang.String jarContainerPath = \"PATH_TO_JAR\";\njava.util.Map<java.lang.String, java.net.URL> packageNamesToCertMap = new java.util.HashMap<java.lang.String, java.net.URL>();\ntry {\n\tpackageNamesToCertMap.put(\"PACKAGE_NAME\", new java.net.URL(\"CERTIFICATE_OF_PKG.pem\"));\n} catch (java.net.MalformedURLException e) {\n\te.printStackTrace();\n}\nit.necst.grabnrun.SecureLoaderFactory mSecureLoaderFactory = new it.necst.grabnrun.SecureLoaderFactory(this);\nit.necst.grabnrun.SecureDexClassLoader mSecureDexClassLoader = mSecureLoaderFactory.createDexClassLoader(\n\tjarContainerPath,\n\tnull,\n\tgetClass().getClassLoader(),\n\tpackageNamesToCertMap);\ntry {\n\tjava.lang.Class<?> loadedClass = mSecureDexClassLoader.loadClass(\"PKG_NAME.CLASSNAME\");\n} catch (ClassNotFoundException e) {\n\t//handle exception\n}"
- name: Remove DexClassLoader object
  actions:
  - rewrite:
      to: ""