registry  /  ggk-happy  /  1.2.28

ggk-happy@1.2.28

Mobile and Web client for Claude Code and Codex

AI Security Review

scanned 4d ago · by lpm-firewall-ai

Global/root install triggers unconsented setup that downloads and executes an external rtk binary and may report local identity data. This creates install-time remote code execution and persistence outside normal npm package extraction.

Static reason
One or more suspicious static signals were detected.; previous stored version diff introduced dangerous source
Trigger
npm global install or root install running package postinstall
Impact
Unconsented external binary execution, PATH persistence, and possible machineId/token reporting from existing Happy credentials.
Mechanism
postinstall auto-takeover downloads, installs, chmods, runs rtk init, and reports rtk events
Attack narrative
On install, the package first unpacks bundled tools. If installed globally or as root, postinstall invokes the CLI install subcommand automatically. That path downloads an rtk binary from minio.ask-ggk.com, installs it into a user-local path, chmods it executable, runs rtk init, may add it to PATH, and reports events including machineId and stored token to guguke.ask-ggk.com when prior credentials exist.
Rationale
The package performs unconsented lifecycle execution of a remotely downloaded native binary plus identity/token reporting and persistence during global/root installation. This exceeds package-aligned CLI behavior and establishes a concrete install-time attack surface. Product guard normalized a non-low false-positive publish_block request to warn-only suspicious.
Evidence
package.jsonscripts/postinstall.cjsbin/happy.mjsscripts/unpack-tools.cjsdist/index-BHQeoxqq.cjstools/unpacked~/.local/share/ggkhappy/rtk/bin/rtk~/.zshrc
Network endpoints5
minio.ask-ggk.com/happy/rtk-x86_64-pc-windows-msvc.zipminio.ask-ggk.com/happy/rtk-x86_64-apple-darwin.tar.gzminio.ask-ggk.com/happy/rtk-x86_64-unknown-linux-musl.tar.gzminio.ask-ggk.com/happy/rtk-aarch64-unknown-linux-gnu.tar.gzguguke.ask-ggk.com/api/v1/agent/rtk/gain/report

Decision evidence

public snapshot
AI called this Suspicious at 94.0% confidence as Malware with medium false-positive risk.
Evidence for warning
  • package.json defines postinstall: node scripts/postinstall.cjs.
  • scripts/postinstall.cjs auto-runs bin/happy.mjs install during global or root installs unless HAPPY_SKIP_AUTO_TAKEOVER is set.
  • dist/index-BHQeoxqq.cjs runRtkInstall downloads platform rtk binaries from minio.ask-ggk.com, writes them under user-local ggkhappy paths, chmods, and runs rtk init.
  • dist/index-BHQeoxqq.cjs reportRtkEvent sends machineId and stored Happy token to https://guguke.ask-ggk.com/api/v1/agent/rtk/gain/report when credentials exist.
  • dist/index-BHQeoxqq.cjs addBinDirToUserPath can persist rtk path in ~/.zshrc on macOS or User Path on Windows.
  • scripts/unpack-tools.cjs also extracts bundled archives into tools/unpacked during install.
Evidence against
  • README/package metadata describe a Claude/Codex mobile/web client, so agent and network features are partly package-aligned.
  • No obvious import-time exfiltration in bin wrappers; main CLI behavior is largely user-invoked.
  • Claude SessionStart hook settings are generated as temporary per-session files and cleaned up in normal CLI flow, not directly written by postinstall.
Behavioral surface
Source
ChildProcessCryptoDynamicRequireEnvironmentVarsFilesystemNetworkShellWebSocket
Supply chain
HighEntropyStringsUrlStrings
ManifestNo manifest risk signals triggered.
scanned 33 file(s), 1.50 MB of source, external domains: 127.0.0.1, accounts.google.com, api.cluster-fluster.com, api.openai.com, auth.openai.com, claude.ai, console.anthropic.com, developers.google.com, github.com, goo.gle, guguke.ask-ggk.com, happy-api.ask-ggk.com, happy.ask-ggk.com, happy.engineering, minio.ask-ggk.com, oauth2.googleapis.com, registry.npmjs.org, www.apple.com, www.googleapis.com

Source & flagged code

12 flagged · loading source
package.jsonView file
scripts.postinstall = node scripts/postinstall.cjs
High
Install Time Lifecycle Scripts

Package defines install-time lifecycle scripts.

package.jsonView on unpkg
scripts.postinstall = node scripts/postinstall.cjs
Medium
Ambiguous Install Lifecycle Script

Install-time lifecycle script is not statically allowlisted and needs review.

package.jsonView on unpkg
bin/happy.mjsView file
2L3: import { execFileSync } from 'child_process'; L4: import { fileURLToPath } from 'url';
High
Child Process

Package source references child process execution.

bin/happy.mjsView on unpkg · L2
7// Check if we're already running with the flags L8: const hasNoWarnings = process.execArgv.includes('--no-warnings'); L9: const hasNoDeprecation = process.execArgv.includes('--no-deprecation');
High
Shell

Package source references shell execution.

bin/happy.mjsView on unpkg · L7
dist/AcpBackend-CUsR9zw9.cjsView file
2L3: var node_child_process = require('node:child_process'); L4: var sdk = require('@agentclientprotocol/sdk');
Medium
Dynamic Require

Package source references dynamic require/import behavior.

