top of page

A Malicious npm 'AI Copilot' Still Asks Windows 11 Users for Admin, Four Days After It Was Exposed. A Missing Backslash Blunts It.

Writer: Patrick Duggan
Patrick Duggan
37 minutes ago
6 min read
A Malicious npm 'AI Copilot' Still Asks Windows 11 Users for Admin, Four Days After It Was Exposed. A Missing Backslash Blunts It.

Four days after Elastic Security Labs published a teardown of a malicious npm package that poses as an AI coding assistant, the package is still on npm, still has no record in the open-source vulnerability database most tools check, and on Windows 11 it still pops a request for administrator rights before it does anything else.


What it wants those rights for is to switch off two Windows defenses. It fails, at least in the current version. The reason is not a patch or a takedown. The author forgot to escape six backslashes.



Who found what


The research belongs to Elastic. On October 12, Elastic researchers Jia Yu Chan and Daniel Stepanic published REF8801, "Auditing the auditor: Unmasking Apex Accelerator". They tied two npm packages, @apexacc/cli and @apexacc/audit, to a fake Web3 accelerator that lures crypto founders with free AI credits. They showed the CLI reroutes an AI coding agent's model traffic to the attacker and plants an attacker-controlled MCP server. We wrote up what that means for defenders yesterday. Read Elastic first. Everything about the campaign itself is theirs.


This post covers one narrower thing: what the version you would get from npm today actually does, read line by line, and how it got that way.



What is live on npm right now


On October 16 the npm registry still served @apexacc/cli, latest version 1.6.2, published September 27 by a maintainer account named "apexaccelerator." The account has pushed 122 versions since the first one on August 9. The companion @apexacc/audit is gone from the registry. A query to OSV, the free vulnerability database that a lot of security tooling relies on, returned an empty answer for both names.


The package's README tells users: "No file contents are transmitted without your explicit action." Elastic's analysis says otherwise.


I downloaded the 1.6.2 tarball and read it without running it. It is tiny: four files, and the part that runs is a launcher of about 4KB. The tarball's SHA-256 is 7ca5e3908dd8721d0cf6af2488f0825c0d91a5e0b7c8529ef830141a4a3ba31f. The one file that matters is apex.cjs, SHA-256 4029192a44ee738deba9aa53b57550075cb8fd170a63f0636dea5452256f2175, a 112-line launcher wired up as the package's apex command.


There is no install script. Nothing happens at npm install. It runs when someone runs the tool, for example with npx @apexacc/cli. Then, in order, before it downloads anything:


On any Windows machine, it sets the PowerShell execution policy for the current user to RemoteSigned. No admin rights needed. That change lands.


On Windows 11 (build 22000 or later), it starts a hidden PowerShell window that asks for elevation through the normal User Account Control prompt, carrying its commands as a base64 EncodedCommand. The user sees a UAC prompt. If they click Yes, the elevated commands run.


Those commands are meant to add a Microsoft Defender exclusion for the user's .apex folder and set the registry value VerifiedAndReputablePolicyState to 0 under HKLM\SYSTEM\CurrentControlSet\Control\CI\Policy. That value is the switch for Smart App Control, the Windows 11 feature that blocks untrusted and unsigned apps.


Only after all that does it try to download its real payload, a binary the launcher itself calls "~105MB," from the GitHub releases of a repository named apexaccs/copilot, into a hidden .apex\bin folder in the user's home directory. On macOS it also fetches a helper called apex-verify-darwin. Today that repository returns 404, as does the earlier repository the package used, Apex-Accelerator/apexcli. The payload host is dead.





The backslash


The elevated commands are written inside a JavaScript template literal, the backtick-quoted string type, with single backslashes. JavaScript treats a backslash in front of an ordinary letter as an escape that means nothing and silently drops it. I checked the raw bytes of the file: every backslash in that block is single, and there is not one doubled backslash anywhere in it.


So by the time the string reaches PowerShell, the Defender exclusion path has become C:\Users\yourname.apex, a sibling of your home folder rather than the .apex folder inside it. The registry key has become HKLMSYSTEMCurrentControlSetControlCIPolicy, which is not a valid key, so the Smart App Control change should fail. Both commands run in a hidden window with errors suppressed, so nobody sees them fail.


I want to be exact about the limits here. I reproduced the escaping behavior with my own test string in Node.js. I did not run the package on Windows. What reg.exe and Defender do with those mangled values is inferred from the code, not observed.



