Back to skill

Security audit

Polymarket Opportunities Scanning

Security checks for vulnerabilities and agentic risk

Overview

The skill appears to be a real Polymarket scanner, but it needs Review because its report sender uses local Apple Mail automation and a vulnerable shell command while the docs misstate Telegram delivery.

Install only if you are comfortable with a scheduled script sending emails from your local Apple Mail account. Review and restrict the .env recipient, avoid installing it under paths writable or controlled by others, and treat the Telegram instructions as inaccurate unless the publisher updates the implementation.

Vulnerability Patterns
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/send-report.js:96
Finding

Shell Command Injection Through an Unquoted Scanner Path

Content
View full analysis

Vulnerability Details

File Location: scripts/send-report.js, lines 96–100
Vulnerability Type: Shell command injection caused by constructing a command string from an unquoted filesystem path
Risk Level: Medium

js
execSync(`node ${join(__dirname, 'scanner.js')}`, {
  stdio: 'inherit',
  cwd: __dirname,
  timeout: 120000, // 2-minute timeout
});

Technical Analysis

execSync() receives a command string and executes it through a system shell. The absolute path produced by join(__dirname, 'scanner.js') is interpolated directly into that string without shell-safe quoting.

Although the filename scanner.js is fixed, __dirname depends on the directory in which the Skill is installed. If an attacker can influence that installation path and include shell metacharacters in a directory name, the shell may interpret part of the path as additional syntax rather than as a literal scanner path.

This issue does not provide a remote exploitation path by itself. Exploitation requires the attacker to control or materially influence the directory into which the Skill is copied, extracted, or installed.

Attack Path

  1. An attacker causes the Skill to be installed or extracted under a directory name containing shell metacharacters and an attacker-selected command.
  2. The user, automation, or documented scheduled task starts send-report.js.
  3. Line 96 constructs a shell command by concatenating node with the attacker-influenced absolute path.
  4. execSync() passes the resulting string to the system shell.
  5. The shell interprets the metacharacters and executes the injected command with the privileges of the account running the report.

Impact Assessment

Successful exploitation permits arbitrary local command execution under the operating-system account that invokes send-report.js. The attacker could access or modify files available to that account, execute programs, read local configurat ...[truncated 235 chars]

Remediation
View remediation

Remediation Suggestions

Avoid passing a constructed command string to a shell. Invoke the Node.js executable directly with a separate argument array:

js
import { execFileSync } from 'child_process';

execFileSync(process.execPath, [join(__dirname, 'scanner.js')], {
  stdio: 'inherit',
  cwd: __dirname,
  timeout: 120000,
});

execFileSync() does not use a shell by default, so metacharacters in the installation path are treated as literal path characters. Using process.execPath also ensures that the scanner runs with the same Node.js executable as the parent process.

As defense in depth:

  • Install the Skill only into trusted, administrator-controlled directories.
  • Do not attempt to fix the issue solely through manual quoting, because shell escaping differs across operating systems and shells.
  • Run scheduled scans under a dedicated, least-privileged account.
  • Restrict write access to the Skill directory so untrusted users cannot replace scanner.js or alter runtime configuration.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (17)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The skill advertises use of Polymarket's public API, but the documented flow also includes dispatch through Apple Mail/osascript and orchestration behaviors that are not clearly declared as privileged actions. Using local mail clients and OS scripting broadens the trust boundary and can expose data or trigger unintended local actions beyond the user's expectation of a simple market scan.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The skill advertises use of Polymarket's public API, but the documented flow also includes dispatch through Apple Mail/osascript and orchestration behaviors that are not clearly declared as privileged actions. Using local mail clients and OS scripting broadens the trust boundary and can expose data or trigger unintended local actions beyond the user's expectation of a simple market scan.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 23)May include surrounding context.

md
1. Copy `scripts/scanner.js` and `scripts/send-report.js` to your project directory

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 23)May include surrounding context.

md
1. Copy `scripts/scanner.js` and `scripts/send-report.js` to your project directory

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · references/setup.md (reported line 16)May include surrounding context.

md
const __dirname = dirname(fileURLToPath(import.meta.url));

// .env loader
try {
  const envPath = join(__dirname, '.env');
  if (existsSync(envPath)) {

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · references/setup.md (reported line 19)May include surrounding context.

md
const __dirname = dirname(fileURLToPath(import.meta.url));

// .env loader
try {
  const envPath = join(__dirname, '.env');
  if (existsSync(envPath)) {

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/send-report.js (reported line 15)May include surrounding context.

js
const __dirname = dirname(fileURLToPath(import.meta.url));

// .env loader
try {
  const envPath = join(__dirname, '.env');
  if (existsSync(envPath)) {

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/send-report.js (reported line 17)May include surrounding context.

js
// .env loader
try {
  const envPath = join(__dirname, '.env');
  if (existsSync(envPath)) {
    for (const line of readFileSync(envPath, 'utf8').split(/\r?\n/)) {
      const m = line.match(/^\s*([A-Z0-9_]+)\s*=\s*(.*)\s*$/i);

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
87% confidence
Finding

The skill documents behaviors that require network access and likely environment/file access, but it does not declare any explicit tool scope or permissions. This weakens reviewability and least-privilege controls, making it easier for the skill to access capabilities beyond what a user would reasonably expect.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill sends results externally via Telegram and email but does not provide a clear privacy warning. Even if the report is market data, transmitted content can include user-selected recipients, timestamps, local paths, or operational details that create unnecessary disclosure risk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The cron example instructs the agent to send failure details via Telegram, but users are not warned that errors may contain sensitive operational information such as file paths, system details, stack traces, or configuration values. Shipping raw failures to an external messaging platform increases the chance of unintended disclosure.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script explicitly formats timestamps with the 'zh-CN' locale and emits user-facing console output in Chinese. This imposes a specific language/locale on all users without offering a choice or documenting a justified regional constraint.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The file header says the script runs the scanner and 'directly sends to Telegram', and the manifest also describes delivery via Telegram and email. In this file, the only implemented delivery path is email through Apple Mail/osascript; no Telegram API call or bot integration exists.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The comment explicitly states '直接发 Telegram' ('send directly to Telegram'), but the implemented notification function is sendEmail() using Apple Mail and osascript. This is an active contradiction between documentation and actual behavior, not merely an omission.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The script invokes local Apple Mail automation through osascript, giving the skill host-side subprocess execution and the ability to send email from the user's local Mail account. Even though the current command string escapes quotes and is built from expected inputs, this host-integrated automation exceeds the stated public-API scanning purpose and can exfiltrate report contents or future sensitive data if scanner output becomes attacker-controlled.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

The manifest presents the skill as a scanner/reporting tool focused on Polymarket analysis and message delivery. This code additionally persists the full opportunity dataset to disk as opportunities.json, which is a behavior beyond the described reporting flow.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

The script explicitly formats time with the 'zh-CN' locale and the surrounding user-facing logs/messages are written in Chinese. This imposes a specific language/locale choice without any visible opt-in or configuration, which matches the language/locale policy concern for natural-language content.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/send-report.js:41