AI Security Review
scanned 3h ago · by lpm-firewall-aiLPM blocks this version under the AI-agent control-surface policy. Install-time lifecycle code plants package-supplied Claude skill files into the user's home directory. This mutates a broad foreign AI-agent control surface without an explicit user CLI action.
Static reason
High-risk behavior combination matched malicious policy.
Trigger
npm install of @lsproxy/cli@0.11.3
Impact
Unconsented registration of package-provided AI-agent instructions for Claude users.
Mechanism
postinstall copies bundled skills into ~/.claude/skills
Policy narrative
On install, npm runs skillit-postinstall.cjs. The script traverses bundled markdown, rewrites command text, creates ~/.claude/skills, and copies bundled skill directories there, causing Claude to load package-provided instructions outside the package's own namespace.
Rationale
The inspected source shows unconsented install-time mutation of ~/.claude/skills, a foreign AI-agent control surface covered by the block policy. Product-aligned content does not neutralize lifecycle delivery into another agent's home control directory.
Evidence
package.jsonskillit-postinstall.cjsskills/lsproxy-cli/SKILL.mdskills/lsproxy-cli/**~/.claude/skills/lsproxy-cli/**
Decision evidence
public snapshotAI called this Malicious at 95.0% confidence as Dangerous Capability with low false-positive risk.
Evidence for policy block
- package.json defines postinstall: node ./skillit-postinstall.cjs.
- skillit-postinstall.cjs creates ~/.claude/skills and copies bundled skills there during install.
- skillit-postinstall.cjs rewrites bundled markdown before copying, mutating package-supplied agent instructions at install time.
- skills/lsproxy-cli/SKILL.md is a Claude skill with frontmatter name and command guidance.
Evidence against
- No credential harvesting or exfiltration endpoints found in inspected package source.
- dist/cli.js behavior is package-aligned LSP/refactor CLI functionality.
- Runtime child_process use in dist/session.js and dist/connect.js is user-invoked LSP server/proxy spawning.
- Codex adapter is read-only; Claude config writes in dist/config/adapters/claude-code.js are behind explicit config export/import commands.
Behavioral surface
ChildProcessEnvironmentVarsFilesystemShell
HighEntropyStrings
Source & flagged code
2 flagged · loading sourcepackage.jsonView file
•scripts.postinstall = node ./sk[redacted]
High
Install Time Lifecycle Scripts
Package defines install-time lifecycle scripts.
package.jsonView on unpkgskillit-postinstall.cjsView file
26Install-time AI-agent control hijack evidence:
L26: const updated = content.replaceAll(npxPrefix, binName);
L27: if (updated !== content) fs.writeFileSync(full, updated, 'utf8');
L28: }
...
L32: function copyDir(src, dest) {
L33: fs.mkdirSync(dest, { recursive: true });
L34: for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
...
L39: } else {
L40: fs.copyFileSync(srcPath, destPath);
L41: }
...
L46:
L47: const userSkillsDir = path.join(os.homedir(), '.claude', 'skills');
L48: try {
Payload evidence from skills/lsproxy-cli/SKILL.md:
L63: server has not loaded the full workspace project. lsproxy flags this case as `partial:true`
L64: with a `warning` (and a stderr note) instead of a bare `ok:true`. Do not treat a
L65: partial/empty result as "no callers" for a deletion or a file move; verify with a
...
L1068:
L1069: - [Repository](https://github.com/pradeepmouli/lspeasy.git)
L1070: - Author: Pradeep Mouli
Critical
Ai Agent Control Hijack
Install-time source drops package-supplied AI-agent/MCP control files or instructions.
skillit-postinstall.cjsView on unpkg · L26Findings
1 Critical1 High2 Medium3 Low
CriticalAi Agent Control Hijackskillit-postinstall.cjs
HighInstall Time Lifecycle Scriptspackage.json
MediumEnvironment Vars
MediumStructural Risk Force Deep Review
LowScripts Present
LowFilesystem
LowHigh Entropy Strings