How it got that way


The npm registry keeps every version, so the history is readable. I scanned all 122 tarballs for the Smart App Control code. It shows up in six.


On September 17 at 08:19 UTC, version 1.5.120 added the registry change. Seven minutes later, 1.5.121 added the Defender exclusion. Both were escaped correctly, with doubled backslashes, but they ran without asking for elevation. The author's own code comment says "if running as admin." Writing to HKLM and adding a Defender exclusion both need admin rights, so on a normal user session those attempts should have failed, while from a terminal that was already running as administrator they would have worked.


Ninety seconds after that, at 08:27 UTC, version 1.5.122 rewrote the block to request elevation through UAC, which fixed the permissions problem, and moved the commands into the template literal, which broke the paths. Version 1.6.0 on September 18, 1.6.1 (the version Elastic analyzed) and 1.6.2 carry the same broken block. Version 1.6.2 added the execution-policy line.


Elastic's report describes the UAC prompt, the Defender exclusion and the Smart App Control change in the companion @apexacc/audit package. The CLI launcher carries its own copy.



What we did, and when


Our free pre-install check, check-package, has answered BLOCK for both packages since October 15 at 13:54 UTC. That is three days after Elastic published. We were late, and there is no lead to claim here.


Today we filed both packages with the OpenSSF malicious-packages project, which feeds OSV, in pull request 1644. Its validation checks pass. It is not merged yet, so the packages are filed, not listed. We also emailed npm's security team with the evidence. As a test, our new GitHub Action failed a pull request that added @apexacc/[email protected] and allowed one that added left-pad.



What to check


If anyone in your organization ran @apexacc/cli on Windows, look for these:


A .apex folder in the user's profile (%USERPROFILE%\.apex on Windows, ~/.apex on macOS).


Defender exclusions. In an elevated PowerShell, run Get-MpPreference and read ExclusionPath. Look for both the .apex folder and the mangled sibling path ending in yourname.apex.


Smart App Control state, under Windows Security, App & browser control. Anyone who ran version 1.5.120 or 1.5.121 from an administrator terminal may have had it switched off for real.


The PowerShell execution policy. Run Get-ExecutionPolicy -List and look for RemoteSigned at CurrentUser that nobody chose.


npm and npx history for @apexacc on developer machines and CI runners.


Then use Elastic's indicator list as the source of truth for the network side. And treat any "accelerator" that wants you to run its own AI tooling for free credits as the lure it is.



Why this matters


A dead payload server is not a dead package. On Windows 11 today, this one still asks for admin rights, and on any Windows machine it still changes a security setting without asking. The publisher account is live. Fixing the bug means doubling six backslashes and publishing version 1.6.3.


The defense-weakening step is independent of the payload. It runs first, it is meant to clear the way for whatever comes next, and whatever comes next can be pointed at a new host.


And the public lists lag the research. Four days after a major vendor published, OSV had nothing for either package. A clean answer from a free registry means nobody has filed it yet. It does not mean the package is safe.



How we checked this post


I counted 46 checkable claims in this post. I checked 42 of them myself on October 16 against the npm registry, the tarballs, OSV, GitHub, Elastic's report and our own check-package. The other 4 rest on our internal records or on general Windows knowledge: the 13:54 UTC time our check started blocking, the email to npm, the GitHub Action test, and the fact that HKLM writes and Defender exclusions need admin rights.


Three things changed between the working notes and this post. The working version of the story said the package still switches off Windows defenses; reading the bytes showed it tries and, as shipped, fails. A payload size carried over from notes was 114MB; the launcher says about 105MB. And I first wrote that the fix was two characters; it is six backslashes. At least 5% of what remains is still wrong, and I don't know which.


Was this useful? Rate this post with the widget at the bottom of the page. We read every response.




How do AI models see YOUR brand?

AIPM has audited 250+ domains. 15 seconds. Free while still in beta.



Was this useful? Thirty seconds, no cookies, no tracking, no third parties, your address hashed and never stored. If the box below does not load, the same question lives at https://analytics.dugganusa.com/nps.html?post=a-malicious-npm-ai-copilot-still-asks-windows-11-users-for-admin-four-days-after-it-was-exposed



Comments

Rated 0 out of 5 stars.
No ratings yet

Add a rating
bottom of page