CVE-2025-59489: Arbitrary Code Execution in Unity Runtime
Posted on October 3, 2025 • 6 minutes • 1067 words
Table of contents
Introduction
Hello, I’m RyotaK (@ryotkak ), a security engineer at GMO Flatt Security Inc.
In May 2025, I participated in the Meta Bug Bounty Researcher Conference 2025. During this event, I discovered a vulnerability (CVE-2025-59489) in the Unity Runtime that affects games and applications built on Unity 2017.1 and later.
In this article, I will explain the technical aspects of this vulnerability and its impact.
This vulnerability was disclosed to Unity following responsible disclosure practices.
Unity has since released patches for Unity 2019.1 and later, as well as a Unity Binary Patch tool to address the issue, and I strongly encourage developers to download the updated versions of Unity, recompile affected games or applications, and republish as soon as possible.
For the official security advisory, please refer to Unity’s advisory here: https://unity.com/security/sept-2025-01
We appreciate Unity’s commitment to addressing this issue promptly and their ongoing efforts to enhance the security of their platform.
Security vulnerabilities are an inherent challenge in software development, and by working together as a community, we can continue to make software systems safer for everyone.
TL;DR
A vulnerability was identified in the Unity Runtime’s intent handling process for Unity games and applications.
This vulnerability allows malicious intents to control command line arguments passed to Unity applications, enabling attackers to load arbitrary shared libraries (.so
files) and execute malicious code, depending on the platform.
In its default configuration, this vulnerability allowed malicious applications installed on the same device to hijack permissions granted to Unity applications.
In specific cases, the vulnerability could be exploited remotely to execute arbitrary code, although I didn’t investigate third-party Unity applications to find an app with the functionality required to enable this exploit.
Unity has addressed this issue and has updated all affected Unity versions starting with 2019.1. Developers are strongly encouraged to download them, recompile their games and applications, and republish to ensure their projects remain secure.
About Unity
Unity is a popular game engine used to develop games and applications for various platforms, including Android.
According to Unity’s website, 70% of top mobile games are built with Unity. This includes popular games like Among Us and Pokémon GO, along with many other applications that use Unity for development.
Technical Details
Note: During the analysis, I used Android 16.0 on the Android Emulator of Android Studio. The behavior and impact of this vulnerability may differ on older Android versions.
Unity’s Intent Handler
To support debugging Unity applications on Android devices, Unity automatically adds a handler for the intent containing the unity
extra to the UnityPlayerActivity. This activity serves as the default entry point for applications and is exported to other applications.
https://docs.unity3d.com/6000.0/Documentation/Manual/android-custom-activity-command-line.html
adb shell am start -n "com.Company.MyGame/com.unity3d.player.UnityPlayerActivity" -e unity "-systemallocator"
As documented above, the unity
extra is parsed as command line arguments for Unity.
While Android’s permission model manages feature access by granting permissions to applications, it does not restrict which intents can be sent to an application.
This means any application can send the unity
extra to a Unity application, allowing attackers to control the command line arguments passed to that application.
xrsdk-pre-init-library Command Line Argument
After loading the Unity Runtime binary into Ghidra, I discovered the following command line argument:
initLibPath = FUN_00272540(uVar5, "xrsdk-pre-init-library");
The value of this command line argument is later passed to dlopen
, causing the path specified in xrsdk-pre-init-library
to be loaded as a native library.
lVar2 = dlopen(initLibPath, 2);
This behavior allows attackers to execute arbitrary code within the context of the Unity application, leveraging its permissions by launching them with the -xrsdk-pre-init-library argument.
Attack Scenarios
Local Attack
Any malicious application installed on the same device can exploit this vulnerability by:
- Extracting the native library with the
android:extractNativeLibs
attribute set totrue
in the AndroidManifest.xml - Launching the Unity application with the
-xrsdk-pre-init-library
argument pointing to the malicious library - The Unity application would then load and execute the malicious code with its own permissions
Remote Exploitation via Browser
In specific cases, this vulnerability could potentially be exploited remotely although the condition .
For example, if an application exports UnityPlayerActivity
or UnityPlayerGameActivity
with the android.intent.category.BROWSABLE
category (allowing browser launches), websites can specify extras passed to the activity using intent URLs:
intent:#Intent;package=com.example.unitygame;scheme=custom-scheme;S.unity=-xrsdk-pre-init-library%20/data/local/tmp/malicious.so;end;
At first glance, it might appear that malicious websites could exploit this vulnerability by forcing browsers to download .so
files and load them via the xrsdk-pre-init-library
argument.
SELinux Restrictions
However, Android’s strict SELinux policy prevents dlopen
from opening files in the downloads directory, which mitigates almost all remote exploitation scenarios.
library "/sdcard/Download/libtest.so" ("/storage/emulated/0/Download/libtest.so") needed
or dlopened by "/data/app/~~24UwD8jnw7asNjRwx1MOBg==/com.DefaultCompany.com.unity.template.
mobile2D-E043IptGJDwcTqq56BocIA==/lib/arm64/libunity.so" is not accessible for the
namespace: [name="clns-9", ld_library_paths="",default_library_paths="/data/app/~~24UwD8jnw7asNjRwx1MOBg==/com.DefaultCompany.com.unity.template.
mobile2D-E043IptGJDwcTqq56BocIA==/lib/arm64:/data/app/~~24UwD8jnw7asNjRwx1MOBg==/com.DefaultCompany.com.unity.template.mobile2D-E043IptGJDwcTqq56BocIA==/base.apk!/lib/arm64-v8a", permitted_paths="/data:/mnt/expand:/data/data/com.DefaultCompany.com.unity.template.mobile2D"]
That being said, since the /data/
directory is included in permitted_paths
, if the target application writes files to its private storage, it can be used to bypass this restriction.
Furthermore, dlopen
doesn’t require the .so
file extension. If attackers can control the content of a file in an application’s private storage, they can exploit this vulnerability by creating a file containing malicious native library binary. This is actually a common pattern when applications cache data.
For example, another vulnerability in Messenger was exploited using the application’s cache: https://www.hexacon.fr/slides/Calvanno-Defense_through_Offense_Building_a_1-click_Exploit_Targeting_Messenger_for_Android.pdf
Requirements for Remote Exploitation
To exploit this vulnerability remotely, the following conditions must be met:
- The application exports
UnityPlayerActivity
orUnityPlayerGameActivity
with theandroid.intent.category.BROWSABLE
category - The application writes files with attacker-controlled content to its private storage (e.g., through caching)
Even without these conditions, local exploitation remains possible for any Unity application.
Demonstration
Conclusion
In this article, I explained a vulnerability in Unity Runtime that allows arbitrary code execution in almost all Unity applications on Android.
I hope this article helps you understand that vulnerabilities can exist in the frameworks and libraries you depend on, and you should always be mindful of the security implications of the features you use.
Shameless plug
At GMO Flatt Security, we provide top-notch penetration testing for a wide range of targets, from Web apps to IoT devices.
https://flatt.tech/en/professional/penetration_test
We also developed Takumi, our AI security engineer. It’s an autonomous agent that finds vulnerabilities in source code and has already discovered CVEs in major libraries like Vim and Next.js. https://flatt.tech/en/takumi
Recently, we’ve expanded Takumi’s capabilities. It’s no longer just a SAST (white-box testing) tool; we’ve added DAST (black-box testing) to enable high-fidelity gray-box scanning for more accurate results.
Based in Japan, we work with clients globally, including industry leaders like Canonical Ltd.
If you’d like to learn more, please contact us at https://flatt.tech/en