{"slug": "withgoogle-stitch-sdk-scope-squat-harvests-developer-credentials", "title": "@withgoogle/stitch-sdk: Scope Squat Harvests Developer Credentials", "summary": "A malicious npm package named @withgoogle/stitch-sdk impersonates Google's Stitch AI design tool by squatting the @withgoogle scope, harvesting developer credentials from eight sources via a preinstall hook and CLI binary, and exfiltrating them to an attacker-controlled domain. The package recorded 87 downloads on its first day, targeting credentials from Claude Code, git config, SSH keys, GitHub CLI, npm config, and Docker config.", "body_md": "# @withgoogle/stitch-sdk: Scope Squat Harvests Developer Credentials\n\n### Table of Contents\n\n## TL;DR\n\nA malicious npm package published under `@withgoogle/stitch-sdk`\n\nimpersonates Google’s [Stitch AI design tool](https://stitch.withgoogle.com) by squatting the `@withgoogle`\n\nnpm scope. On install, the package silently harvests developer credentials from eight sources and exfiltrates them to an attacker-controlled domain. The credential harvester runs via a `preinstall`\n\nhook (triggered by `npm install`\n\n) and is duplicated in the CLI binary (`bin/cli.js`\n\n), giving the attacker two independent execution paths. The code is clean, readable JavaScript with no obfuscation. The attacker relies entirely on the trust implied by the `@withgoogle`\n\nscope name rather than hiding the payload.\n\n**Impact:**\n\n- Credentials harvested from Claude Code, git config,\n`~/.git-credentials`\n\n, SSH public keys, GitHub CLI, npm config,`~/.npmrc`\n\n, and`~/.docker/config.json`\n\n- All stolen data exfiltrated via HTTPS GET to\n`hxxps://stitch-production[.]org/api/v1`\n\n- TLS certificate validation disabled on all outbound requests\n- 87 downloads recorded on the first day of publication (June 19, 2026)\n\n**Indicators of Compromise (IoC):**\n\n| Indicator | Value |\n|---|---|\n| Package | `@withgoogle/stitch-sdk` v0.1.1, v0.1.2 |\n| npm maintainer | `maximus-mcmillan` (\n|\n| C2 domain | `stitch-production.org` |\n| C2 IPs (Cloudflare) | 172.67.189.185, 104.21.65.94 |\n| Exfil pattern | `GET /api/v1?src=<source>&user=<credential>` |\n| SHA256 (v0.1.1) | `ba5b2a9a7fe596734fb69bdf1a35071d1a2f435a36e8c870bd4390c562d9f614` |\n| SHA256 (v0.1.2) | `638b523ddd3382b622c412e37f274db1a9a6505893fa7236183f0b67a5355e94` |\n\n## Analysis\n\n### The scope squat\n\nGoogle’s Stitch is a popular AI-powered design tool that generates UI screens from text prompts. The product lives at `stitch.withgoogle.com`\n\n, and Google publishes its official SDK as [ @google/stitch-sdk](https://www.npmjs.com/package/@google/stitch-sdk) (30,000+ weekly downloads, 18 versions, published by Google employees).\n\nThe attacker exploits the gap between the product’s URL domain and Google’s npm scope. The product URL is `stitch.withgoogle.com`\n\n, but Google’s npm scope is `@google`\n\n, not `@withgoogle`\n\n. npm scope registration is first-come-first-served with no trademark verification, so the attacker registered `@withgoogle`\n\nand published a credential harvester under a name that looks like it belongs to Google.\n\nThis is a step above ordinary typosquatting. The attacker did not misspell a package name. They registered a scope that maps to a real Google domain (`withgoogle.com`\n\n) and used it to publish a package with the exact same base name as the legitimate SDK. A developer who knows the product URL `stitch.withgoogle.com`\n\ncould reasonably assume `@withgoogle/stitch-sdk`\n\nis the official package.\n\nThe attacker reinforced the impersonation with matching version numbers. The malicious package ships as v0.1.1 and v0.1.2, overlapping with the legitimate `@google/stitch-sdk`\n\n’s own version history (which also has 0.1.1 and 0.1.2-next releases).\n\n### The two execution paths\n\nThe package contains five files totaling 19KB. Two of them carry the payload.\n\nThe `preinstall`\n\nhook runs `scripts/preinstall.js`\n\nautomatically during `npm install`\n\n, before dependencies are resolved. npm suppresses lifecycle script output when a package is installed as a dependency, so the harvesting is silent. The `bin`\n\nfield registers `bin/cli.js`\n\nas the `stitch-sdk`\n\ncommand on the user’s PATH, creating a second execution path if the user runs `stitch-sdk`\n\nor `npx @withgoogle/stitch-sdk`\n\n. Both files contain identical credential harvesting code.\n\nThe `repository`\n\nfield points to `github.com/maximus-mcmillan/stitch-sdk`\n\n, a URL that returns 404. The GitHub user `maximus-mcmillan`\n\ndoes not exist either. The entire identity is fabricated.\n\n### The credential harvester\n\nBoth `scripts/preinstall.js`\n\nand `bin/cli.js`\n\nimport `child_process`\n\n, `fs`\n\n, `os`\n\n, `path`\n\n, `https`\n\n, and `http`\n\n, then run eight collection functions in sequence:\n\nThe execution order is deliberate. `collectClaude()`\n\nruns first.\n\n#### Claude Code credentials\n\nThe function checks whether the `claude`\n\nCLI is installed, runs `claude auth status`\n\n, parses the JSON output, and extracts the authenticated user’s email. This is a deliberate targeting of AI coding tool credentials. Most npm malware focuses on git, npm, and cloud provider tokens. Explicitly prioritizing Claude Code auth (and placing it first in the execution order) suggests the attacker views AI tool access as high-value. Multiple npm malware families have begun targeting Claude Code in 2026, though most focus on persistence through config injection rather than credential harvesting.\n\n#### Git, SSH, and GitHub credentials\n\nThe harvester reads git configuration through two parallel paths. It runs `git config --global user.email`\n\nand `git config --system user.email`\n\nvia `execSync`\n\n, then also reads `~/.gitconfig`\n\nand `~/.config/git/config`\n\ndirectly from disk using `fs.readFileSync`\n\nand applies a regex to extract all email addresses:\n\nThis regex sweep means the harvester does not just grab configured emails. It captures any email-shaped string found anywhere in the file, including old config lines and comments.\n\nThe same regex is applied to `~/.git-credentials`\n\n(which stores HTTPS passwords and tokens in URL format), all `*.pub`\n\nfiles in `~/.ssh/`\n\n(SSH public key comments typically contain the owner’s email), and `~/.npmrc`\n\nand `~/.docker/config.json`\n\n(both of which may contain registry authentication tokens).\n\nFor GitHub, the harvester calls the `gh`\n\nCLI directly:\n\nThis queries the GitHub API through the user’s authenticated session to retrieve their primary email.\n\n### Exfiltration\n\nEvery harvested credential passes through a single `emit()`\n\nfunction:\n\nEach credential is sent as an HTTPS GET request with the stolen value in the query string: `GET /api/v1?src=git_config--global&`\n\n. The [[email protected]](/cdn-cgi/l/email-protection)`src`\n\nparameter tags the credential’s origin (e.g., `claude_api_user`\n\n, `gh_api_user`\n\n, `file:~/.npmrc`\n\n), letting the attacker correlate which tool configurations a victim has.\n\nThe function deduplicates via a `Set`\n\n, so the same email address found in both `~/.gitconfig`\n\nand an SSH public key is only exfiltrated once. It uses `rejectUnauthorized: false`\n\nto disable TLS certificate validation on all outbound requests. A `_pending`\n\ncounter and `_maybeExit()`\n\ncallback ensure the process does not exit until every HTTP request completes or times out.\n\nThe C2 domain `stitch-production.org`\n\nwas registered via GoDaddy on June 19, 2026 at 11:07 UTC, exactly 75 minutes before the first package version was published at 12:22 UTC. The domain resolves to Cloudflare IPs (172.67.189.185, 104.21.65.94) and runs nginx/1.18.0 on Ubuntu behind the proxy.\n\nIn v0.1.2, the attacker added a fallback beacon for cases where no credentials are found:\n\nThis confirms the package was installed even on machines where no developer credentials could be harvested. Version 0.1.1 simply exited silently in this case.\n\n### The cover story\n\nThe README is polished and deliberately misleading. It includes a security warning about the very behavior the package performs:\n\nSecurity:`preinstall`\n\n/`install`\n\n/`postinstall`\n\nscripts execute arbitrary code on the installing machine and are a known supply-chain attack surface. Keep them minimal and transparent, never download remote code, phone home, or touch files outside the package.\n\nThe README describes the preinstall hook as “deliberately benign” and claims it checks the Node.js version. The hook actually harvests credentials and phones home to the C2.\n\nThe CLI `--help`\n\ntext in v0.1.2 goes further:\n\nThis text references three real packages (`@google/stitch-sdk`\n\n, `ai`\n\n, `@ai-sdk/google`\n\n) and the real Google documentation URL. It positions the malicious package as “the new version” of the legitimate one. The only visible seam is the typo “Alternitevly.”\n\nThe v0.1.1 help text was simpler: “stitch-sdk has not yet been released. Use the Stitch MCP server in the meantime.” The attacker refined the social engineering between versions without changing the payload.\n\n### Attacker profile\n\nThe npm account `maximus-mcmillan`\n\nhas published exactly one package. No other packages exist under the `@withgoogle`\n\nscope. The C2 domain, the npm account, and the GitHub identity were all created for this single operation.\n\nThe payload itself is clean, readable JavaScript with no obfuscation, no hex encoding, no base64, no minification. This is a deliberate strategy. Static analysis tools that flag obfuscation patterns, string concatenation tricks, or encoded payloads would not trigger on this code. The attacker trades detectability-by-reading for undetectability-by-automation, and bets that the `@withgoogle`\n\nscope provides enough trust that few people will actually read the source.\n\n## Conclusion\n\n`@withgoogle/stitch-sdk`\n\ndemonstrates scope squatting as an impersonation technique beyond simple typosquatting. By registering a scope that maps to a real Google domain, matching the legitimate package’s version numbers, and referencing real Google documentation, the attacker built a convincing enough identity to collect 87 installs on day one.\n\nThe credential harvester’s explicit targeting of Claude Code (as its first priority collector) reflects a broader shift in the npm threat landscape. AI coding tools are becoming standard targets alongside git, npm, and cloud credentials.\n\nDevelopers who installed this package should rotate credentials for any tool configured on the affected machine: git, GitHub, npm publish tokens, Docker registry auth, and Claude Code sessions. Running [ vet](https://github.com/safedep/vet) against lockfiles can flag scope-squatted packages before they reach install.\n\n- vet\n- malware\n- npm\n- supply-chain\n- scope-squatting\n- credential-theft\n\n### Author\n\n#### SafeDep Team\n\nsafedep.io\n\n### Share\n\n## The Latest from SafeDep blogs\n\nFollow for the latest updates and insights on open source security & engineering\n\n[Five npm Packages That Hide a Windows Binary Dropper](/procwire-npm-windows-dropper-campaign)\n\nFive npm packages published in a 12-minute burst split a Windows binary dropper across a fake utility toolkit. The loader hides in a preinstall hook, decodes its C2 from a helper package, and fetches...\n\n[astro.config.mjs Supply Chain Attack via Blockchain C2](/astro-config-blockchain-c2-supply-chain)\n\nAn obfuscated IIFE hidden in astro.config.mjs fires at every build, beacons an HTTP C2, and pulls staged commands from a Tron-to-BSC blockchain dead drop.\n\n[Mastra npm Scope Takeover: 143 Packages Drop a RAT](/mastra-npm-scope-takeover-supply-chain-attack)\n\nAn attacker republished 143 @mastra packages, including @mastra/core, each with one injected dependency: easy-day-js, a dayjs clone whose install hook downloads and runs a remote access trojan.\n\n[Miasma Worm: Most Infected GitHub Repos Are Still Live](/miasma-worm-still-infected-github-repos)\n\nEight days after the Miasma worm forged a credential stealer into public GitHub repositories, most are still serving it. A re-scan of the published victim list plus a fresh code-search sweep found...\n\n## Ship Code.\n\n## Not Malware.\n\nStart free with open source tools on your machine. Scale to a unified platform for your organization.", "url": "https://wpnews.pro/news/withgoogle-stitch-sdk-scope-squat-harvests-developer-credentials", "canonical_source": "https://safedep.io/withgoogle-stitch-sdk-scope-squat-credential-harvester", "published_at": "2026-06-20 12:00:00+00:00", "updated_at": "2026-06-20 14:15:03.663143+00:00", "lang": "en", "topics": ["ai-tools", "ai-safety", "developer-tools"], "entities": ["Google", "Stitch", "npm", "Claude Code", "GitHub", "Cloudflare", "maximus-mcmillan", "stitch-production.org"], "alternates": {"html": "https://wpnews.pro/news/withgoogle-stitch-sdk-scope-squat-harvests-developer-credentials", "markdown": "https://wpnews.pro/news/withgoogle-stitch-sdk-scope-squat-harvests-developer-credentials.md", "text": "https://wpnews.pro/news/withgoogle-stitch-sdk-scope-squat-harvests-developer-credentials.txt", "jsonld": "https://wpnews.pro/news/withgoogle-stitch-sdk-scope-squat-harvests-developer-credentials.jsonld"}}