registry  /  apkpub-cli  /  0.0.2

apkpub-cli@0.0.2

APK 多市场分发 CLI 工具 - 一键发布到华为/小米/OPPO/VIVO/荣耀及自定义渠道

AI Security Review

scanned 3h ago · by lpm-firewall-ai

LPM blocks this version under the AI-agent control-surface policy. The package performs unconsented install-time mutation of broad AI-agent skill directories. That creates an agent control-surface change during npm install, even though the copied skill appears package-owned.

Static reason
High-risk behavior combination matched malicious policy.
Trigger
npm install / pnpm install running package postinstall
Impact
Installs agent-facing instructions/capability docs without an explicit user command, affecting multiple agent platforms if their config dirs exist.
Mechanism
postinstall copies bundled AI-agent skill files into user home agent skill directories
Policy narrative
On install, npm runs scripts/install-skill.mjs. The script detects existing AI-agent config directories in the user's home directory and recursively copies the package's bundled using-apkpub-cli skill into each corresponding skills directory. This is not a remote payload or credential theft path, but it is an unprompted mutation of broad agent control surfaces during package installation.
Rationale
Static inspection confirms install-time writes into several foreign AI-agent skill directories via postinstall. Under the install-control policy this is concrete unconsented mutation of broad AI-agent control surfaces, so it should be blocked despite no observed exfiltration or remote code execution. Product guard normalized a concrete AI-agent control hijack publish_block to the blockable dangerous-capability shape.
Evidence
package.jsonscripts/install-skill.mjsskills/using-apkpub-cli/SKILL.mddist/apkpub.js~/.agents/skills/using-apkpub-cli~/.cursor/skills/using-apkpub-cli~/.hermes/skills/using-apkpub-cli~/.claude/skills/using-apkpub-cli

Decision evidence

public snapshot
AI called this Malicious at 92.0% confidence as Dangerous Capability with low false-positive risk.
Evidence for policy block
  • package.json defines postinstall: node scripts/install-skill.mjs.
  • scripts/install-skill.mjs runs at install time and copies skills/using-apkpub-cli into ~/.agents, ~/.cursor, ~/.hermes, and ~/.claude skills dirs when those config dirs exist.
  • scripts/install-skill.mjs also honors APKPUB_SKILL_DIRS to write the skill to arbitrary user-provided directories.
Evidence against
  • scripts/install-skill.mjs copies only package-bundled skill files; no download, eval, child_process, or credential harvesting observed there.
  • Install script can be skipped with APKPUB_SKIP_SKILL_INSTALL and silently ignores missing agent config dirs.
  • dist/apkpub.js is a CLI for APK publishing; network calls use user-supplied store credentials for app-market APIs.
  • No prompt injection text or exfiltration logic observed in the inspected install script.
Behavioral surface
Source
CryptoEnvironmentVarsFilesystemNetwork
Supply chain
UrlStrings
ManifestNo manifest risk signals triggered.
scanned 2 file(s), 104 KB of source, external domains: api.developer.xiaomi.com, appmarket-openapi-drcn.cloud.honor.com, connect-api.cloud.huawei.com, developer-api.vivo.com.cn, iam.developer.honor.com, oop-openapi-cn.heytapmobi.com

Source & flagged code

3 flagged · loading source
package.jsonView file
scripts.postinstall = node scripts/install-skill.mjs
High
Install Time Lifecycle Scripts

Package defines install-time lifecycle scripts.

package.jsonView on unpkg
dist/apkpub.jsView file
131"client_secret", L132: "privateKey", L133: "access_key_secret", ... L185: if (level === "debug" && !debugMode) return; L186: const stream = level === "error" ? process.stderr : process.stderr; L187: stream.write(formatMessage(level, tag, message) + "\n"); L188: } ... L198: function getConfigRoot(debug = false) { L199: const base = path.join(os.homedir(), CONFIG_DIR_NAME); L200: return debug ? path.join(base, "debug") : base; ... L252: const content = await readFile(filePath, "utf8"); L253: const raw = JSON.parse(content);
Low
Weak Crypto

Package source references weak cryptographic algorithms.

dist/apkpub.jsView on unpkg · L131
scripts/install-skill.mjsView file
13Install-time AI-agent control hijack evidence: L13: existsSync, L14: mkdirSync, L15: readdirSync, L16: copyFileSync, L17: statSync, ... L45: { label: 'hermes', agentDir: join(home, '.hermes'), skillsDir: join(home, '.hermes', 'skills') }, L46: { label: 'claude', agentDir: join(home, '.claude'), skillsDir: join(home, '.claude', 'skills') }, L47: ]; ... L61: function copyDir(src, dest) { L62: mkdirSync(dest, { recursive: true }); L63: for (const entry of readdirSync(src)) { ... L68: } else { Payload evidence from skills/using-apkpub-cli/SKILL.md: L15: 1. **先自发现**:首次使用先运行 `apkpub describe --json`,获取命令、渠道、退出码与结果 schema,不要凭记忆假设参数。 L16: 2. **始终加 `--json`**:JSON 结果走 stdout,进度与日志走 stderr,便于解析。 L17: 3. **非交互**:`publish` 必须加 `--yes` 跳过确认;CI 场景再加 `--no-progress`。 ... L78: "results": [ L79: { "name": "huawei", "status": "success", "downloadUrl": "https://..." }, L80: { "name": "mi", "status": "failed", ... L107: | 荣耀 | `honor` | client_id, client_secret | L108: | 小米 | `mi` | account, publicKey, privateKey | L109: | OPPO | `oppo` | client_id, client_secret | ... L125: ```bash L126: HUAWEI_CLIENT_SECRET=*** MI_PRIVATE_KEY=*** \ L127: apkpub publish --app com.example.app --apk ./out/ \
Critical
Ai Agent Control Hijack

Install-time source drops package-supplied AI-agent/MCP control files or instructions.

scripts/install-skill.mjsView on unpkg · L13

Findings

1 Critical1 High3 Medium4 Low
CriticalAi Agent Control Hijackscripts/install-skill.mjs
HighInstall Time Lifecycle Scriptspackage.json
MediumNetwork
MediumEnvironment Vars
MediumStructural Risk Force Deep Review
LowScripts Present
LowWeak Cryptodist/apkpub.js
LowFilesystem
LowUrl Strings