Back to skill

Security audit

Sales Dashboard

Security checks for vulnerabilities and agentic risk

Overview

The skill has a coherent sales-dashboard purpose, but it needs review because it can use broad local credential files and can prepare arbitrary local file contents for Discord delivery.

Review before installing. Run it only in a dedicated workspace or service account with access limited to the intended OKKI CRM config, report directory, and optional dashboard inputs. Confirm Discord delivery and cron schedules are wanted, avoid passing arbitrary paths to --report or --output, and require HTTPS/approved hosts for CRM authentication.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (5)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/discord-push.js:123
Finding

Arbitrary Local File Disclosure Through Discord Push Instructions

Content
View full analysis
({ index: i + 1, total: chunks.length, content: c })), total_chunks: chunks.length, generated_at: new Date().toISOString() }; ``` ### Technical Analysis The `--report` argument is treated as an unrestricted filesystem path. The script only checks whether the path exists and then reads it with the privileges of the Node.js process. It does not require the target to be beneath `data/reports`, verify that it is a regular Markdown report, reject symbolic links, or enforce an approved filename pattern. The complete file contents are split into chunks and embedded in an Agent-consumable `discord_push` instruction. Although this script does not directly connect to Discord, its declared integration model expects another Agent component to execute the generated instruction. Therefore, the unrestricted local read can become an external data-disclosure channel. ### Attack Path 1. An attacker or untrusted workflow invokes the script with a sensitive readable path: ```bash node scripts/discord-pu ...[truncated 982 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/data-collector.js:28
Finding

Excessive Access to External Environment Files and Token Caches

Content
View full analysis
Date.now() / 1000 + 300) { return cached.access_token; } } catch (_) {} } ``` ### Technical Analysis The collector reads an `.env` file outside the Skill directory and imports every parsed variable into `process.env`, even though its declared task only requires a limited set of OKKI credentials. This exposes the running Skill to unrelated secrets stored in the shared environment file. The `ENV_PATH` and `OKKI_WORKSPACE` environment variables also permit callers to redirect the collector to other accessible filesystem locations. The collector subsequently reads configuration and a ...[truncated 1397 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/data-collector.js:132
Finding

CRM Credentials Can Be Sent to an Unvalidated or Plaintext Token Endpoint

Content
View full analysis
{ const u = new URL(url); const mod = u.protocol === 'https:' ? https : http; const reqOpts = { hostname: u.hostname, port: u.port, path: u.pathname + u.search, method: opts.method || 'GET', headers: opts.headers || {}, timeout: 30000 }; ``` ### Technical Analysis The OAuth client secret is sent to `config.tokenUrl`, which is obtained from an external configuration file. The code does not enforce an allowlist of official OKKI hosts and accepts both HTTPS and plaintext HTTP. If the configuration is modified, replaced, or redirected through the configurable workspace path, credentials can be transmitted to an attacker-controlled host. When HTTP is used, network observers can capture the client ID and secret in transit. Even with HTTPS, the absence of destination allowlisting permits a malicious but valid HTTPS endpoint to receive the credentials. The complete token response is then written to `token.cache` without an explicit restrictive file mode. Its effective permissions depend on the process umask, which may expose access tokens or other respo ...[truncated 1139 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/metrics-calculator.js:190
Finding

Arbitrary File Overwrite Through the Metrics Output Argument

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/report-generator.js:154
Finding

Report Filename Path Traversal Through Unvalidated Period and Date Arguments

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (19)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/data-collector.js --period weekly [--date 2026-03-24] [--dry-run]

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/data-collector.js --period weekly [--date 2026-03-24] [--dry-run]

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/metrics-calculator.js --check-alerts

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/report-generator.js --period weekly [--dry-run]

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/report-generator.js --period weekly [--dry-run]

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/discord-push.js --latest-report weekly

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/discord-push.js --latest-report weekly

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/discord-push.js --latest-report weekly

Credential Access

High
Category
Privilege Escalation
Confidence
84% confidence
Finding

The script is designed to read secrets from a filesystem .env path and an external workspace token/config cache using broad, attacker-influenceable paths from environment variables. In an agent/skill context, this creates credential exposure risk because the skill can access sensitive local files outside its own directory and then use those credentials to authenticate to external systems.

Content

Scanner excerpt · scripts/data-collector.js (reported line 31)May include surrounding context.

js
const OKKI_WORKSPACE = process.env.OKKI_WORKSPACE || path.resolve(__dirname, '../../../xiaoman-okki');
const OKKI_CONFIG_PATH = path.join(OKKI_WORKSPACE, 'api/config.json');
const OKKI_TOKEN_CACHE = path.join(OKKI_WORKSPACE, 'api/token.cache');
const ENV_PATH = process.env.ENV_PATH || path.resolve(__dirname, '../../../.env');
const SNAPSHOTS_DIR = path.join(BASE_DIR, 'data', 'snapshots');
const LATEST_PATH = path.join(BASE_DIR, 'data', 'latest.json');
const LOGS_DIR = path.join(BASE_DIR, 'logs');

Credential Access

High
Category
Privilege Escalation
Confidence
91% confidence
Finding

The loadEnv() routine reads a .env file from a path that may point outside the project and imports every key/value into process.env without trust boundaries. In a skill environment, this behavior can harvest unrelated credentials present on the host and makes the skill more dangerous because it intentionally ingests potentially sensitive secrets for later use.

Content

Scanner excerpt · scripts/data-collector.js (reported line 88)May include surrounding context.

js
} catch (_) {}
}

// ============ .env 加载 ============
function loadEnv() {
  if (!fs.existsSync(ENV_PATH)) return;
  const lines = fs.readFileSync(ENV_PATH, 'utf-8').split('\n');

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · scripts/discord-push.js (reported line 99)May include surrounding context.

js
generated_at: new Date().toISOString()
  };
  
  return instructions;
}

// ============ 告警推送 ============

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
81% confidence
Finding

All user-facing documentation in the skill is written in Chinese, including the title and operational instructions, with no indication that users may choose another language. Under the stated policy, forcing a specific language without user opt-in can be a natural-language policy violation unless the locale restriction is documented and justified.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill explicitly collects sales data from CRM and related sources, generates reports, and pushes them to Discord, but the description does not warn users that potentially sensitive business data will be transmitted to an external messaging platform. This creates a real risk of unintended data disclosure, especially if users assume the skill only produces local dashboards or internal reports.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The description is written only in Chinese ("Farreach 销售仪表盘配置"), indicating a fixed language choice in natural-language configuration. The file does not offer any language/locale option or explain that the skill is intentionally limited to a Chinese-speaking or China-region context.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The weekly and monthly reports are hard-coded to the Asia/Shanghai timezone, which imposes a locale-specific behavior. There is no indication that users can choose a timezone or that the skill is explicitly scoped to that region for compliance or business reasons.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

This code file contains natural-language documentation and user-facing runtime messages exclusively in Chinese, starting with the file header and continuing throughout the script. That imposes a specific language on users/operators without any opt-in or documented locale constraint, which matches the language-policy violation criteria.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

This code file contains natural-language comments and usage text entirely in Chinese, and later emits Chinese-only console messages. The policy requires flagging language or locale constraints when a skill forces a specific language without user opt-in or a documented justification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The script's visible runtime messages, errors, and alerts are presented only in Chinese, which imposes a language choice on users. There is no mechanism for selecting another locale and no documented justification for a Chinese-only interface.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

The number formatter explicitly uses toLocaleString('en-US', ...), which forces a specific locale for output formatting. This is a natural-language/locale policy concern because the file does not offer user choice or explain why US English formatting is required.

Content

No source excerpt is available for this finding.