Skip to content

Security Independently confirmed3 publishers 2 min read Published Updated

JFrog says a stock Parallels Desktop install hands any local user a root shell

JFrog found that an unprivileged account on a Mac running Parallels Desktop 26.4.0 can reach the root dispatcher over a world-writable socket and run code as uid 0 through argument injection in the appliance installer.

The Watch · Security desk

Send a correction

Illustration accompanying JFrog says a stock Parallels Desktop install hands any local user a root shell
Generated illustration

What happened

  • JFrog found that an unprivileged local user on a Mac running Parallels Desktop 26.4.0, build 57513, on Apple silicon can execute code as root through the prl_disp_service daemon.
  • A quote in the appliance installer's parent-path argument closes the tar command early and injects --use-compress-program=, making macOS tar run the attacker's script as uid 0.
  • None of this needs a running VM, because the launch daemon starts the privileged service at load on a stock install.

Why it matters

  • What's now possible capability Any account already on the host, a coworker login, a CI agent, or resident malware, gains a reliable local escalation to root without admin rights or a Parallels signature.
  • What it limits constraint The payload is a poisoned argv flag rather than a shell metacharacter, so detection rules that watch for shell injection will not catch it.
  • Who has to decide decision Defenders have to treat older builds and the App Store Edition as in scope until a patched build is confirmed, because JFrog did not regression-test them.

The chain has three links. A default install supplies all three. [1]

The dispatcher daemon, prl_disp_service, runs as root because it installs appliances, registers VMs, and starts networking helpers on the host. [2] Its Unix socket at /var/run/prl_disp_service.socket sits at mode 0777, so any process can connect. [3] JFrog tested this on Desktop 26.4.0, build 57513, on Apple silicon. [4] A running VM is not required; the launch daemon starts the service at load. [5]

Authentication is the second link. The login call, PrlSrv_LoginLocal, trusts the peer credentials the kernel supplies for the socket connection: uid, gid, sometimes pid. [6] It does not check a Parallels Team ID, so an unsigned Python client logs in, and a non-admin account logs in the same way. [7] JFrog's proven path works when the daemon reports the caller is not a local administrator. [8]

The third link is the appliance installer. The SDK call PrlSrv_InstallAppliance takes an optional sVmParentPath argument that chooses where the new VM bundle is provisioned. [9] That string flows into a tar command line built with Qt string splitting. [10] A quote in the parent path closes the intended argument early, and the leftover text becomes a --use-compress-program= flag. macOS tar then runs the attacker's script as uid 0. [11]

This is argument injection. There is no /bin/sh in the path, so metacharacters like a semicolon do nothing. [12] The payload is a feature flag of the child binary, tar's own --use-compress-program, which names a program tar will execute. [13]

JFrog did not regression-test older builds for the writeup. It said to treat any Desktop install that still exposes the same InstallAppliance extract template and the world-writable dispatcher socket as in scope. [14] The App Store Edition may start its services differently, but JFrog said the core risk is the same class of root helper IPC. [15]

To check exposure, read the socket mode and the product version. [17] If the socket is srwxrwxrwx and Desktop is at or near 26.4.0 build 57513, JFrog says to assume exposure until a patched build is confirmed. [18] The company noted the tool sits on a large number of developer and enterprise Macs. [16]

What to watch

  • A patched Parallels build that tightens the socket permissions or adds Team ID validation on PrlSrv_LoginLocal, and a CVE assignment.
  • Confirmation of whether builds older than 26.4.0 and the App Store Edition expose the same extract template and socket mode.
  • Any in-the-wild use of the chain as a post-compromise escalation step on developer or enterprise Mac fleets.

Clarity's read

What the record supports and how the coverage leans. The claims behind it follow.

Reality

Evidence80
Adoption42
Hype gap+10
Incentives55
Confidence76

Perspective Coverage

3 publishers
Builder
Builder 34%
Operator
Operator 48%
Investor
Investor 18%
Why these scores

Claim ledger

Ranked by verification strength, evidence, and original report placement.

  1. [1]

    ParaShells needs three things a normal Parallels Desktop install already provides by default.

    Reported SupportedView cited source
  2. [2]

    prl_disp_service is the privileged host daemon behind Parallels Desktop; it installs appliance packages, registers VMs, and starts networking helpers, and runs as root because those jobs touch host networking and archives as root.

    Reported SupportedView cited source
  3. [3]

    Local clients connect to /var/run/prl_disp_service.socket, whose mode is srwxrwxrwx (0777), so any process can connect.

    Reported SupportedView cited source
  4. [4]

    JFrog found the issue while testing Parallels Desktop 26.4.0, build 57513, on Apple silicon (macOS arm64).

    Reported SupportedView cited source
  5. [5]

    A running VM is not required; on a stock install the launch daemon starts prl_disp_service at load.

    Reported SupportedView cited source
  6. [6]

    PrlSrv_LoginLocal authenticates using peer credentials from the kernel, typically uid, gid, and sometimes pid.

    Reported SupportedView cited source
  7. [7]

    There is no Parallels Team ID validation for the login call, so PrlSrv_LoginLocal succeeds for an unsigned Python client and the same login works for a non-admin user.

    Reported SupportedView cited source
  8. [8]

    The proven path works when PrlUsrCfg_IsLocalAdministrator reports 0, that is, when the caller is not a local administrator, and no Parallels code signature is required on the client.

    Reported SupportedView cited source
  9. [9]

    The SDK exposes PrlSrv_InstallAppliance(hServer, hAppCfg, sVmParentPath, nFlags); the optional sVmParentPath string chooses where the new VM bundle is provisioned.

    Reported SupportedView cited source
  10. [10]

    The appliance unpack path builds tar arguments using Qt string splitting.

    Reported SupportedView cited source
  11. [11]

    A quote in the parent path injects --use-compress-program=, and macOS tar runs the attacker's script as uid 0.

    Reported SupportedView cited source
  12. [12]

    The exploit is argument injection, not classic command injection: there is no shell, so tokens like a semicolon and id do nothing useful.

    Reported SupportedView cited source
  13. [13]

    In argument injection the payload is a feature flag of the child binary, here macOS tar.

    Reported SupportedView cited source
  14. [14]

    JFrog did not regression-test every older build and said to treat any Desktop install that still exposes the same InstallAppliance extract template and world-writable dispatcher socket as in scope.

    Reported SupportedView cited source
  15. [15]

    The App Store Edition may differ in how services start, but JFrog said the core risk is the same class of root helper IPC.

    Reported SupportedView cited source
  16. [16]

    Parallels Desktop is on a large number of developer and enterprise Macs.

    Reported SupportedView cited source
  17. [17]

    JFrog's detection guidance is to read the product version and check whether /var/run/prl_disp_service.socket is world-writable.

    Reported SupportedView cited source
  18. [18]

    If the socket mode is 0777 (srwxrwxrwx) and Desktop is at or near 26.4.0 (57513), JFrog says to assume exposure until a patched build is confirmed.

    Reported SupportedView cited source

Sources

3 independent publishers whose own reporting we read for this story.

  1. helpnetsecurity.com

    1 article · September 16, 2026

    Parallels Desktop flaw hands any local user root on a Mac (CVE-2026-90894)
  2. jfrog.com

    1 article · September 15, 2026

    ParaShells: Parallels Desktop Turns Appliance Install Into a Root Shell
  3. thecyberexpress.com

    1 article · September 17, 2026

    New Parallels Desktop Flaw Lets Local Users Seize Root Control of Macs

Topics and entities

Entities

  • JFrog
  • Yuval Moravchick
  • prl_disp_service
  • Parallels Desktop