Back to skill

Security audit

js-eyes

Security checks across malware telemetry and agentic risk

Overview

This is a disclosed but very powerful browser-automation runtime, and it needs Review because installation and startup can change local browser integration and the package gives some risky install guidance.

Install only if you intentionally want an agent-controlled local browser runtime. Keep the server on localhost with token auth, leave anonymous and remote bind disabled, disable nativeHost.autoInstall unless token sync is needed, avoid the curl-to-bash install path, and review/approve any cookie, script, file-upload, external-skill, or native-host change before use.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (20)

Tp4

High
Category
MCP Tool Poisoning
Confidence
92% confidence
Finding
The skill is presented as an install/connect/troubleshooting helper, but the documented behavior grants access to a much broader and more privileged runtime: server management, token lifecycle, policy changes, skill trust/install flows, remote package retrieval, dependency installation, and process launching. That mismatch can cause a host or user to trust and enable the skill under a narrower mental model than its real authority, increasing the risk of dangerous actions such as installing untrusted skills, expanding browser automation authority, or altering security posture.

Description-Behavior Mismatch

Medium
Confidence
79% confidence
Finding
The manifest description presents the plugin primarily as browser automation, but the configuration also enables automatic installation and repair of Native Messaging host components, potentially rewriting manifests, launchers, or Windows registry entries. When security-sensitive host modification behavior is not clearly disclosed at the top level, operators may enable the plugin without understanding that it changes local browser integration and trust boundaries.

Missing User Warnings

High
Confidence
96% confidence
Finding
The cookie-reading actions expose authentication tokens, session cookies, and other sensitive browser state directly to the caller with no visible consent gate, scoping restriction, or warning. In a browser-control skill, this materially increases account-takeover and data-exfiltration risk because any actor allowed to invoke the action can harvest secrets from active browsing sessions.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
Returning full page HTML can disclose page content that includes private user data, embedded tokens, hidden form values, CSRF data, and internal application state. In this skill's browser-automation context, unrestricted HTML extraction enables silent scraping of sensitive information from whatever page the user has open.

Missing User Warnings

High
Confidence
98% confidence
Finding
The action executes arbitrary JavaScript in an existing browser tab, allowing DOM manipulation, data extraction, form submission, and abuse of the page's authenticated session. This is especially dangerous in a browser-control skill because code can act with the user's live privileges against any site open in the target browser.

Missing User Warnings

High
Confidence
91% confidence
Finding
This action allows arbitrary Base64-encoded file contents to be injected into a page's file input, which can transmit sensitive local or generated data into a remote web application without meaningful disclosure. In an automation setting, this creates a clear exfiltration path and can also enable unintended uploads to attacker-controlled pages.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
This SDK exposes methods to retrieve browser cookies by tab or domain and returns them directly to the caller. Cookies can contain session identifiers or other authentication material, so in an agent/browser-automation context this creates a meaningful credential-exfiltration surface, especially if higher-level callers invoke it without strong user consent or policy enforcement.

Missing User Warnings

Medium
Confidence
87% confidence
Finding
The SDK provides a file upload primitive that can send arbitrary local files into a browser tab without any built-in user-facing confirmation in this file. In an agent setting, that can lead to unintended disclosure of local sensitive files if a caller or prompt chain selects unsafe paths, even though a policy hook exists.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The subprocess is launched with a near-complete copy of the parent environment, which commonly includes secrets such as API tokens, cloud credentials, CI tokens, and proxy settings. Because the code is explicitly designed to execute linked sub-skill CLI code, any compromised or overly-privileged skill gains access to those values and can misuse them even though shell injection is prevented.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The handler returns highly sensitive browser data, including cookies, page HTML, screenshots, and page info, directly to any connected automation client over WebSocket, with no visible per-request user confirmation in this file. Because this skill is meant to connect and operate browsers, these primitives materially increase risk: a compromised or unauthorized automation client could exfiltrate authenticated session data and page contents at scale.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The cache-writing logic persists sourceInput, normalizedInput, sourceUrl, normalizedUrl, tool metadata, and arbitrary payload fields to disk in plaintext JSON. In a browser/scraping skill, those values can contain sensitive URLs, query tokens, session-related data, or extracted page content, so local retention creates a real confidentiality risk if the host is shared, compromised, or logs/artifacts are collected elsewhere.

Missing User Warnings

High
Confidence
97% confidence
Finding
When saveRawHtml is enabled, the code writes the full page HTML to disk, which can include authentication tokens in markup, PII, CSRF values, hidden fields, and other sensitive application data. Because this skill operates on browser/page content, raw HTML capture is especially risky and can materially increase exposure beyond ordinary logs or metadata.

External Script Fetching

High
Category
Supply Chain
Content
}
            if (!installed) {
              lines.push(`  安装: 调用 js-eyes 工具,action="skills/plan-install",args.skillId="${s.id}"`);
              lines.push(`  或命令行: curl -fsSL https://js-eyes.com/install.sh | bash -s -- ${s.id}`);
            }
            lines.push("");
          }
