Skip to content

VR Overlay RCE

Critical
Natsumi-sama published GHSA-j98g-mgjm-wqph Aug 6, 2024

Package

No package listed

Affected versions

< 2024.03.23

Patched versions

VRCX 2024.03.23

Description

Summary

In VRCX, these two vulnerabilities exist, which results in the remote command execution when combined:

  1. Cross-site scripting via overlay notification
  2. CefSharp browser with over-permission

Mitigation

These vulnerabilities are patched on VRCX 2024.03.23. In addition to the patch, we worked with the VRC team and blocked the older version of VRCX on the VRC's API side.
Users who use the older version of VRCX must update their installation to continue using VRCX.

Technical details

1. Cross-site scripting via overlay notification

In VRCX, there is a feature called Overlay Notification.

This feature lets the user see the VRCX notification while using the HMD.

The following code is used to display the overlay notification:

html/src/vr.js line 495-658

  $app.methods.playNoty = function (json) {
   [...]
   switch (noty.type) {
     case 'OnPlayerJoined':
       text = `<strong>${noty.displayName}</strong> has joined`;
       break;
     case 'OnPlayerLeft':
       text = `<strong>${noty.displayName}</strong> has left`;
       break;
     case 'OnPlayerJoining':
       text = `<strong>${noty.displayName}</strong> is joining`;
       break;
     case 'GPS':
       text = `<strong>${
         noty.displayName
       }</strong> is in ${this.displayLocation(
         noty.location,
         escapeTag(noty.worldName),
         escapeTag(noty.groupName)
       )}`;
       break;
     [...]
   }
   if (text) {
     new Noty({
       type: 'alert',
       theme: this.config.notificationTheme,
       timeout: this.config.notificationTimeout,
       layout: this.config.notificationPosition,
       text: `${img}<div class="noty-text">${text}</div>`
     }).show();
   }
 };

Most user-controllable variables are escaped correctly, and cannot be used to achieve cross-site scripting.

Also, the user's display name cannot contain special characters such as < or >, so it'd be safe usually.

However, VRChat sometimes produces hard-to-parse logs, which allows a malicious user to spoof the display name, bypassing VRChat's restriction.

2. CefSharp browser with over-permission

To execute tasks that require native methods from the CefSharp browser, VRCX exposes the AppApi object.

This object contains some strong methods that allow arbitrary command/code execution.

One of these methods is StartGameFromPath, which accepts the executable path and arguments to be controlled.

Dotnet/AppApi/GameHandler.cs line 114-130

public bool StartGameFromPath(string path, string arguments)
{
  if (!path.EndsWith(".exe"))
    path = Path.Combine(path, "launch.exe");
  if (!File.Exists(path))
    return false;

  Process.Start(new ProcessStartInfo
  {
    WorkingDirectory = Path.GetDirectoryName(path),
    FileName = path,
    UseShellExecute = false,
    Arguments = arguments
  })?.Close();
  return true;
}

While it's impossible to exploit it independently, using the cross-site scripting mentioned above, it's possible to invoke this function with JavaScript like the following:

(async () => {
    await CefSharp.BindObjectAsync('AppApi');
    AppApi.StartGameFromPath('C:/Windows/System32/calc.exe', '');
})();

Severity

Critical

CVE ID

CVE-2024-42366

Weaknesses

No CWEs

Credits