AI Security Review
scanned 2h ago · by lpm-firewall-aiThe CLI can collect a broad MCP_API_KEY environment variable during normal command execution and transmit it to the package service as a bearer token. It also stores that value under the user's home directory.
Static reason
High-risk behavior combination matched malicious policy.
Trigger
User or agent runs fmlhealth-cli commands that call request() without an existing saved token.
Impact
Potential exfiltration and persistence of a broad agent/API credential unrelated to this health CLI.
Mechanism
environment credential capture and bearer-token transmission
Attack narrative
On normal CLI use, getToken() falls back to process.env.YJ_API_KEY or process.env.MCP_API_KEY, saves the value to ~/.fmlhealth-cli/token.json, and request() sends it as an Authorization bearer token to www.fmlhealth.cn API paths. The MCP_API_KEY name is a broad agent credential name, not package-specific, and the included SKILL.md is designed for AI-agent invocation.
Rationale
Source inspection confirms concrete runtime credential capture of a broad MCP_API_KEY and transmission to the package's external service, not merely scanner noise. Lack of install hooks and package-aligned endpoints reduce AI-control-surface concerns but do not remove credential-exfiltration risk.
Evidence
package.jsonbin/fmlhealth-cli.jsSKILL.mdREADME.md~/.fmlhealth-cli/token.json
Network endpoints3
www.fmlhealth.cnwww.fmlhealth.cn/api/auth/oauth/cli-tokenwww.fmlhealth.cn/login.html
Decision evidence
public snapshotAI called this Malicious at 82.0% confidence as Malware with low false-positive risk.
Evidence for block
- bin/fmlhealth-cli.js reads process.env.MCP_API_KEY as an auth token fallback.
- bin/fmlhealth-cli.js persists env token to ~/.fmlhealth-cli/token.json.
- Most runtime commands send that token as Authorization Bearer to www.fmlhealth.cn.
- SKILL.md targets AI agents, increasing likelihood a broad MCP_API_KEY exists in the runtime environment.
Evidence against
- package.json has no npm lifecycle scripts.
- child_process use only opens the package login URL in a browser during explicit auth login.
- No code writes Claude/Codex/Cursor/MCP control-surface config files.
- Network traffic is limited to package-aligned www.fmlhealth.cn endpoints.
Behavioral surface
ChildProcessEnvironmentVarsFilesystemNetworkShell
HighEntropyStringsUrlStrings
NoLicense
Source & flagged code
3 flagged · loading sourcebin/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 · L2020Trigger-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 · L20206const plat = require('os').platform();
L207: if (plat === 'darwin') require('child_process').execSync('open "' + loginUrl + '"');
L208: 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 · L206Findings
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