Confidence
96% confidence
Finding
The skill recommends a `curl ... | bash` install flow for uninstalled skills, which normalizes direct execution of remotely fetched shell script content. In a skill-discovery/install context, this is especially risky because registry-controlled metadata can influence what users are encouraged to run, and a compromised site, MITM on a weak transport path, or malicious upstream could lead to arbitrary code execution on the host.

Unpinned Dependencies

Low
Category
Supply Chain
Content
"dependencies": {
    "@js-eyes/protocol": "2.9.0",
    "@js-eyes/runtime-paths": "2.9.0",
    "ws": "^8.19.0"
  }
}
Confidence
93% confidence
Finding
The dependency on "ws" uses a caret range (^8.19.0), which allows automatic installation of newer 8.x releases rather than a fully fixed version. This weakens supply-chain control and can unintentionally introduce vulnerable or incompatible transitive code, especially in a network-facing browser automation SDK.

Unpinned Dependencies

Low
Category
Supply Chain
Content
"validation.js"
  ],
  "dependencies": {
    "ajv": "^8.17.1"
  },
  "license": "MIT",
  "author": "imjszhang <ortle3x3@gmail.com>",
Confidence
88% confidence
Finding
The dependency uses a caret range (^8.17.1), which permits automatic installation of newer minor/patch releases. While this is common practice and not inherently malicious, it reduces build reproducibility and can unexpectedly pull in a compromised or breaking release from the supply chain.

Known Vulnerable Dependency: ws==8.19.0 — 2 advisory(ies): CVE-2026-45736 (ws: Uninitialized memory disclosure); CVE-2026-48779 (ws: Memory exhaustion DoS from tiny fragments and data chunks)

High
Category
Supply Chain
Confidence
97% confidence
Finding
The package declares ws 8.19.0, which is identified as affected by an uninitialized memory disclosure issue and a memory-exhaustion denial-of-service issue. Because this SDK is specifically built around WebSocket-based browser automation, the vulnerable dependency sits on a core network boundary, making remote exploitation or service disruption more plausible in realistic deployments.

Known Vulnerable Dependency: ws==8.19.0 — 2 advisory(ies): CVE-2026-45736 (ws: Uninitialized memory disclosure); CVE-2026-48779 (ws: Memory exhaustion DoS from tiny fragments and data chunks)

High
Category
Supply Chain
Confidence
98% confidence
Finding
The package depends on ws 8.19.0, which is flagged with advisories for memory disclosure and memory-exhaustion denial of service. Because this is server-core code for an HTTP/WebSocket service, any vulnerable WebSocket parser/handler is especially exposed to untrusted network traffic, making remote exploitation materially more dangerous in this context.

Known Vulnerable Dependency: ajv==8.17.1 — 1 advisory(ies): CVE-2025-69873 (ajv has ReDoS when using `$data` option)

Low
Category
Supply Chain
Confidence
83% confidence
Finding
The package declares ajv 8.17.1, which is reported vulnerable to ReDoS when the $data option is used. In a skill-contract package that performs schema validation, this is relevant because validation libraries may process untrusted input; if the vulnerable option is enabled elsewhere, an attacker could trigger excessive CPU consumption and cause denial of service.

Unsafe Defaults

Medium
Category
Tool Misuse
Content
profile: mergeProfileConfig(raw.profile),
  };
  if (process.env.JS_EYES_INSECURE === '1') {
    merged.allowAnonymous = true;
  }
  if (process.env.JS_EYES_ALLOW_REMOTE_BIND === '1') {
    merged.allowRemoteBind = true;
Confidence
95% confidence
Finding
This is a real insecure-defaults issue because setting JS_EYES_INSECURE=1 disables authentication by forcing allowAnonymous=true at runtime. Even though it is an explicit opt-in via environment variable rather than the compiled default, the code provides a built-in switch that can silently weaken access control, which is especially risky for a browser-automation/runtime service that exposes sensitive tools and session data.

Unsafe Defaults

Medium
Category
Tool Misuse
Content
if (security.allowAnonymous) {
    logger.warn?.(
      '[js-eyes-server] WARNING: allowAnonymous=true (or JS_EYES_INSECURE=1) — 服务端将接受未鉴权 / 未在白名单内的客户端,仅用于过渡兼容',
    );
  }
  if (tokenCreated && tokenFilePath) {
Confidence
89% confidence
Finding
The server explicitly supports an anonymous-access mode that accepts unauthenticated and non-whitelisted clients when `security.allowAnonymous` is enabled. In this skill context, the service exposes browser/automation state over HTTP and WebSocket, so disabling auth can let local or remotely reachable clients inspect status, enumerate tabs/clients, and potentially interact with connected browser/runtime components depending on downstream handlers.

VirusTotal

VirusTotal engine telemetry is currently stale for this artifact.

View on VirusTotal

Static analysis

Detected: suspicious.dangerous_exec, suspicious.exposed_secret_literal

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
packages/protocol/safe-npm.js:91

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
packages/protocol/skill-runner.js:39

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
packages/protocol/tests/safe-npm.test.js:43