October 4, 2021
Last year, we took a look at the DJI Mimo app used with the company’s Osmo “action camera”. Soon thereafter we read security reports from other companies such as Synactiv’s DJI Go analysis, Synactiv’s DJI Pilot analysis, GRIMM’s validation report. These other security companies looked at the DJI Go and Pilot applications used for controlling drones and they found, among other things, similar results to what we found on DJI Mimo.
Soon after last year’s reports from us and other firms, DJI appeared to remove some of the findings that had been published – such as the Mob SDK which was logging significant amounts of information about user’s devices.
We decided it was time to review the latest version of the DJI Go app to see what else might have changed.
Unfortunately, when we took a brief look around, we discovered some problems, including:
- The DJI Go application implements an auto-update mechanism that subverts some of the controls of the Google Play Store.
- DJI has apparently released several different software packages which are all labeled with the same version number.
- In recent versions available from the DJI update service, the app requests additional permissions compared to the latest version on the Google Play Store.
- The DJI Go application requests signature-level permission. This should not be granted by Android except when DJI is the device vendor.
- Native libraries are being written and executed from data storage. Android native library builds are usually packaged into the APK and are only updated when the APK is updated.
- Some logs are stored unscoped, which makes them accessible to any app or user on the mobile device.
What are the Risks of the Continuous Self-Update Mechanism?
GRIMM’s (July 2020 GRIMM’s July 2020 report described the self-update mechanism as a violation of Google’s Developer Program Policies.
In our investigation of the latest versions, the DJI Go 4 app continues to leverage the
REQUEST_INSTALL_PACKAGES permission and a custom update mechanism in order to install more recent versions outside of the approved version from the Google Play Store. You can see the workflow below, which indicates the update is being done outside the Google Play Store.
We noted in the Google Play store reviews that some users have also noticed this issue:
What Version is Current?
This should be a very easy question to answer, but when we dug in, we immediately ran into a lot of variation. We found four variants of DJI Go 4 v4.3.37 that are all officially signed APKs by DJI (Note this was observed in the latest DJI Go 4, but not DJI Fly). This could cause users to not realize they are on different versions, or could cause package managers such as the Google Play Store to not update users to the latest version available. For example, the latest version available on the Google Play Store is v4.3.37, but on DJI’s website, the latest version is v4.3.42.
Typically, software companies use a method such as semantic versioning to ensure each release is uniquely identified by its version. Instead, DJI sometimes will release an updated version without updating the versionName which is displayed to the users.
In the screenshot below from a Google Play Store review, you can see an example of the confusion that is happening to users as their apps update but versions don’t change:
This presents issues for updating and makes us wonder why the updated versions aren’t available on the Google Play Store. Perhaps the Google Play Store may not have accepted some of the changes made in the newest versions? Or did DJI not submit the updated version to the Google Play Store?
The DJI Fly app, which seems to be a rebranded application for DJI Go 5, is only available via direct download and no longer through the Google Play Store. We were unable to find any references as to why DJI Fly was taken off the Google Play Store. We are curious if anyone has compared the different versions which are all marked with the same version number to see what the variations are.
###How Are Additional Permissions Utilized? When we help a company design a secure product or improve the security of their current ones during penetration testing, we encourage limiting permissions to the minimum required. Android has a well-defined method for apps to perform permission access requests.
When updating the DJI Go app from the Google Play Store (v4.4.37) to the DJI hosted version (v4.3.42), the following permissions were added to the manifest:
Also, the READ_PHONE_STATE permission was added back into the manifest when updating from DJI GO 4 to DJI Fly (Go 5). While the definition of these parameters is provided in Android documentation, a question arises as to what each is needed for. Are they only used for those purposes that the user expects and wants them available for?
- ColorOS (OPPO) specific permission for interfacing with Push Notifications
- CaaS Engine provides open APIs that are based on the HUAWEI MeeTime service. It enables app developers to incorporate voice and video calling into their apps’ social framework (such as contacts and friends) with ease.
- We were unable to determine what this permission does from the available Huawei SDK documentation. We believe ‘msdp’ may stand for Multicast Source Discovery Protocol, for which Huawei has various documentation.
Why Does the Application Request a Signature-Level Permission?
The DJI Go 4 and DJI Fly both request INTERACT_ACROSS_USERS_FULL, which is a signature level permission. To use it, the application would need to be signed by the platform key. The platform key is typically used only for internal system and privileged apps and is generated by the device vendor. However, if some type of bypass exists on the device, this could be granted. Is this only used for Android-based remote hardware made by DJI, or for something else?
Why are Native Libraries Being Written & Executed from Data Storage?
The DJI Go 4 application extracts some native vision libraries to its data storage area, rather than using the standard mechanism 1 for APKs to safely include Java Native Interface (JNI) libraries with their application. The permissions on these libraries are read and write for the DJI Android UID and as such can be updated ad hoc.
We believe that in addition to other update mechanisms that could alert the user, the app (or any app with a shared UID) could silently update the native library extracted to this updatable area to change code at runtime. These libraries are
libduml_vision_panorama.so. (This was observed in the latest DJI Go 4 but not DJI Fly.)
We would be interested if anyone has investigated this or analyzed the library download/update mechanism, or the contents and provenance of these libraries.
-rw------- 1 u0_a261 u0_a261 5618344 2021-05-17 17:16 /data/data/dji.go.v4/files/libs/arm64-v8a/libVision.so -rw------- 1 u0_a261 u0_a261 10187784 2021-05-17 17:16 /data/data/dji.go.v4/files/libs/arm64-v8a/libduml_vision_bokeh.so -rw------- 1 u0_a261 u0_a261 11263128 2021-05-17 17:16 /data/data/dji.go.v4/files/libs/arm64-v8a/libduml_vision_panorama.so -rw------- 1 u0_a261 u0_a261 3320348 2021-05-17 17:16 /data/data/dji.go.v4/files/libs/armeabi-v7a/libVision.so -rw------- 1 u0_a261 u0_a261 8763740 2021-05-17 17:16 /data/data/dji.go.v4/files/libs/armeabi-v7a/libduml_vision_bokeh.so -rw------- 1 u0_a261 u0_a261 7048192 2021-05-17 17:16 /data/data/dji.go.v4/files/libs/armeabi-v7a/libduml_vision_panorama.so
What are in the Log Files? Why are they Stored Unscoped?
On modern mobile operating systems, apps have access to storage that the operating system ensures only the appropriate app can access (“scoped”). This is meant to keep sensitive logs and other data private to the app. Non-scoped external storage is generally discouraged since other apps on the device can access it. The best practices are to save in storage what is only available to your app, or if needed, all apps by one developer (based on signing keys).
From our review of the latest DJI Go app, it appears that DJI uses non-scoped storage of log files, including
person_detection.log. The list of log files is shown below:
/sdcard/DJI/dji.go.v5/LOG/qsmcl/date_05-17-2021: total 32 -rw-rw---- 1 root sdcard_rw 23 2021-05-17 22:46 detector_thread_0.txt -rw-rw---- 1 root sdcard_rw 0 2021-05-17 22:46 fusion_log.txt -rw-rw---- 1 root sdcard_rw 946 2021-05-17 22:46 ltsot_scheduler.txt -rw-rw---- 1 root sdcard_rw 443 2021-05-17 22:46 person_detection.log -rw-rw---- 1 root sdcard_rw 0 2021-05-17 22:46 tracker_log.txt
Further, example log contents includes:
# cat /sdcard/DJI/dji.go.v5/LOG/qsmcl/date_05-24-2021/person_detection.log decrypt_file cost time(ms): 435.106 ################################################################### version num: 1.0 total obj classes: 1 class enum: 2 Loaded model_ /data/user/0/dji.go.v5/files/qs/person_detection.modelsuccess! detector init succeeded! GPU acceleration is used. Applied GPU delegate.init cost time(ms): 2324.75 delegates size: 1 interpreter not NULL: 1 wanted input size, [img_h, img_w, img_c]: 224, 384, 3 output size: 4
It appears that
person_detection.log is associated with ‘qsmcl’ and is a log from some model or other detector. Has anyone investigated the log contents or the behavior of this detection model in depth?
What are the Policy Implications?
We believe this may warrant additional investigation. White House Executive Order 14034 explicitly requires an “evidence-based analysis” approach to protecting Americans’ sensitive data from foreign adversaries. When we read through this Executive Order for additional context, we noticed some of the factors to be considered when evaluating a connected software application include “a lack of thorough and reliable third-party auditing of connected software applications” and “the extent to which identified risks have been or can be addressed by independently verifiable measures”.
We regularly assess commercial products and their connected applications for our customers to determine the security implications and privacy risks of these products, and we use industry standard frameworks along with our unique expertise.
Based on our initial look at the latest DJI Go app, we were unable to verify that the risks raised by multiple research reports have been addressed including: Synactiv’s DJI Go analysis, Synactiv’s DJI Pilot analysis, GRIMM’s validation report, and our analysis of DJI Mimo.
One reason we were unable to verify the risks, is that DJI engages in heavy obfuscation and anti-analysis techniques. We would love to see an app in which independent cyber-security researchers can validate the data being collected and used by the app.
We hope the presentation of these problems will encourage other researchers to dive into these applications in more detail.