registry  /  @m13v/s4l  /  1.7.3

@m13v/s4l@1.7.3

Automated social posting pipeline for Reddit, X/Twitter, LinkedIn, and Moltbook. Install as a Claude Code agent skill.

AI Security Review

scanned 2h ago · by lpm-firewall-ai

LPM treats this as warn-only first-party agent extension lifecycle risk. The MCP server automatically changes Claude Code configuration when the server boots, including its own MCP registration and S4L worker permissions/trust state. The npm CLI also installs S4L browser-agent configuration after an explicit init/update command.

Static reason
One or more suspicious static signals were detected.; previous stored version diff introduced dangerous source
Trigger
Starting mcp/dist/index.js, or explicitly running s4l init/update.
Impact
Can make S4L MCP and unattended S4L worker capabilities available to Claude sessions without a per-write prompt.
Mechanism
First-party AI-agent extension registration and permission/trust configuration writes.
Rationale
Source inspection does not establish malware or unconsented npm lifecycle hijacking. The package nevertheless performs automatic Claude configuration and permission/trust mutations on MCP boot, so it should be warned rather than marked clean.
Evidence
package.jsonbin/cli.jsmcp/dist/index.jsmcp/dist/runtime.jsbrowser-agent-configs/all-agents-mcp.json~/.claude.json~/.claude/settings.json~/.claude/scheduled-tasks/~/.claude/browser-agent-configs/~/.claude/browser-profiles/~/.s4l-worker~/social-autoposter
Network endpoints4
astral.sh/uv/install.shgithub.com/browser-use/browser-harness127.0.0.1:9222/json/version127.0.0.1:9555/json/version

Decision evidence

public snapshot
AI called this Suspicious at 91.0% confidence as Dangerous Capability with low false-positive risk.
Evidence for warning
  • mcp/dist/index.js self-registers an MCP server in ~/.claude.json on server boot.
  • mcp/dist/index.js writes tool allow-rules to ~/.claude/settings.json and marks ~/.s4l-worker trusted.
  • bin/cli.js init explicitly copies browser-agent configs into ~/.claude/browser-agent-configs.
  • bin/cli.js user-invoked setup downloads/install tools via curl, git, pip, and uv.
Evidence against
  • package.json has no preinstall, install, postinstall, or prepare lifecycle hook.
  • CLI mutations require explicit init/update commands; npm installation alone has no hook.
  • Config writes target this package's social-autoposter MCP, workers, and browser automation setup.
  • Observed HTTP endpoints are loopback CDP probes or named installer sources; no credential-exfiltration path was confirmed.
Behavioral surface
Source
ChildProcessCryptoDynamicRequireEnvironmentVarsFilesystemNetworkShellWebSocket
Supply chain
HighEntropyStringsUrlStrings
ManifestNo manifest risk signals triggered.
scanned 18 file(s), 545 KB of source, external domains: 127.0.0.1, api.github.com, app.s4l.ai, astral.sh, dl.google.com, github.com, s4l.ai, www.apple.com, www.google.com

Source & flagged code

7 flagged · loading source
bin/cookie-helper.jsView file
13L14: const { spawn, spawnSync } = require('child_process'); L15: const fs = require('fs');
High
Child Process

Package source references child process execution.

bin/cookie-helper.jsView on unpkg · L13
31package = @m13v/s4l; repositoryIdentity = social-autoposter; dependency = ws L31: } else { L32: try { WS = require('ws'); } catch { L33: try { WS = require(path.join('/usr/lib/node_modules', 'ws')); } catch {}
High
Copied Package Dependency Bridge

Package metadata claims a different repository identity while copied source loads a runtime dependency bridge.

bin/cookie-helper.jsView on unpkg · L31
13L14: const { spawn, spawnSync } = require('child_process'); L15: const fs = require('fs');
Medium
Dynamic Require

Package source references dynamic require/import behavior.

bin/cookie-helper.jsView on unpkg · L13
bin/scheduler/launchd.jsView file
4const fs = require('fs'); L5: const { execSync, spawnSync } = require('child_process'); L6: const platform = require('../platform'); ... L32: \t<array> L33: \t\t<string>/bin/bash</string> L34: \t\t<string>${job.script}</string> ... L38: \t<key>StandardOutPath</key> L39: \t<string>${job.stdoutLog}</string> L40: \t<key>StandardErrorPath</key> ... L80: try { L81: const out = execSync('launchctl list', { stdio: 'pipe', maxBuffer: 8 * 1024 * 1024 }).toString(); L82: for (const line of out.split('\n').slice(1)) {
Medium
Install Persistence

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

bin/scheduler/launchd.jsView on unpkg · L4
bin/cli.jsView file
848} L849: console.log(' installing MCP runtime deps (npm install --omit=dev in mcp/)'); L850: const npmRes = spawnSync('npm', ['install', '--omit=dev', '--no-audit', '--no-fund'], { L851: cwd: mcpDest,
High
Runtime Package Install

Package source invokes a package manager install command at runtime.

bin/cli.jsView on unpkg · L848
skill/dm-outreach-reddit.shView file
path = skill/dm-outreach-reddit.sh kind = build_helper sizeBytes = 16928 magicHex = [redacted]
Medium
Ships Build Helper

Package ships non-JavaScript build or shell helper files.

skill/dm-outreach-reddit.shView on unpkg
mcp/dist/index.jsView file
matchType = previous_version_dangerous_delta matchedPackage = @m13v/s4l@1.7.2 matchedIdentity = npm:QG0xM3YvczRs:1.7.2 similarity = 0.833 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; route for source-aware review.

mcp/dist/index.jsView on unpkg

Findings

1 Critical4 High6 Medium4 Low
CriticalPrevious Version Dangerous Deltamcp/dist/index.js
HighChild Processbin/cookie-helper.js
HighShell
HighCopied Package Dependency Bridgebin/cookie-helper.js
HighRuntime Package Installbin/cli.js
MediumDynamic Requirebin/cookie-helper.js
MediumNetwork
MediumEnvironment Vars
MediumInstall Persistencebin/scheduler/launchd.js
MediumShips Build Helperskill/dm-outreach-reddit.sh
MediumStructural Risk Force Deep Review
LowScripts Present
LowFilesystem
LowHigh Entropy Strings
LowUrl Strings