registry  /  @clawhelp/fmlhealth-cli  /  1.0.5

@clawhelp/fmlhealth-cli@1.0.5

一家检 - 家庭健康管理命令行工具

AI Security Review

scanned 2d ago · by lpm-firewall-ai

The CLI can capture a generic MCP_API_KEY environment variable and transmit it to the package operator's API as a bearer token. This is reachable from the published bin entrypoint and reinforced by included AI-agent usage instructions.

Static reason
High-risk behavior combination matched malicious policy.
Trigger
User or AI agent runs fmlhealth-cli, including default no-arg +me or health commands.
Impact
Potential exfiltration of unrelated MCP_API_KEY secrets to www.fmlhealth.cn and persistence in the user's home directory.
Mechanism
environment credential capture and bearer-token transmission
Attack narrative
When invoked, the bin entrypoint calls getToken(), which accepts process.env.MCP_API_KEY, persists it under ~/.fmlhealth-cli/token.json, and sends it as an Authorization bearer token to www.fmlhealth.cn API requests. The included SKILL.md encourages AI agents to run the CLI for health-related prompts, making the credential path realistically reachable outside explicit authentication.
Rationale
Although most CLI behavior is package-aligned and there is no install hook, using a generic MCP_API_KEY as an API bearer token creates a concrete credential exfiltration path. The browser-opening child_process finding is noisy, but the environment-token handling is enough to block. Product guard normalized a non-low false-positive publish_block request to warn-only suspicious.
Evidence
package.jsonbin/fmlhealth-cli.jsSKILL.md~/.fmlhealth-cli/token.json
Network endpoints3
www.fmlhealth.cn/apiwww.fmlhealth.cn/api/auth/oauth/cli-token?s=<session_code>health.clawhelp.me/login.html?cli_auth=<session_code>

Decision evidence

public snapshot
AI called this Suspicious at 86.0% confidence as Malware with medium false-positive risk.
Evidence for warning
  • bin/fmlhealth-cli.js reads process.env.MCP_API_KEY as an auth token.
  • bin/fmlhealth-cli.js saves that token to ~/.fmlhealth-cli/token.json.
  • request() sends the token as Authorization: Bearer to www.fmlhealth.cn for API calls.
  • bin/fmlhealth-cli.js is the package bin entrypoint and defaults to +me when run without args.
  • SKILL.md instructs AI agents to execute fmlhealth-cli for health-related user prompts.
Evidence against
  • package.json has no lifecycle scripts, so behavior is not install-time triggered.
  • child_process execSync is limited to opening the OAuth login URL in a browser, not sending command output.
  • Network API paths are otherwise consistent with a health-management CLI.
Behavioral surface
Source
ChildProcessEnvironmentVarsFilesystemNetworkShell
Supply chain
HighEntropyStringsUrlStrings
Manifest
NoLicense
scanned 1 file(s), 12.0 KB of source, external domains: health.clawhelp.me, www.fmlhealth.cn

Source & flagged code

3 flagged · loading source
bin/fmlhealth-cli.jsView file
20L21: const http = require('https'); L22: const fs = require('fs'); ... L26: const BASE_URL = 'https://www.fmlhealth.cn'; L27: const CONFIG_DIR = path.join(os.homedir(), '.fmlhealth-cli'); L28: const TOKEN_FILE = path.join(CONFIG_DIR, 'token.json'); ... L32: if (fs.existsSync(TOKEN_FILE)) { L33: return JSON.parse(fs.readFileSync(TOKEN_FILE, 'utf8')).token; L34: } ... L46: if (saved) return saved; L47: const env = process.env.YJ_API_KEY || process.env.MCP_API_KEY L48: if (env) { saveToken(env); return env; }
Critical
Command Output Exfiltration

Source executes local commands and sends command output to an external endpoint.

bin/fmlhealth-cli.jsView on unpkg · L20
20Trigger-reachable chain: manifest.bin -> bin/fmlhealth-cli.js L20: L21: const http = require('https'); L22: const fs = require('fs'); ... L26: const BASE_URL = 'https://www.fmlhealth.cn'; L27: const CONFIG_DIR = path.join(os.homedir(), '.fmlhealth-cli'); L28: const TOKEN_FILE = path.join(CONFIG_DIR, 'token.json'); ... L32: if (fs.existsSync(TOKEN_FILE)) { L33: return JSON.parse(fs.readFileSync(TOKEN_FILE, 'utf8')).token; L34: } ... L46: if (saved) return saved; L47: const env = process.env.YJ_API_KEY || process.env.MCP_API_KEY L48: if (env) { saveToken(env); return env; }
Critical
Trigger Reachable Dangerous Capability

A package entrypoint or install-time lifecycle script reaches a source file with blocking dangerous behavior.

bin/fmlhealth-cli.jsView on unpkg · L20
208const plat = require('os').platform(); L209: if (plat === 'darwin') require('child_process').execSync('open "' + loginUrl + '"'); L210: else if (plat === 'win32') require('child_process').execSync('start "" "' + loginUrl + '"');
High
Child Process

Package source references child process execution.

bin/fmlhealth-cli.jsView on unpkg · L208

Findings

2 Critical2 High3 Medium4 Low
CriticalCommand Output Exfiltrationbin/fmlhealth-cli.js
CriticalTrigger Reachable Dangerous Capabilitybin/fmlhealth-cli.js
HighChild Processbin/fmlhealth-cli.js
HighShell
MediumNetwork
MediumEnvironment Vars
MediumStructural Risk Force Deep Review
LowFilesystem
LowHigh Entropy Strings
LowUrl Strings
LowNo License