dist/AcpBackend-CUsR9zw9.cjsView on unpkg · L2
dist/index-BHQeoxqq.cjsView file
matchType = previous_version_dangerous_delta matchedPackage = ggk-happy@1.2.26 matchedIdentity = npm:Z2drLWhhcHB5:1.2.26 similarity = 0.939 summary = stored previous version shares package body but lacks this dangerous source file
Critical
Previous Version Dangerous Delta

This package version adds a dangerous source file absent from the previous stored version.

dist/index-BHQeoxqq.cjsView on unpkg
16var claudeAgentSdk = require('@anthropic-ai/claude-agent-sdk'); L17: var axios = require('axios'); L18: require('node:events'); ... L21: var os$1 = require('os'); L22: var child_process = require('child_process'); L23: var cuid2 = require('@paralleldrive/cuid2'); ... L152: ...existing, L153: metadata: { L154: ...existing.metadata, ... L234: const projectId = path.resolve(workingDirectory).replace(/[^a-zA-Z0-9-]/g, "-"); L235: const claudeConfigDir = process.env.CLAUDE_CONFIG_DIR || path.join(os.homedir(), ".claude"); L236: return path.join(claudeConfigDir, "projects", projectId);
High
Sandbox Evasion Gated Capability

Source gates dangerous network, credential, or execution behavior behind CI, host, platform, time, or geo fingerprint checks.

dist/index-BHQeoxqq.cjsView on unpkg · L16
16Cross-file remote execution chain: dist/index-BHQeoxqq.cjs spawns scripts/claude_local_launcher.cjs; helper contains network access plus dynamic code execution. L16: var claudeAgentSdk = require('@anthropic-ai/claude-agent-sdk'); L17: var axios = require('axios'); L18: require('node:events'); ... L21: var os$1 = require('os'); L22: var child_process = require('child_process'); L23: var cuid2 = require('@paralleldrive/cuid2'); ... L152: ...existing, L153: metadata: { L154: ...existing.metadata, ... L234: const projectId = path.resolve(workingDirectory).replace(/[^a-zA-Z0-9-]/g, "-"); L235: const claudeConfigDir = process.env.CLAUDE_CONFIG_DIR || path.join(os.homedir(), ".claude"); L236: return path.join(claudeConfigDir, "projects", projectId);
High
Cross File Remote Execution Context

Source spawns a local helper that also contains network and dynamic execution context; review data flow before blocking.

dist/index-BHQeoxqq.cjsView on unpkg · L16
16var claudeAgentSdk = require('@anthropic-ai/claude-agent-sdk'); L17: var axios = require('axios'); L18: require('node:events'); ... L21: var os$1 = require('os'); L22: var child_process = require('child_process'); L23: var cuid2 = require('@paralleldrive/cuid2'); ... L152: ...existing, L153: metadata: { L154: ...existing.metadata, ... L234: const projectId = path.resolve(workingDirectory).replace(/[^a-zA-Z0-9-]/g, "-"); L235: const claudeConfigDir = process.env.CLAUDE_CONFIG_DIR || path.join(os.homedir(), ".claude"); L236: return path.join(claudeConfigDir, "projects", projectId);
Medium
Install Persistence

Source writes installer persistence such as shell profile or service configuration.

dist/index-BHQeoxqq.cjsView on unpkg · L16
scripts/download-tools.shView file
path = scripts/download-tools.sh kind = build_helper sizeBytes = 4241 magicHex = [redacted]
Medium
Ships Build Helper

Package ships non-JavaScript build or shell helper files.

scripts/download-tools.shView on unpkg
tools/archives/difftastic-arm64-linux.tar.gzView file
path = tools/archives/difftastic-arm64-linux.tar.gz kind = high_entropy_blob sizeBytes = 11425536 magicHex = [redacted]
High
Ships High Entropy Blob

Package ships high-entropy non-source blobs.

tools/archives/difftastic-arm64-linux.tar.gzView on unpkg
path = tools/archives/difftastic-arm64-linux.tar.gz kind = compressed_blob sizeBytes = 11425536 magicHex = [redacted]
Medium
Ships Compressed Blob

Package ships compressed or archive-like blobs.

tools/archives/difftastic-arm64-linux.tar.gzView on unpkg

Findings

1 Critical6 High8 Medium4 Low
CriticalPrevious Version Dangerous Deltadist/index-BHQeoxqq.cjs
HighInstall Time Lifecycle Scriptspackage.json
HighChild Processbin/happy.mjs
HighShellbin/happy.mjs
HighSandbox Evasion Gated Capabilitydist/index-BHQeoxqq.cjs
HighCross File Remote Execution Contextdist/index-BHQeoxqq.cjs
HighShips High Entropy Blobtools/archives/difftastic-arm64-linux.tar.gz
MediumAmbiguous Install Lifecycle Scriptpackage.json
MediumDynamic Requiredist/AcpBackend-CUsR9zw9.cjs
MediumNetwork
MediumEnvironment Vars
MediumInstall Persistencedist/index-BHQeoxqq.cjs
MediumShips Build Helperscripts/download-tools.sh
MediumShips Compressed Blobtools/archives/difftastic-arm64-linux.tar.gz
MediumStructural Risk Force Deep Review
LowScripts Present
LowFilesystem
LowHigh Entropy Strings
LowUrl Strings