Typosquatted Microsoft AI packages harvest developer credentials
How attackers weaponised typosquatted Microsoft AI tooling to harvest OpenAI, HuggingFace, AWS, and Azure credentials from developer workstations.
Multiple campaigns over the past quarter have weaponised Microsoft-stewarded open-source projects to harvest credentials from AI development workstations. The pattern is consistent. Typosquatted or trojanised packages imitating Microsoft AI tooling - AutoGen, Semantic Kernel, promptflow, the VS Code AI Toolkit - landing on developer machines through PyPI, npm, and the VS Code Marketplace. Once executed, the implant enumerates credential stores specific to AI work: HuggingFace tokens at ~/.cache/huggingface/token, OpenAI keys in shell rc files, Azure OpenAI deployment keys in .env, Weights and Biases tokens at ~/.netrc, AWS credentials at ~/.aws/credentials, and browser session cookies for huggingface.co, wandb.ai, and platform.openai.com. Exfiltration over HTTPS to attacker-controlled infrastructure fronted by Cloudflare Workers. CWE-506 - embedded malicious code. CWE-829 - inclusion of functionality from untrusted control sphere. MITRE T1195.002 for the supply chain compromise, T1552.001 for the file-system credential read, T1539 for the cookie theft.
The bug class is not a memory-corruption bug. It is a trust-boundary failure at the package-registry layer. PyPI, npm, and the VS Code Marketplace permit publication under namespaces visually adjacent to legitimate Microsoft projects. autogen-agentchat is the real package. autogen_agentchat is not. semantic-kernel is real. semantic-kernels is not. promptflow-tools is real. promptflow_tools is not. The substitution is a single character, a separator swap, a pluralisation. The registries do not enforce homograph protection at publish time. They do not require organisational verification for namespaces that overlap with widely-known Microsoft repos. The same model applies to the VS Code Marketplace, where publisher IDs are assigned first-come and the only verification gate is a Microsoft account. A publisher named MS-AI-Toolkit will render in the marketplace UI next to Microsoft if the user is scanning visually. Display-name collision is not blocked.
The exploitation path begins at install. A developer types pip install autogen_agentchat instead of autogen-agentchat. The malicious package executes setup.py at install time, which is arbitrary code execution by design. The script writes a stager to ~/.local/share/ under a name that mimics a Python cache directory. The stager registers a launchd or systemd-user unit for persistence - MITRE T1543.001 or T1543.002 depending on host. On first execution, it reads environment variables exported by the developer’s shell. OPENAI_API_KEY, ANTHROPIC_API_KEY, AZURE_OPENAI_API_KEY, HUGGINGFACE_TOKEN, WANDB_API_KEY, HF_TOKEN. It walks the home directory for .env files and parses them as KEY=VALUE. It reads ~/.aws/credentials, ~/.azure/credentials, ~/.config/gh/hosts.yml for GitHub tokens, and ~/.docker/config.json for registry credentials. Each file is hashed, base64-encoded, and POSTed to a collector endpoint in a single request structured to look like telemetry. Content-Type application/json. User-Agent string that mimics pip’s own.
The second-stage primitive is session theft. The implant locates Chromium-family browser profiles - Chrome, Edge, Brave, Arc - and reads the encrypted cookie store. On Windows, decryption keys are protected by DPAPI bound to the user SID, which means the running implant in the user’s context can decrypt them through CryptUnprotectData against Local State. On macOS, the keychain entry Chrome Safe Storage is queryable from the user session and yields the AES key. Cookies for huggingface.co, wandb.ai, platform.openai.com, portal.azure.com, and github.com are extracted. Session cookies carry the authenticated session without requiring the password or the second factor. T1539. The attacker imports the cookies into a headless Chromium and is logged in as the developer. MFA was performed already. The session does not re-prompt.
The attacker now has API keys that bill against the developer’s organisation. They have a logged-in HuggingFace session that can publish models, push to private spaces, and read access tokens. They have a logged-in GitHub session that can read private repos, create personal access tokens, and push to any repo the user has write access to. The pivot is from developer workstation to organisation-scale impact. The AI dev surface is high-value because the credentials touch paid inference quotas, proprietary model weights, training data buckets, and CI/CD systems that fine-tune and ship models. A stolen OpenAI key with a high spend cap is monetised through reseller-bot networks within hours. A stolen HuggingFace token with write access to a popular space is used to host a malicious model that pulls in the next victim. The compromise compounds.
Real-world activity ties to two clusters. The first is consistent with low-skill financially-motivated operators harvesting API keys for resale - the same actors who have run npm-typosquat campaigns against the broader JavaScript ecosystem since 2022. The second cluster shows more discipline: selective targeting of repositories that touch frontier model fine-tuning, deliberate avoidance of antivirus-triggering payloads, and use of legitimate cloud telemetry endpoints - including Azure Application Insights ingestion URLs - as exfiltration cover. That second cluster overlaps in tradecraft with reporting against groups tracked under names including UNC-class designators in vendor reporting and ShinyHunters-adjacent activity in commodity-credential markets. Attribution beyond cluster overlap is not established.
Telemetry from this attack chain is uneven. The install step is loud if you are looking for it. pip install against a typosquat will produce a process tree where python spawns pip, which spawns python setup.py, which writes files under ~/.local/share/ and registers a persistence unit. Sysmon Event ID 1 captures the process creation. Sysmon Event ID 11 captures the file write. Sysmon Event ID 13 captures the registry write if Windows. On macOS, EndpointSecurity events ES_EVENT_TYPE_NOTIFY_EXEC and ES_EVENT_TYPE_NOTIFY_WRITE cover the equivalent. EDRs catch this if the rules look at package-manager-spawned writes outside expected install prefixes. Many do not. The credential-read step is quieter. Reading ~/.aws/credentials from a Python process is not anomalous on a developer workstation - the AWS SDK does it on every boto3 call. The signal is the combination: the same process reading ~/.aws/credentials, ~/.huggingface/token, browser cookie stores, and .env files within a short window, followed by an outbound HTTPS POST. That correlation is rarely written as a detection because it requires file-read auditing turned on for user home directories, which most endpoint policies do not enable.
The browser cookie theft has a specific tell on Windows. A non-browser process calling CryptUnprotectData against Local State of a Chromium profile is high-fidelity. Microsoft Defender for Endpoint surfaces this under the Sensitive credential memory access category when configured to monitor browser data access. Sysmon Event ID 10 with the target process being a Chromium-family executable and the source being anything else is a strong correlation rule. Few SIEM deployments have this rule live. On macOS, keychain access from outside the owning application produces a securityd log entry - visible if log stream --predicate 'subsystem == "com.apple.securityd"' is being captured, which it typically is not.
Network telemetry catches the exfiltration if egress goes anywhere unusual. The attackers know this. The collectors fronted by Cloudflare Workers terminate TLS at a domain that resolves to Cloudflare IP space, which is on every allowlist in every enterprise. The destination IP looks like every other Cloudflare-fronted service the developer talks to. Without TLS inspection and without domain reputation that flags newly-registered Workers subdomains, the egress is invisible. The detection that does fire is volume: a Python process making a single large POST to a domain not seen before from that host. Behavioural network rules catch this. Signature rules do not.
The technical reality is that none of this required a CVE in Microsoft code. The Microsoft projects themselves are not exploited. The exploitation is of the trust boundary around them - the assumption that a package named like AutoGen is AutoGen, that a marketplace publisher named like Microsoft is Microsoft, that a pip install of a tool referenced in a Microsoft tutorial pulls a Microsoft-signed artifact. None of those assumptions are enforced by the registries. Patch boundary is not meaningful here because there is nothing in Microsoft’s codebase to patch. The residual exposure is structural: any developer workstation with API keys in environment variables and authenticated browser sessions to AI platforms is one typosquat install away from full credential compromise. The control that breaks the chain is artifact pinning by hash, publisher verification enforced at install time, and removal of long-lived API keys from developer environments in favour of short-lived federated credentials. Those controls exist. They are rarely deployed on the workstations where the keys actually live.
See also: NordVPN for tunneled traffic when operating outside controlled networks.
#ad Contains an affiliate link.
Keep Reading
prompt-injectionThe chatbot answered the door for attackers
Meta's Instagram chatbot abuse case is a prompt injection and confused deputy failure. Technical breakdown of the vector, telemetry gap, and residual exposure.
github-securityMegalodon hijacked 55,000 GitHub repos via token replay
Megalodon compromised 55,000+ GitHub repositories through PAT harvesting, pull_request_target abuse, and OAuth scope inheritance. Technical breakdown.
supply-chainYour valid credentials are the breach.
Technical analysis of a coordinated GitHub Actions workflow compromise across 5,561 repositories, with detection guidance for audit log and EDR telemetry.
Stay in the loop
New writing delivered when it's ready. No schedule, no spam.